Gestion issue epic dans milestone

This commit is contained in:
2026-05-28 06:11:33 +02:00
parent e20a009882
commit 05bb1b58d9
10 changed files with 1024 additions and 21 deletions
@@ -621,6 +621,107 @@ describe('IssueDetail — existing issue', () => {
expect(spy).not.toHaveBeenCalled();
});
});
describe('isChildOfEpic', () => {
it('is false when issue has no epic', () => {
(component as any).issue.epic = '';
expect((component as any).isChildOfEpic).toBe(false);
});
it('is true when issue belongs to an epic', () => {
(component as any).issue.epic = 'My Epic';
expect((component as any).isChildOfEpic).toBe(true);
});
});
describe('onMilestoneChange — epic propagation', () => {
beforeEach(() => {
(component as any).issue.type = 'Epic';
(component as any).issue.name = 'Big Epic';
store.upsert(makeIssue({ id: 2, name: 'Child 1', epic: 'Big Epic' }));
store.upsert(makeIssue({ id: 3, name: 'Child 2', epic: 'Big Epic' }));
});
it('adds epic and all children to the selected milestone', async () => {
milestonesStore.seed([makeMilestone({ id: 10, name: 'Sprint A', issueIds: [] })]);
await (component as any).onMilestoneChange(10);
expect(milestonesStore.getById(10)?.issueIds).toContain(1);
expect(milestonesStore.getById(10)?.issueIds).toContain(2);
expect(milestonesStore.getById(10)?.issueIds).toContain(3);
});
it('removes epic and all children from the previous milestone', async () => {
milestonesStore.seed([
makeMilestone({ id: 10, name: 'Sprint A', issueIds: [1, 2, 3] }),
makeMilestone({ id: 20, name: 'Sprint B', issueIds: [] }),
]);
await (component as any).onMilestoneChange(20);
expect(milestonesStore.getById(10)?.issueIds).toHaveLength(0);
expect(milestonesStore.getById(20)?.issueIds).toContain(1);
expect(milestonesStore.getById(20)?.issueIds).toContain(2);
expect(milestonesStore.getById(20)?.issueIds).toContain(3);
});
it('removes epic and all children from milestone when set to null', async () => {
milestonesStore.seed([makeMilestone({ id: 10, name: 'Sprint A', issueIds: [1, 2, 3] })]);
await (component as any).onMilestoneChange(null);
expect(milestonesStore.getById(10)?.issueIds).toHaveLength(0);
});
});
describe('confirmCreateInEpic — milestone propagation', () => {
beforeEach(() => {
(component as any).issue.type = 'Epic';
(component as any).issue.name = 'My Epic';
});
it('adds the created issue to the epic milestone', async () => {
milestonesStore.seed([makeMilestone({ id: 10, name: 'Sprint A', issueIds: [1] })]);
(component as any).newIssueName = 'New Story';
await (component as any).confirmCreateInEpic();
const m = milestonesStore.getById(10);
expect(m?.issueIds.length).toBeGreaterThan(1);
});
it('does not touch milestones when epic has no milestone', async () => {
milestonesStore.seed([makeMilestone({ id: 10, name: 'Sprint A', issueIds: [] })]);
(component as any).newIssueName = 'New Story';
await (component as any).confirmCreateInEpic();
expect(milestonesStore.getById(10)?.issueIds).toHaveLength(0);
});
});
describe('confirmAddToEpic — milestone propagation', () => {
beforeEach(() => {
(component as any).issue.type = 'Epic';
(component as any).issue.name = 'My Epic';
});
it('adds the issue to the epic milestone when epic has one', async () => {
milestonesStore.seed([makeMilestone({ id: 10, name: 'Sprint A', issueIds: [1] })]);
(component as any).selectedEpicCandidateId = 2;
await (component as any).confirmAddToEpic();
expect(milestonesStore.getById(10)?.issueIds).toContain(2);
});
it('moves the issue from its current milestone to the epic milestone', async () => {
milestonesStore.seed([
makeMilestone({ id: 10, name: 'Sprint A', issueIds: [1] }),
makeMilestone({ id: 20, name: 'Sprint B', issueIds: [2] }),
]);
(component as any).selectedEpicCandidateId = 2;
await (component as any).confirmAddToEpic();
expect(milestonesStore.getById(10)?.issueIds).toContain(2);
expect(milestonesStore.getById(20)?.issueIds).not.toContain(2);
});
it('does not touch milestones when epic has no milestone', async () => {
milestonesStore.seed([makeMilestone({ id: 20, name: 'Sprint B', issueIds: [2] })]);
(component as any).selectedEpicCandidateId = 2;
await (component as any).confirmAddToEpic();
expect(milestonesStore.getById(20)?.issueIds).toContain(2);
});
});
});
describe('IssueDetail — new issue route', () => {