@elisra-devops/docgen-data-provider 1.63.13 → 1.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +26 -9
- package/.github/workflows/release.yml +9 -10
- package/README.md +50 -24
- package/bin/helpers/tfs.d.ts +3 -0
- package/bin/helpers/tfs.js +44 -7
- package/bin/helpers/tfs.js.map +1 -1
- package/bin/modules/GitDataProvider.d.ts +10 -0
- package/bin/modules/GitDataProvider.js +10 -0
- package/bin/modules/GitDataProvider.js.map +1 -1
- package/bin/modules/TestDataProvider.js +0 -1
- package/bin/modules/TestDataProvider.js.map +1 -1
- package/bin/modules/TicketsDataProvider.d.ts +63 -24
- package/bin/modules/TicketsDataProvider.js +216 -114
- package/bin/modules/TicketsDataProvider.js.map +1 -1
- package/bin/tests/helpers/helper.test.js +279 -0
- package/bin/tests/helpers/helper.test.js.map +1 -0
- package/bin/{helpers/test → tests/helpers}/tfs.test.js +312 -49
- package/bin/tests/helpers/tfs.test.js.map +1 -0
- package/bin/tests/index.test.js +25 -0
- package/bin/tests/index.test.js.map +1 -0
- package/bin/tests/models/tfs-data.test.js +160 -0
- package/bin/tests/models/tfs-data.test.js.map +1 -0
- package/bin/{modules/test → tests/modules}/JfrogDataProvider.test.js +9 -9
- package/bin/tests/modules/JfrogDataProvider.test.js.map +1 -0
- package/bin/tests/modules/ResultDataProvider.test.js +1942 -0
- package/bin/tests/modules/ResultDataProvider.test.js.map +1 -0
- package/bin/tests/modules/gitDataProvider.test.js +1888 -0
- package/bin/tests/modules/gitDataProvider.test.js.map +1 -0
- package/bin/{modules/test → tests/modules}/managmentDataProvider.test.js +13 -1
- package/bin/tests/modules/managmentDataProvider.test.js.map +1 -0
- package/bin/tests/modules/pipelineDataProvider.test.d.ts +1 -0
- package/bin/tests/modules/pipelineDataProvider.test.js +783 -0
- package/bin/tests/modules/pipelineDataProvider.test.js.map +1 -0
- package/bin/tests/modules/testDataProvider.test.d.ts +1 -0
- package/bin/tests/modules/testDataProvider.test.js +717 -0
- package/bin/tests/modules/testDataProvider.test.js.map +1 -0
- package/bin/tests/modules/ticketsDataProvider.test.d.ts +1 -0
- package/bin/tests/modules/ticketsDataProvider.test.js +1681 -0
- package/bin/tests/modules/ticketsDataProvider.test.js.map +1 -0
- package/bin/tests/utils/DataProviderUtils.test.d.ts +1 -0
- package/bin/tests/utils/DataProviderUtils.test.js +61 -0
- package/bin/tests/utils/DataProviderUtils.test.js.map +1 -0
- package/bin/tests/utils/testStepParserHelper.test.d.ts +1 -0
- package/bin/tests/utils/testStepParserHelper.test.js +359 -0
- package/bin/tests/utils/testStepParserHelper.test.js.map +1 -0
- package/package.json +9 -1
- package/src/helpers/tfs.ts +51 -7
- package/src/modules/GitDataProvider.ts +10 -0
- package/src/modules/TestDataProvider.ts +0 -1
- package/src/modules/TicketsDataProvider.ts +298 -141
- package/src/tests/helpers/helper.test.ts +337 -0
- package/src/tests/helpers/tfs.test.ts +1092 -0
- package/src/tests/index.test.ts +28 -0
- package/src/tests/models/tfs-data.test.ts +203 -0
- package/src/tests/modules/JfrogDataProvider.test.ts +167 -0
- package/src/tests/modules/ResultDataProvider.test.ts +2571 -0
- package/src/tests/modules/gitDataProvider.test.ts +2628 -0
- package/src/{modules/test → tests/modules}/managmentDataProvider.test.ts +33 -1
- package/src/tests/modules/pipelineDataProvider.test.ts +1038 -0
- package/src/tests/modules/testDataProvider.test.ts +1046 -0
- package/src/tests/modules/ticketsDataProvider.test.ts +2204 -0
- package/src/tests/utils/DataProviderUtils.test.ts +76 -0
- package/src/tests/utils/testStepParserHelper.test.ts +437 -0
- package/tsconfig.json +1 -0
- package/bin/helpers/test/tfs.test.js.map +0 -1
- package/bin/modules/test/JfrogDataProvider.test.js.map +0 -1
- package/bin/modules/test/ResultDataProvider.test.js +0 -444
- package/bin/modules/test/ResultDataProvider.test.js.map +0 -1
- package/bin/modules/test/gitDataProvider.test.js +0 -428
- package/bin/modules/test/gitDataProvider.test.js.map +0 -1
- package/bin/modules/test/managmentDataProvider.test.js.map +0 -1
- package/bin/modules/test/pipelineDataProvider.test.js +0 -237
- package/bin/modules/test/pipelineDataProvider.test.js.map +0 -1
- package/bin/modules/test/testDataProvider.test.js +0 -234
- package/bin/modules/test/testDataProvider.test.js.map +0 -1
- package/bin/modules/test/ticketsDataProvider.test.js +0 -348
- package/bin/modules/test/ticketsDataProvider.test.js.map +0 -1
- package/src/helpers/test/tfs.test.ts +0 -748
- package/src/modules/test/JfrogDataProvider.test.ts +0 -171
- package/src/modules/test/ResultDataProvider.test.ts +0 -542
- package/src/modules/test/gitDataProvider.test.ts +0 -645
- package/src/modules/test/pipelineDataProvider.test.ts +0 -292
- package/src/modules/test/testDataProvider.test.ts +0 -318
- package/src/modules/test/ticketsDataProvider.test.ts +0 -462
- /package/bin/{helpers/test/tfs.test.d.ts → tests/helpers/helper.test.d.ts} +0 -0
- /package/bin/{modules/test/JfrogDataProvider.test.d.ts → tests/helpers/tfs.test.d.ts} +0 -0
- /package/bin/{modules/test/ResultDataProvider.test.d.ts → tests/index.test.d.ts} +0 -0
- /package/bin/{modules/test/gitDataProvider.test.d.ts → tests/models/tfs-data.test.d.ts} +0 -0
- /package/bin/{modules/test/managmentDataProvider.test.d.ts → tests/modules/JfrogDataProvider.test.d.ts} +0 -0
- /package/bin/{modules/test/pipelineDataProvider.test.d.ts → tests/modules/ResultDataProvider.test.d.ts} +0 -0
- /package/bin/{modules/test/testDataProvider.test.d.ts → tests/modules/gitDataProvider.test.d.ts} +0 -0
- /package/bin/{modules/test/ticketsDataProvider.test.d.ts → tests/modules/managmentDataProvider.test.d.ts} +0 -0
|
@@ -1,542 +0,0 @@
|
|
|
1
|
-
import { TFSServices } from '../../helpers/tfs';
|
|
2
|
-
import ResultDataProvider from '../ResultDataProvider';
|
|
3
|
-
import logger from '../../utils/logger';
|
|
4
|
-
import Utils from '../../utils/testStepParserHelper';
|
|
5
|
-
|
|
6
|
-
// Mock dependencies
|
|
7
|
-
jest.mock('../../helpers/tfs');
|
|
8
|
-
jest.mock('../../utils/logger');
|
|
9
|
-
jest.mock('../../utils/testStepParserHelper');
|
|
10
|
-
jest.mock('p-limit', () => () => (fn: Function) => fn());
|
|
11
|
-
|
|
12
|
-
describe('ResultDataProvider', () => {
|
|
13
|
-
let resultDataProvider: ResultDataProvider;
|
|
14
|
-
const mockOrgUrl = 'https://dev.azure.com/organization/';
|
|
15
|
-
const mockToken = 'mock-token';
|
|
16
|
-
const mockProjectName = 'test-project';
|
|
17
|
-
const mockTestPlanId = '12345';
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
jest.clearAllMocks();
|
|
21
|
-
resultDataProvider = new ResultDataProvider(mockOrgUrl, mockToken);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
describe('Utility methods', () => {
|
|
25
|
-
describe('flattenSuites', () => {
|
|
26
|
-
it('should flatten a hierarchical suite structure into a single-level array', () => {
|
|
27
|
-
// Arrange
|
|
28
|
-
const suites = [
|
|
29
|
-
{
|
|
30
|
-
id: 1,
|
|
31
|
-
name: 'Parent 1',
|
|
32
|
-
children: [
|
|
33
|
-
{ id: 2, name: 'Child 1' },
|
|
34
|
-
{
|
|
35
|
-
id: 3,
|
|
36
|
-
name: 'Child 2',
|
|
37
|
-
children: [{ id: 4, name: 'Grandchild 1' }],
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
},
|
|
41
|
-
{ id: 5, name: 'Parent 2' },
|
|
42
|
-
];
|
|
43
|
-
|
|
44
|
-
// Act
|
|
45
|
-
const result: any[] = (resultDataProvider as any).flattenSuites(suites);
|
|
46
|
-
|
|
47
|
-
// Assert
|
|
48
|
-
expect(result).toHaveLength(5);
|
|
49
|
-
expect(result.map((s) => s.id)).toEqual([1, 2, 3, 4, 5]);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
describe('filterSuites', () => {
|
|
54
|
-
it('should filter suites based on selected suite IDs', () => {
|
|
55
|
-
// Arrange
|
|
56
|
-
const testSuites = [
|
|
57
|
-
{ id: 1, name: 'Suite 1', parentSuite: { id: 0 } },
|
|
58
|
-
{ id: 2, name: 'Suite 2', parentSuite: { id: 1 } },
|
|
59
|
-
{ id: 3, name: 'Suite 3', parentSuite: { id: 1 } },
|
|
60
|
-
];
|
|
61
|
-
const selectedSuiteIds = [1, 3];
|
|
62
|
-
|
|
63
|
-
// Act
|
|
64
|
-
const result: any[] = (resultDataProvider as any).filterSuites(testSuites, selectedSuiteIds);
|
|
65
|
-
|
|
66
|
-
// Assert
|
|
67
|
-
expect(result).toHaveLength(2);
|
|
68
|
-
expect(result.map((s) => s.id)).toEqual([1, 3]);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should return all suites with parent when no suite IDs are selected', () => {
|
|
72
|
-
// Arrange
|
|
73
|
-
const testSuites = [
|
|
74
|
-
{ id: 1, name: 'Suite 1', parentSuite: { id: 0 } },
|
|
75
|
-
{ id: 2, name: 'Suite 2', parentSuite: { id: 1 } },
|
|
76
|
-
{ id: 3, name: 'Suite 3', parentSuite: null },
|
|
77
|
-
];
|
|
78
|
-
|
|
79
|
-
// Act
|
|
80
|
-
const result: any[] = (resultDataProvider as any).filterSuites(testSuites);
|
|
81
|
-
|
|
82
|
-
// Assert
|
|
83
|
-
expect(result).toHaveLength(2);
|
|
84
|
-
expect(result.map((s) => s.id)).toEqual([1, 2]);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
describe('buildTestGroupName', () => {
|
|
89
|
-
it('should return simple suite name when hierarchy is disabled', () => {
|
|
90
|
-
// Arrange
|
|
91
|
-
const suiteMap = new Map([[1, { id: 1, name: 'Suite 1', parentSuite: { id: 0 } }]]);
|
|
92
|
-
|
|
93
|
-
// Act
|
|
94
|
-
const result = (resultDataProvider as any).buildTestGroupName(1, suiteMap, false);
|
|
95
|
-
|
|
96
|
-
// Assert
|
|
97
|
-
expect(result).toBe('Suite 1');
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('should build hierarchical name with parent info', () => {
|
|
101
|
-
// Arrange
|
|
102
|
-
const suiteMap = new Map([
|
|
103
|
-
[1, { id: 1, name: 'Parent', parentSuite: null }],
|
|
104
|
-
[2, { id: 2, name: 'Child', parentSuite: { id: 1 } }],
|
|
105
|
-
]);
|
|
106
|
-
|
|
107
|
-
// Act
|
|
108
|
-
const result = (resultDataProvider as any).buildTestGroupName(2, suiteMap, true);
|
|
109
|
-
|
|
110
|
-
// Assert
|
|
111
|
-
expect(result).toBe('Child');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should abbreviate deep hierarchies', () => {
|
|
115
|
-
// Arrange
|
|
116
|
-
const suiteMap = new Map([
|
|
117
|
-
[1, { id: 1, name: 'Root', parentSuite: null }],
|
|
118
|
-
[2, { id: 2, name: 'Level1', parentSuite: { id: 1 } }],
|
|
119
|
-
[3, { id: 3, name: 'Level2', parentSuite: { id: 2 } }],
|
|
120
|
-
[4, { id: 4, name: 'Level3', parentSuite: { id: 3 } }],
|
|
121
|
-
]);
|
|
122
|
-
|
|
123
|
-
// Act
|
|
124
|
-
const result = (resultDataProvider as any).buildTestGroupName(4, suiteMap, true);
|
|
125
|
-
|
|
126
|
-
// Assert
|
|
127
|
-
expect(result).toBe('Level1/.../Level3');
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
describe('convertRunStatus', () => {
|
|
132
|
-
it('should convert API status to readable format', () => {
|
|
133
|
-
// Arrange & Act & Assert
|
|
134
|
-
expect((resultDataProvider as any).convertRunStatus('passed')).toBe('Passed');
|
|
135
|
-
expect((resultDataProvider as any).convertRunStatus('failed')).toBe('Failed');
|
|
136
|
-
expect((resultDataProvider as any).convertRunStatus('notApplicable')).toBe('Not Applicable');
|
|
137
|
-
expect((resultDataProvider as any).convertRunStatus('unknown')).toBe('Not Run');
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
describe('compareActionResults', () => {
|
|
144
|
-
it('should compare version-like step positions correctly', () => {
|
|
145
|
-
// Act & Assert
|
|
146
|
-
const compare = (resultDataProvider as any).compareActionResults;
|
|
147
|
-
expect(compare('1', '2')).toBe(-1);
|
|
148
|
-
expect(compare('2', '1')).toBe(1);
|
|
149
|
-
expect(compare('1.1', '1.2')).toBe(-1);
|
|
150
|
-
expect(compare('1.2', '1.1')).toBe(1);
|
|
151
|
-
expect(compare('1.1', '1.1')).toBe(0);
|
|
152
|
-
expect(compare('1.1.1', '1.1')).toBe(1);
|
|
153
|
-
expect(compare('1.1', '1.1.1')).toBe(-1);
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
describe('Data fetching methods', () => {
|
|
159
|
-
describe('fetchTestSuites', () => {
|
|
160
|
-
it('should fetch and process test suites correctly', async () => {
|
|
161
|
-
// Arrange
|
|
162
|
-
const mockTestSuites = {
|
|
163
|
-
value: [
|
|
164
|
-
{
|
|
165
|
-
id: 1,
|
|
166
|
-
name: 'Root Suite',
|
|
167
|
-
children: [{ id: 2, name: 'Child Suite 1', parentSuite: { id: 1 } }],
|
|
168
|
-
},
|
|
169
|
-
],
|
|
170
|
-
count: 1,
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockTestSuites);
|
|
174
|
-
|
|
175
|
-
// Act
|
|
176
|
-
const result = await (resultDataProvider as any).fetchTestSuites(mockTestPlanId, mockProjectName);
|
|
177
|
-
|
|
178
|
-
// Assert
|
|
179
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
180
|
-
`${mockOrgUrl}${mockProjectName}/_apis/testplan/Plans/${mockTestPlanId}/Suites?asTreeView=true`,
|
|
181
|
-
mockToken
|
|
182
|
-
);
|
|
183
|
-
expect(result).toHaveLength(1);
|
|
184
|
-
expect(result[0]).toHaveProperty('testSuiteId', 2);
|
|
185
|
-
expect(result[0]).toHaveProperty('testGroupName');
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should handle errors and return empty array', async () => {
|
|
189
|
-
// Arrange
|
|
190
|
-
const mockError = new Error('API error');
|
|
191
|
-
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
|
|
192
|
-
|
|
193
|
-
// Act
|
|
194
|
-
const result = await (resultDataProvider as any).fetchTestSuites(mockTestPlanId, mockProjectName);
|
|
195
|
-
|
|
196
|
-
// Assert
|
|
197
|
-
expect(logger.error).toHaveBeenCalled();
|
|
198
|
-
expect(result).toEqual([]);
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
describe('fetchTestPoints', () => {
|
|
203
|
-
it('should fetch and map test points correctly', async () => {
|
|
204
|
-
// Arrange
|
|
205
|
-
const mockSuiteId = '123';
|
|
206
|
-
const mockTestPoints = {
|
|
207
|
-
value: [
|
|
208
|
-
{
|
|
209
|
-
testCaseReference: { id: 1, name: 'Test Case 1' },
|
|
210
|
-
configuration: { name: 'Config 1' },
|
|
211
|
-
results: {
|
|
212
|
-
outcome: 'passed',
|
|
213
|
-
lastTestRunId: 100,
|
|
214
|
-
lastResultId: 200,
|
|
215
|
-
lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } },
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
],
|
|
219
|
-
count: 1,
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockTestPoints);
|
|
223
|
-
|
|
224
|
-
// Act
|
|
225
|
-
const result = await (resultDataProvider as any).fetchTestPoints(
|
|
226
|
-
mockProjectName,
|
|
227
|
-
mockTestPlanId,
|
|
228
|
-
mockSuiteId
|
|
229
|
-
);
|
|
230
|
-
|
|
231
|
-
// Assert
|
|
232
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
233
|
-
`${mockOrgUrl}${mockProjectName}/_apis/testplan/Plans/${mockTestPlanId}/Suites/${mockSuiteId}/TestPoint?includePointDetails=true`,
|
|
234
|
-
mockToken
|
|
235
|
-
);
|
|
236
|
-
expect(result).toHaveLength(1);
|
|
237
|
-
expect(result[0]).toEqual({
|
|
238
|
-
testCaseId: 1,
|
|
239
|
-
testCaseName: 'Test Case 1',
|
|
240
|
-
configurationName: 'Config 1',
|
|
241
|
-
outcome: 'passed',
|
|
242
|
-
lastRunId: 100,
|
|
243
|
-
lastResultId: 200,
|
|
244
|
-
lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } },
|
|
245
|
-
testCaseUrl: 'https://dev.azure.com/organization/test-project/_workitems/edit/1',
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
it('should handle errors and return empty array', async () => {
|
|
250
|
-
// Arrange
|
|
251
|
-
const mockSuiteId = '123';
|
|
252
|
-
const mockError = new Error('API error');
|
|
253
|
-
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
|
|
254
|
-
|
|
255
|
-
// Act
|
|
256
|
-
const result = await (resultDataProvider as any).fetchTestPoints(
|
|
257
|
-
mockProjectName,
|
|
258
|
-
mockTestPlanId,
|
|
259
|
-
mockSuiteId
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
// Assert
|
|
263
|
-
expect(logger.error).toHaveBeenCalled();
|
|
264
|
-
expect(result).toEqual([]);
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
describe('Data transformation methods', () => {
|
|
270
|
-
describe('mapTestPoint', () => {
|
|
271
|
-
it('should transform test point data correctly', () => {
|
|
272
|
-
// Arrange
|
|
273
|
-
const testPoint = {
|
|
274
|
-
testCaseReference: { id: 1, name: 'Test Case 1' },
|
|
275
|
-
configuration: { name: 'Config 1' },
|
|
276
|
-
results: {
|
|
277
|
-
outcome: 'passed',
|
|
278
|
-
lastTestRunId: 100,
|
|
279
|
-
lastResultId: 200,
|
|
280
|
-
lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } },
|
|
281
|
-
},
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
// Act
|
|
285
|
-
const result = (resultDataProvider as any).mapTestPoint(testPoint, mockProjectName);
|
|
286
|
-
|
|
287
|
-
// Assert
|
|
288
|
-
expect(result).toEqual({
|
|
289
|
-
testCaseId: 1,
|
|
290
|
-
testCaseName: 'Test Case 1',
|
|
291
|
-
configurationName: 'Config 1',
|
|
292
|
-
outcome: 'passed',
|
|
293
|
-
lastRunId: 100,
|
|
294
|
-
lastResultId: 200,
|
|
295
|
-
lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } },
|
|
296
|
-
testCaseUrl: 'https://dev.azure.com/organization/test-project/_workitems/edit/1',
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
it('should handle missing fields', () => {
|
|
301
|
-
// Arrange
|
|
302
|
-
const testPoint = {
|
|
303
|
-
testCaseReference: { id: 1, name: 'Test Case 1' },
|
|
304
|
-
// No configuration or results
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
// Act
|
|
308
|
-
const result = (resultDataProvider as any).mapTestPoint(testPoint, mockProjectName);
|
|
309
|
-
|
|
310
|
-
// Assert
|
|
311
|
-
expect(result).toEqual({
|
|
312
|
-
testCaseId: 1,
|
|
313
|
-
testCaseName: 'Test Case 1',
|
|
314
|
-
configurationName: undefined,
|
|
315
|
-
outcome: 'Not Run',
|
|
316
|
-
lastRunId: undefined,
|
|
317
|
-
lastResultId: undefined,
|
|
318
|
-
lastResultDetails: undefined,
|
|
319
|
-
testCaseUrl: 'https://dev.azure.com/organization/test-project/_workitems/edit/1',
|
|
320
|
-
});
|
|
321
|
-
});
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
describe('calculateGroupResultSummary', () => {
|
|
325
|
-
it('should return empty strings when includeHardCopyRun is true', () => {
|
|
326
|
-
// Arrange
|
|
327
|
-
const testPoints = [{ outcome: 'passed' }, { outcome: 'failed' }];
|
|
328
|
-
|
|
329
|
-
// Act
|
|
330
|
-
const result = (resultDataProvider as any).calculateGroupResultSummary(testPoints, true);
|
|
331
|
-
|
|
332
|
-
// Assert
|
|
333
|
-
expect(result).toEqual({
|
|
334
|
-
passed: '',
|
|
335
|
-
failed: '',
|
|
336
|
-
notApplicable: '',
|
|
337
|
-
blocked: '',
|
|
338
|
-
notRun: '',
|
|
339
|
-
total: '',
|
|
340
|
-
successPercentage: '',
|
|
341
|
-
});
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
it('should calculate summary statistics correctly', () => {
|
|
345
|
-
// Arrange
|
|
346
|
-
const testPoints = [
|
|
347
|
-
{ outcome: 'passed' },
|
|
348
|
-
{ outcome: 'passed' },
|
|
349
|
-
{ outcome: 'failed' },
|
|
350
|
-
{ outcome: 'notApplicable' },
|
|
351
|
-
{ outcome: 'blocked' },
|
|
352
|
-
{ outcome: 'something else' },
|
|
353
|
-
];
|
|
354
|
-
|
|
355
|
-
// Act
|
|
356
|
-
const result = (resultDataProvider as any).calculateGroupResultSummary(testPoints, false);
|
|
357
|
-
|
|
358
|
-
// Assert
|
|
359
|
-
expect(result).toEqual({
|
|
360
|
-
passed: 2,
|
|
361
|
-
failed: 1,
|
|
362
|
-
notApplicable: 1,
|
|
363
|
-
blocked: 1,
|
|
364
|
-
notRun: 1,
|
|
365
|
-
total: 6,
|
|
366
|
-
successPercentage: '33.33%',
|
|
367
|
-
});
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
it('should handle empty array', () => {
|
|
371
|
-
// Arrange
|
|
372
|
-
const testPoints: any[] = [];
|
|
373
|
-
|
|
374
|
-
// Act
|
|
375
|
-
const result = (resultDataProvider as any).calculateGroupResultSummary(testPoints, false);
|
|
376
|
-
|
|
377
|
-
// Assert
|
|
378
|
-
expect(result).toEqual({
|
|
379
|
-
passed: 0,
|
|
380
|
-
failed: 0,
|
|
381
|
-
notApplicable: 0,
|
|
382
|
-
blocked: 0,
|
|
383
|
-
notRun: 0,
|
|
384
|
-
total: 0,
|
|
385
|
-
successPercentage: '0.00%',
|
|
386
|
-
});
|
|
387
|
-
});
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
describe('mapAttachmentsUrl', () => {
|
|
391
|
-
it('should map attachment URLs correctly', () => {
|
|
392
|
-
// Arrange
|
|
393
|
-
const mockRunResults = [
|
|
394
|
-
{
|
|
395
|
-
testCaseId: 1,
|
|
396
|
-
lastRunId: 100,
|
|
397
|
-
lastResultId: 200,
|
|
398
|
-
iteration: {
|
|
399
|
-
attachments: [{ id: 1, name: 'attachment1.png', actionPath: 'path1' }],
|
|
400
|
-
actionResults: [{ actionPath: 'path1', stepPosition: '1.1' }],
|
|
401
|
-
},
|
|
402
|
-
analysisAttachments: [{ id: 2, fileName: 'analysis1.txt' }],
|
|
403
|
-
},
|
|
404
|
-
];
|
|
405
|
-
|
|
406
|
-
// Act
|
|
407
|
-
const result = resultDataProvider.mapAttachmentsUrl(mockRunResults, mockProjectName);
|
|
408
|
-
|
|
409
|
-
// Assert
|
|
410
|
-
expect(result[0].iteration.attachments[0].downloadUrl).toBe(
|
|
411
|
-
`${mockOrgUrl}${mockProjectName}/_apis/test/runs/100/results/200/attachments/1/attachment1.png`
|
|
412
|
-
);
|
|
413
|
-
expect(result[0].iteration.attachments[0].stepNo).toBe('1.1');
|
|
414
|
-
expect(result[0].analysisAttachments[0].downloadUrl).toBe(
|
|
415
|
-
`${mockOrgUrl}${mockProjectName}/_apis/test/runs/100/results/200/attachments/2/analysis1.txt`
|
|
416
|
-
);
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
it('should handle missing iteration', () => {
|
|
420
|
-
// Arrange
|
|
421
|
-
const mockRunResults = [
|
|
422
|
-
{
|
|
423
|
-
testCaseId: 1,
|
|
424
|
-
lastRunId: 100,
|
|
425
|
-
lastResultId: 200,
|
|
426
|
-
// No iteration
|
|
427
|
-
analysisAttachments: [{ id: 2, fileName: 'analysis1.txt' }],
|
|
428
|
-
},
|
|
429
|
-
];
|
|
430
|
-
|
|
431
|
-
// Act
|
|
432
|
-
const result = resultDataProvider.mapAttachmentsUrl(mockRunResults, mockProjectName);
|
|
433
|
-
|
|
434
|
-
// Assert
|
|
435
|
-
expect(result[0]).toEqual(mockRunResults[0]);
|
|
436
|
-
});
|
|
437
|
-
});
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
describe('getCombinedResultsSummary', () => {
|
|
441
|
-
it('should combine all results into expected format', async () => {
|
|
442
|
-
// Arrange
|
|
443
|
-
const mockTestSuites = {
|
|
444
|
-
value: [
|
|
445
|
-
{
|
|
446
|
-
id: 1,
|
|
447
|
-
name: 'Root Suite',
|
|
448
|
-
children: [{ id: 2, name: 'Child Suite 1', parentSuite: { id: 1 } }],
|
|
449
|
-
},
|
|
450
|
-
],
|
|
451
|
-
count: 1,
|
|
452
|
-
};
|
|
453
|
-
|
|
454
|
-
const mockTestPoints = {
|
|
455
|
-
value: [
|
|
456
|
-
{
|
|
457
|
-
testCaseReference: { id: 1, name: 'Test Case 1' },
|
|
458
|
-
configuration: { name: 'Config 1' },
|
|
459
|
-
results: {
|
|
460
|
-
outcome: 'passed',
|
|
461
|
-
lastTestRunId: 100,
|
|
462
|
-
lastResultId: 200,
|
|
463
|
-
lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } },
|
|
464
|
-
},
|
|
465
|
-
},
|
|
466
|
-
],
|
|
467
|
-
count: 1,
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
const mockTestCases = {
|
|
471
|
-
value: [
|
|
472
|
-
{
|
|
473
|
-
workItem: {
|
|
474
|
-
id: 1,
|
|
475
|
-
workItemFields: [{ key: 'Steps', value: '<steps>...</steps>' }],
|
|
476
|
-
},
|
|
477
|
-
},
|
|
478
|
-
],
|
|
479
|
-
};
|
|
480
|
-
|
|
481
|
-
const mockResult = {
|
|
482
|
-
testCase: { id: 1, name: 'Test Case 1' },
|
|
483
|
-
testSuite: { id: 2, name: 'Child Suite 1' },
|
|
484
|
-
iterationDetails: [
|
|
485
|
-
{
|
|
486
|
-
actionResults: [
|
|
487
|
-
{ stepIdentifier: '1', outcome: 'Passed', errorMessage: '', actionPath: 'path1' },
|
|
488
|
-
],
|
|
489
|
-
attachments: [],
|
|
490
|
-
},
|
|
491
|
-
],
|
|
492
|
-
testCaseRevision: 1,
|
|
493
|
-
failureType: null,
|
|
494
|
-
resolutionState: null,
|
|
495
|
-
comment: null,
|
|
496
|
-
};
|
|
497
|
-
|
|
498
|
-
// Setup mocks for API calls
|
|
499
|
-
(TFSServices.getItemContent as jest.Mock)
|
|
500
|
-
.mockResolvedValueOnce(mockTestSuites) // fetchTestSuites
|
|
501
|
-
.mockResolvedValueOnce(mockTestPoints) // fetchTestPoints
|
|
502
|
-
.mockResolvedValueOnce(mockTestCases) // fetchTestCasesBySuiteId
|
|
503
|
-
.mockResolvedValueOnce(mockResult) // fetchResult
|
|
504
|
-
.mockResolvedValueOnce({ value: [] }) // fetchResult - attachments
|
|
505
|
-
.mockResolvedValueOnce({ fields: {} }); // fetchResult - wiByRevision
|
|
506
|
-
|
|
507
|
-
const mockTestStepParserHelper = (resultDataProvider as any).testStepParserHelper;
|
|
508
|
-
mockTestStepParserHelper.parseTestSteps.mockResolvedValueOnce([
|
|
509
|
-
{
|
|
510
|
-
stepId: 1,
|
|
511
|
-
stepPosition: '1',
|
|
512
|
-
action: 'Do something',
|
|
513
|
-
expected: 'Something happens',
|
|
514
|
-
isSharedStepTitle: false,
|
|
515
|
-
},
|
|
516
|
-
]);
|
|
517
|
-
|
|
518
|
-
// Act
|
|
519
|
-
const result = await resultDataProvider.getCombinedResultsSummary(
|
|
520
|
-
mockTestPlanId,
|
|
521
|
-
mockProjectName,
|
|
522
|
-
undefined,
|
|
523
|
-
true
|
|
524
|
-
);
|
|
525
|
-
|
|
526
|
-
// Assert
|
|
527
|
-
expect(result.combinedResults.length).toBeGreaterThan(0);
|
|
528
|
-
expect(result.combinedResults[0]).toHaveProperty(
|
|
529
|
-
'contentControl',
|
|
530
|
-
'test-group-summary-content-control'
|
|
531
|
-
);
|
|
532
|
-
expect(result.combinedResults[1]).toHaveProperty(
|
|
533
|
-
'contentControl',
|
|
534
|
-
'test-result-summary-content-control'
|
|
535
|
-
);
|
|
536
|
-
expect(result.combinedResults[2]).toHaveProperty(
|
|
537
|
-
'contentControl',
|
|
538
|
-
'detailed-test-result-content-control'
|
|
539
|
-
);
|
|
540
|
-
});
|
|
541
|
-
});
|
|
542
|
-
});
|