Ajout des dates calculés
This commit is contained in:
@@ -11,6 +11,7 @@ const makeIssue = (overrides: Partial<IssueEntity> = {}): IssueEntity => ({
|
||||
epic: '',
|
||||
name: 'Test Issue',
|
||||
startDate: '',
|
||||
startDateMode: 'forced',
|
||||
endDate: '',
|
||||
dueDate: '',
|
||||
description: '',
|
||||
@@ -183,6 +184,123 @@ describe('IssuesStore', () => {
|
||||
expect(store.getById(991)?.startDate).toBe('2026-01-01');
|
||||
expect(store.getById(991)?.endDate).toBe('2026-01-31');
|
||||
});
|
||||
|
||||
it('restores startDateMode when the API response omits it', async () => {
|
||||
const issue = makeIssue({ id: 1, startDateMode: 'calculated' });
|
||||
const p = store.upsert(issue);
|
||||
const apiResponse = { ...makeIssue({ id: 1 }), startDateMode: undefined };
|
||||
httpMock.expectOne({ method: 'PUT', url: `${API_BASE_URL}/issues/1` }).flush(apiResponse);
|
||||
await p;
|
||||
expect(store.getById(1)?.startDateMode).toBe('calculated');
|
||||
});
|
||||
|
||||
it('restores linkedIssueIds in comments when API response omits them', async () => {
|
||||
const issueWithComment = makeIssue({ id: 1, comments: [{ id: 10, text: 'hello', createdAt: '', updatedAt: null, linkedIssueIds: [2, 3] }] });
|
||||
const apiResponse = makeIssue({ id: 1, comments: [{ id: 10, text: 'hello', createdAt: '', updatedAt: null, linkedIssueIds: undefined as any }] });
|
||||
const p = store.upsert(issueWithComment);
|
||||
httpMock.expectOne({ method: 'PUT', url: `${API_BASE_URL}/issues/1` }).flush(apiResponse);
|
||||
await p;
|
||||
expect(store.getById(1)?.comments[0].linkedIssueIds).toEqual([2, 3]);
|
||||
});
|
||||
|
||||
it('keeps existing linkedIssueIds in comments when already present in API response', async () => {
|
||||
const issue = makeIssue({ id: 1, comments: [{ id: 10, text: 'hello', createdAt: '', updatedAt: null, linkedIssueIds: [5] }] });
|
||||
const apiResponse = makeIssue({ id: 1, comments: [{ id: 10, text: 'hello', createdAt: '', updatedAt: null, linkedIssueIds: [5] }] });
|
||||
const p = store.upsert(issue);
|
||||
httpMock.expectOne({ method: 'PUT', url: `${API_BASE_URL}/issues/1` }).flush(apiResponse);
|
||||
await p;
|
||||
expect(store.getById(1)?.comments[0].linkedIssueIds).toEqual([5]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cascade recalculation of calculated-mode issues', () => {
|
||||
it('updates startDate of a calculated-mode dependent when its dependency endDate changes', async () => {
|
||||
await loadWith([
|
||||
makeIssue({ id: 1, endDate: '2026-06-01' }),
|
||||
makeIssue({ id: 2, startDateMode: 'calculated', dependsOnIds: [1], startDate: '2026-06-01', endDate: '' }),
|
||||
]);
|
||||
const p = store.upsert(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
httpMock.expectOne({ method: 'PUT', url: `${API_BASE_URL}/issues/1` }).flush(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
await p;
|
||||
expect(store.getById(2)?.startDate).toBe('2026-06-10');
|
||||
});
|
||||
|
||||
it('recalculates endDate of a calculated-mode dependent based on estimatedTime', async () => {
|
||||
await loadWith([
|
||||
makeIssue({ id: 1, endDate: '2026-06-01' }),
|
||||
makeIssue({ id: 2, startDateMode: 'calculated', dependsOnIds: [1], startDate: '2026-06-01', estimatedTime: 16, endDate: '2026-06-02' }),
|
||||
]);
|
||||
const p = store.upsert(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
httpMock.expectOne({ method: 'PUT', url: `${API_BASE_URL}/issues/1` }).flush(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
await p;
|
||||
expect(store.getById(2)?.startDate).toBe('2026-06-10');
|
||||
expect(store.getById(2)?.endDate).toBe('2026-06-11');
|
||||
});
|
||||
|
||||
it('clears endDate when dependency loses its endDate', async () => {
|
||||
await loadWith([
|
||||
makeIssue({ id: 1, endDate: '2026-06-10' }),
|
||||
makeIssue({ id: 2, startDateMode: 'calculated', dependsOnIds: [1], startDate: '2026-06-10', estimatedTime: 8, endDate: '2026-06-10' }),
|
||||
]);
|
||||
const p = store.upsert(makeIssue({ id: 1, endDate: '' }));
|
||||
httpMock.expectOne({ method: 'PUT', url: `${API_BASE_URL}/issues/1` }).flush(makeIssue({ id: 1, endDate: '' }));
|
||||
await p;
|
||||
expect(store.getById(2)?.startDate).toBe('');
|
||||
expect(store.getById(2)?.endDate).toBe('');
|
||||
});
|
||||
|
||||
it('cascades through a chain A → B → C', async () => {
|
||||
await loadWith([
|
||||
makeIssue({ id: 1, endDate: '2026-06-01' }),
|
||||
makeIssue({ id: 2, startDateMode: 'calculated', dependsOnIds: [1], startDate: '2026-06-01', estimatedTime: 8, endDate: '2026-06-01' }),
|
||||
makeIssue({ id: 3, startDateMode: 'calculated', dependsOnIds: [2], startDate: '2026-06-01', estimatedTime: 16, endDate: '2026-06-02' }),
|
||||
]);
|
||||
const p = store.upsert(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
httpMock.expectOne({ method: 'PUT', url: `${API_BASE_URL}/issues/1` }).flush(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
await p;
|
||||
expect(store.getById(2)?.startDate).toBe('2026-06-10');
|
||||
expect(store.getById(2)?.endDate).toBe('2026-06-10');
|
||||
expect(store.getById(3)?.startDate).toBe('2026-06-10');
|
||||
expect(store.getById(3)?.endDate).toBe('2026-06-11');
|
||||
});
|
||||
|
||||
it('does not affect forced-mode issues', async () => {
|
||||
await loadWith([
|
||||
makeIssue({ id: 1, endDate: '2026-06-01' }),
|
||||
makeIssue({ id: 2, startDateMode: 'forced', dependsOnIds: [1], startDate: '2026-05-01', endDate: '2026-05-15' }),
|
||||
]);
|
||||
const p = store.upsert(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
httpMock.expectOne({ method: 'PUT', url: `${API_BASE_URL}/issues/1` }).flush(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
await p;
|
||||
expect(store.getById(2)?.startDate).toBe('2026-05-01');
|
||||
expect(store.getById(2)?.endDate).toBe('2026-05-15');
|
||||
});
|
||||
|
||||
it('uses the latest endDate among multiple dependencies', async () => {
|
||||
await loadWith([
|
||||
makeIssue({ id: 1, endDate: '2026-06-01' }),
|
||||
makeIssue({ id: 2, endDate: '2026-06-05' }),
|
||||
makeIssue({ id: 3, startDateMode: 'calculated', dependsOnIds: [1, 2], startDate: '', estimatedTime: 8, endDate: '' }),
|
||||
]);
|
||||
const p = store.upsert(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
httpMock.expectOne({ method: 'PUT', url: `${API_BASE_URL}/issues/1` }).flush(makeIssue({ id: 1, endDate: '2026-06-10' }));
|
||||
await p;
|
||||
expect(store.getById(3)?.startDate).toBe('2026-06-10');
|
||||
expect(store.getById(3)?.endDate).toBe('2026-06-10');
|
||||
});
|
||||
|
||||
it('recalculates after deleteById removes a dependency', async () => {
|
||||
await loadWith([
|
||||
makeIssue({ id: 1, endDate: '2026-06-10' }),
|
||||
makeIssue({ id: 2, endDate: '2026-06-05' }),
|
||||
makeIssue({ id: 3, startDateMode: 'calculated', dependsOnIds: [1, 2], startDate: '2026-06-10', estimatedTime: 8, endDate: '2026-06-10' }),
|
||||
]);
|
||||
const p = store.deleteById(1);
|
||||
httpMock.expectOne({ method: 'DELETE', url: `${API_BASE_URL}/issues/1` }).flush(null);
|
||||
await p;
|
||||
expect(store.getById(3)?.startDate).toBe('2026-06-05');
|
||||
expect(store.getById(3)?.endDate).toBe('2026-06-05');
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteById', () => {
|
||||
|
||||
Reference in New Issue
Block a user