Skip to content

Commit 0b1ea9f

Browse files
committed
test: migrate dashboard and run detail v2 fixtures
1 parent 57d3c35 commit 0b1ea9f

2 files changed

Lines changed: 68 additions & 15 deletions

File tree

frontend/src/lib/features/testing/testRunDetailData.test.js

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,23 @@ describe('test run detail request graph', () => {
77
tests: {
88
testRuns: {
99
getDetail: vi.fn().mockResolvedValue({
10-
run: { id: 9, set_id: 4 },
11-
test_cases: [{ id: 1, test_steps: [{ id: 11 }] }, { id: 2 }],
10+
run: { id: 9, plan_id: 4 },
11+
test_cases: [
12+
{ id: 1, test_steps: [{ id: 11 }] },
13+
{ id: 2, test_steps: [{ id: 12 }] },
14+
{ id: 3 },
15+
],
1216
results: [{ id: 21, test_case_id: 1 }],
13-
step_results: { '1_11': { step_id: 11, status: 'passed' } },
17+
step_results: [
18+
{ test_case_id: 1, step_id: 11, status: 'passed' },
19+
{ test_case_id: 2, step_id: 12, status: 'failed' },
20+
],
1421
}),
1522
get: vi.fn(),
1623
getResults: vi.fn(),
1724
getStepResults: vi.fn(),
1825
},
19-
testSets: {
26+
testPlans: {
2027
get: vi.fn(),
2128
getTestCases: vi.fn(),
2229
},
@@ -31,17 +38,21 @@ describe('test run detail request graph', () => {
3138
expect(apiClient.tests.testRuns.get).not.toHaveBeenCalled();
3239
expect(apiClient.tests.testRuns.getResults).not.toHaveBeenCalled();
3340
expect(apiClient.tests.testRuns.getStepResults).not.toHaveBeenCalled();
34-
expect(apiClient.tests.testSets.get).not.toHaveBeenCalled();
35-
expect(apiClient.tests.testSets.getTestCases).not.toHaveBeenCalled();
41+
expect(apiClient.tests.testPlans.get).not.toHaveBeenCalled();
42+
expect(apiClient.tests.testPlans.getTestCases).not.toHaveBeenCalled();
3643
expect(apiClient.tests.testCases.steps.getAll).not.toHaveBeenCalled();
3744
expect(detail).toEqual({
38-
run: { id: 9, set_id: 4 },
45+
run: { id: 9, plan_id: 4 },
3946
testCases: [
4047
{ id: 1, test_steps: [{ id: 11 }] },
41-
{ id: 2, test_steps: [] },
48+
{ id: 2, test_steps: [{ id: 12 }] },
49+
{ id: 3, test_steps: [] },
4250
],
4351
results: [{ id: 21, test_case_id: 1 }],
44-
stepResults: { '1_11': { step_id: 11, status: 'passed' } },
52+
stepResults: {
53+
'1_11': { test_case_id: 1, step_id: 11, status: 'passed' },
54+
'2_12': { test_case_id: 2, step_id: 12, status: 'failed' },
55+
},
4556
});
4657
});
4758

@@ -52,4 +63,24 @@ describe('test run detail request graph', () => {
5263

5364
await expect(loadTestRunDetail(apiClient, 3, 9)).rejects.toThrow('Test run not found');
5465
});
66+
67+
it('normalizes missing optional graph lists without additional requests', async () => {
68+
const getDetail = vi.fn().mockResolvedValue({ run: { id: 9, plan_id: 4 } });
69+
const apiClient = { tests: { testRuns: { getDetail } } };
70+
await expect(loadTestRunDetail(apiClient, 3, 9)).resolves.toEqual({
71+
run: { id: 9, plan_id: 4 },
72+
testCases: [],
73+
results: [],
74+
stepResults: {},
75+
});
76+
expect(getDetail).toHaveBeenCalledExactlyOnceWith(3, 9);
77+
});
78+
79+
it('propagates a failed aggregate request', async () => {
80+
const failure = new Error('Run unavailable');
81+
const getDetail = vi.fn().mockRejectedValue(failure);
82+
const apiClient = { tests: { testRuns: { getDetail } } };
83+
await expect(loadTestRunDetail(apiClient, 3, 9)).rejects.toBe(failure);
84+
expect(getDetail).toHaveBeenCalledExactlyOnceWith(3, 9);
85+
});
5586
});

frontend/src/lib/widgets/dashboard/taskWidgetState.test.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,28 +85,50 @@ describe('normalizeTaskResponse', () => {
8585
];
8686

8787
test('sorts by due date (earliest first, nulls last)', () => {
88-
const result = normalizeTaskResponse(items);
88+
const result = normalizeTaskResponse({ data: items });
8989
expect(result.map((t) => t.id)).toEqual([3, 1, 4, 2]);
9090
});
9191

9292
test('respects numeric maxItems cap', () => {
93-
const result = normalizeTaskResponse(items, 2);
93+
const result = normalizeTaskResponse({ data: items }, 2);
9494
expect(result).toHaveLength(2);
9595
expect(result[0].id).toBe(3); // earliest due date
9696
});
9797

9898
test("'all' returns every item", () => {
99-
const result = normalizeTaskResponse(items, 'all');
99+
const result = normalizeTaskResponse({ data: items }, 'all');
100100
expect(result).toHaveLength(4);
101101
});
102102

103-
test('handles wrapped { items: [...] } responses', () => {
104-
const result = normalizeTaskResponse({ items });
103+
test('handles v2 data and pagination without rendering metadata', () => {
104+
const result = normalizeTaskResponse({
105+
data: items,
106+
pagination: { page: 1, page_size: 50, total_items: 4, total_pages: 1 },
107+
});
105108
expect(result).toHaveLength(4);
106109
});
107110

108111
test('filters out entries without an id', () => {
109-
const result = normalizeTaskResponse([{ title: 'no id' }, ...items]);
112+
const result = normalizeTaskResponse({ data: [null, { title: 'no id' }, ...items] });
110113
expect(result).toHaveLength(4);
111114
});
115+
116+
test('normalizes due dates without mutating the source objects or ordering', () => {
117+
const source = Object.freeze(items.map((item) => Object.freeze({ ...item })));
118+
const result = normalizeTaskResponse({ data: source });
119+
expect(result.map((item) => item.dueDate)).toEqual([
120+
'2026-06-01T00:00:00Z',
121+
'2026-06-05T00:00:00Z',
122+
'2026-06-10T00:00:00Z',
123+
null,
124+
]);
125+
expect(source.map((item) => item.id)).toEqual([1, 2, 3, 4]);
126+
expect(source.every((item) => !Object.hasOwn(item, 'dueDate'))).toBe(true);
127+
});
128+
129+
test('returns no rows for empty or absent v2 data', () => {
130+
for (const response of [null, undefined, {}, { data: [] }]) {
131+
expect(normalizeTaskResponse(response)).toEqual([]);
132+
}
133+
});
112134
});

0 commit comments

Comments
 (0)