@elisra-devops/docgen-data-provider 1.63.13 → 1.67.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/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,292 +0,0 @@
|
|
|
1
|
-
import { PipelineRun } from '../../models/tfs-data';
|
|
2
|
-
import { TFSServices } from '../../helpers/tfs';
|
|
3
|
-
import PipelinesDataProvider from '../PipelinesDataProvider';
|
|
4
|
-
import GitDataProvider from '../GitDataProvider';
|
|
5
|
-
import logger from '../../utils/logger';
|
|
6
|
-
|
|
7
|
-
jest.mock('../../helpers/tfs');
|
|
8
|
-
jest.mock('../../utils/logger');
|
|
9
|
-
jest.mock('../GitDataProvider');
|
|
10
|
-
|
|
11
|
-
describe('PipelinesDataProvider', () => {
|
|
12
|
-
let pipelinesDataProvider: PipelinesDataProvider;
|
|
13
|
-
const mockOrgUrl = 'https://dev.azure.com/orgname/';
|
|
14
|
-
const mockToken = 'mock-token';
|
|
15
|
-
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
jest.clearAllMocks();
|
|
18
|
-
pipelinesDataProvider = new PipelinesDataProvider(mockOrgUrl, mockToken);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe('isMatchingPipeline', () => {
|
|
22
|
-
// Create test method to access private method
|
|
23
|
-
const invokeIsMatchingPipeline = (
|
|
24
|
-
fromPipeline: PipelineRun,
|
|
25
|
-
targetPipeline: PipelineRun,
|
|
26
|
-
searchPrevPipelineFromDifferentCommit: boolean
|
|
27
|
-
): boolean => {
|
|
28
|
-
return (pipelinesDataProvider as any).isMatchingPipeline(
|
|
29
|
-
fromPipeline,
|
|
30
|
-
targetPipeline,
|
|
31
|
-
searchPrevPipelineFromDifferentCommit
|
|
32
|
-
);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
it('should return false when repository IDs are different', () => {
|
|
36
|
-
// Arrange
|
|
37
|
-
const fromPipeline = {
|
|
38
|
-
resources: {
|
|
39
|
-
repositories: {
|
|
40
|
-
'0': {
|
|
41
|
-
self: {
|
|
42
|
-
repository: { id: 'repo1' },
|
|
43
|
-
version: 'v1',
|
|
44
|
-
refName: 'refs/heads/main'
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
} as unknown as PipelineRun;
|
|
50
|
-
|
|
51
|
-
const targetPipeline = {
|
|
52
|
-
resources: {
|
|
53
|
-
repositories: {
|
|
54
|
-
'0': {
|
|
55
|
-
self: {
|
|
56
|
-
repository: { id: 'repo2' },
|
|
57
|
-
version: 'v1',
|
|
58
|
-
refName: 'refs/heads/main'
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
} as unknown as PipelineRun;
|
|
64
|
-
|
|
65
|
-
// Act
|
|
66
|
-
const result = invokeIsMatchingPipeline(fromPipeline, targetPipeline, false);
|
|
67
|
-
|
|
68
|
-
// Assert
|
|
69
|
-
expect(result).toBe(false);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should return true when versions are the same and searchPrevPipelineFromDifferentCommit is false', () => {
|
|
73
|
-
// Arrange
|
|
74
|
-
const fromPipeline = {
|
|
75
|
-
resources: {
|
|
76
|
-
repositories: {
|
|
77
|
-
'0': {
|
|
78
|
-
self: {
|
|
79
|
-
repository: { id: 'repo1' },
|
|
80
|
-
version: 'v1',
|
|
81
|
-
refName: 'refs/heads/main'
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
} as unknown as PipelineRun;
|
|
87
|
-
|
|
88
|
-
const targetPipeline = {
|
|
89
|
-
resources: {
|
|
90
|
-
repositories: {
|
|
91
|
-
'0': {
|
|
92
|
-
self: {
|
|
93
|
-
repository: { id: 'repo1' },
|
|
94
|
-
version: 'v1',
|
|
95
|
-
refName: 'refs/heads/main'
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
} as unknown as PipelineRun;
|
|
101
|
-
|
|
102
|
-
// Act
|
|
103
|
-
const result = invokeIsMatchingPipeline(fromPipeline, targetPipeline, false);
|
|
104
|
-
|
|
105
|
-
// Assert
|
|
106
|
-
expect(result).toBe(true);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('should return false when versions are the same and searchPrevPipelineFromDifferentCommit is true', () => {
|
|
110
|
-
// Arrange
|
|
111
|
-
const fromPipeline = {
|
|
112
|
-
resources: {
|
|
113
|
-
repositories: {
|
|
114
|
-
'0': {
|
|
115
|
-
self: {
|
|
116
|
-
repository: { id: 'repo1' },
|
|
117
|
-
version: 'v1',
|
|
118
|
-
refName: 'refs/heads/main'
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
} as unknown as PipelineRun;
|
|
124
|
-
|
|
125
|
-
const targetPipeline = {
|
|
126
|
-
resources: {
|
|
127
|
-
repositories: {
|
|
128
|
-
'0': {
|
|
129
|
-
self: {
|
|
130
|
-
repository: { id: 'repo1' },
|
|
131
|
-
version: 'v1',
|
|
132
|
-
refName: 'refs/heads/main'
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
} as unknown as PipelineRun;
|
|
138
|
-
|
|
139
|
-
// Act
|
|
140
|
-
const result = invokeIsMatchingPipeline(fromPipeline, targetPipeline, true);
|
|
141
|
-
|
|
142
|
-
// Assert
|
|
143
|
-
expect(result).toBe(false);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should return true when refNames match but versions differ', () => {
|
|
147
|
-
// Arrange
|
|
148
|
-
const fromPipeline = {
|
|
149
|
-
resources: {
|
|
150
|
-
repositories: {
|
|
151
|
-
'0': {
|
|
152
|
-
self: {
|
|
153
|
-
repository: { id: 'repo1' },
|
|
154
|
-
version: 'v1',
|
|
155
|
-
refName: 'refs/heads/main'
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
} as unknown as PipelineRun;
|
|
161
|
-
|
|
162
|
-
const targetPipeline = {
|
|
163
|
-
resources: {
|
|
164
|
-
repositories: {
|
|
165
|
-
'0': {
|
|
166
|
-
self: {
|
|
167
|
-
repository: { id: 'repo1' },
|
|
168
|
-
version: 'v2',
|
|
169
|
-
refName: 'refs/heads/main'
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
} as unknown as PipelineRun;
|
|
175
|
-
|
|
176
|
-
// Act
|
|
177
|
-
const result = invokeIsMatchingPipeline(fromPipeline, targetPipeline, true);
|
|
178
|
-
|
|
179
|
-
// Assert
|
|
180
|
-
expect(result).toBe(true);
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it('should use __designer_repo when self is not available', () => {
|
|
184
|
-
// Arrange
|
|
185
|
-
const fromPipeline = {
|
|
186
|
-
resources: {
|
|
187
|
-
repositories: {
|
|
188
|
-
__designer_repo: {
|
|
189
|
-
repository: { id: 'repo1' },
|
|
190
|
-
version: 'v1',
|
|
191
|
-
refName: 'refs/heads/main'
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
} as unknown as PipelineRun;
|
|
196
|
-
|
|
197
|
-
const targetPipeline = {
|
|
198
|
-
resources: {
|
|
199
|
-
repositories: {
|
|
200
|
-
__designer_repo: {
|
|
201
|
-
repository: { id: 'repo1' },
|
|
202
|
-
version: 'v1',
|
|
203
|
-
refName: 'refs/heads/main'
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
} as unknown as PipelineRun;
|
|
208
|
-
|
|
209
|
-
// Act
|
|
210
|
-
const result = invokeIsMatchingPipeline(fromPipeline, targetPipeline, false);
|
|
211
|
-
|
|
212
|
-
// Assert
|
|
213
|
-
expect(result).toBe(true);
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
describe('getPipelineRunDetails', () => {
|
|
218
|
-
it('should call TFSServices.getItemContent with correct parameters', async () => {
|
|
219
|
-
// Arrange
|
|
220
|
-
const projectName = 'project1';
|
|
221
|
-
const pipelineId = 123;
|
|
222
|
-
const runId = 456;
|
|
223
|
-
const mockResponse = { id: runId, resources: {} };
|
|
224
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
225
|
-
|
|
226
|
-
// Act
|
|
227
|
-
const result = await pipelinesDataProvider.getPipelineRunDetails(projectName, pipelineId, runId);
|
|
228
|
-
|
|
229
|
-
// Assert
|
|
230
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
231
|
-
`${mockOrgUrl}${projectName}/_apis/pipelines/${pipelineId}/runs/${runId}`,
|
|
232
|
-
mockToken
|
|
233
|
-
);
|
|
234
|
-
expect(result).toEqual(mockResponse);
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
describe('GetPipelineRunHistory', () => {
|
|
239
|
-
it('should return filtered pipeline run history', async () => {
|
|
240
|
-
// Arrange
|
|
241
|
-
const projectName = 'project1';
|
|
242
|
-
const pipelineId = '123';
|
|
243
|
-
const mockResponse = {
|
|
244
|
-
value: [
|
|
245
|
-
{ id: 1, result: 'succeeded' },
|
|
246
|
-
{ id: 2, result: 'failed' },
|
|
247
|
-
{ id: 3, result: 'canceled' },
|
|
248
|
-
{ id: 4, result: 'succeeded' }
|
|
249
|
-
]
|
|
250
|
-
};
|
|
251
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
252
|
-
|
|
253
|
-
// Act
|
|
254
|
-
const result = await pipelinesDataProvider.GetPipelineRunHistory(projectName, pipelineId);
|
|
255
|
-
|
|
256
|
-
// Assert
|
|
257
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
258
|
-
`${mockOrgUrl}${projectName}/_apis/pipelines/${pipelineId}/runs`,
|
|
259
|
-
mockToken,
|
|
260
|
-
'get',
|
|
261
|
-
null,
|
|
262
|
-
null
|
|
263
|
-
);
|
|
264
|
-
expect(result).toEqual({
|
|
265
|
-
count: 4, // Note: Current filter logic keeps all runs where result is not 'failed' AND not 'canceled'
|
|
266
|
-
value: mockResponse.value
|
|
267
|
-
});
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
it('should handle API errors gracefully', async () => {
|
|
271
|
-
// Arrange
|
|
272
|
-
const projectName = 'project1';
|
|
273
|
-
const pipelineId = '123';
|
|
274
|
-
const expectedError = new Error('API error');
|
|
275
|
-
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
|
|
276
|
-
|
|
277
|
-
// Act
|
|
278
|
-
const result = await pipelinesDataProvider.GetPipelineRunHistory(projectName, pipelineId);
|
|
279
|
-
|
|
280
|
-
// Assert
|
|
281
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
282
|
-
`${mockOrgUrl}${projectName}/_apis/pipelines/${pipelineId}/runs`,
|
|
283
|
-
mockToken,
|
|
284
|
-
'get',
|
|
285
|
-
null,
|
|
286
|
-
null
|
|
287
|
-
);
|
|
288
|
-
expect(logger.error).toHaveBeenCalledWith(`Could not fetch Pipeline Run History: ${expectedError.message}`);
|
|
289
|
-
expect(result).toBeUndefined();
|
|
290
|
-
});
|
|
291
|
-
});
|
|
292
|
-
});
|
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
import { TFSServices } from '../../helpers/tfs';
|
|
2
|
-
import { Helper, suiteData } from '../../helpers/helper';
|
|
3
|
-
import TestDataProvider from '../TestDataProvider';
|
|
4
|
-
import Utils from '../../utils/testStepParserHelper';
|
|
5
|
-
import logger from '../../utils/logger';
|
|
6
|
-
import { TestCase } from '../../models/tfs-data';
|
|
7
|
-
|
|
8
|
-
jest.mock('../../helpers/tfs');
|
|
9
|
-
jest.mock('../../utils/logger');
|
|
10
|
-
jest.mock('../../helpers/helper');
|
|
11
|
-
jest.mock('../../utils/testStepParserHelper');
|
|
12
|
-
jest.mock('p-limit', () => jest.fn(() => (fn: Function) => fn()));
|
|
13
|
-
|
|
14
|
-
describe('TestDataProvider', () => {
|
|
15
|
-
let testDataProvider: TestDataProvider;
|
|
16
|
-
const mockOrgUrl = 'https://dev.azure.com/orgname/';
|
|
17
|
-
const mockToken = 'mock-token';
|
|
18
|
-
const mockProject = 'project-123';
|
|
19
|
-
const mockPlanId = '456';
|
|
20
|
-
const mockSuiteId = '789';
|
|
21
|
-
const mockTestCaseId = '101112';
|
|
22
|
-
|
|
23
|
-
beforeEach(() => {
|
|
24
|
-
jest.clearAllMocks();
|
|
25
|
-
|
|
26
|
-
testDataProvider = new TestDataProvider(mockOrgUrl, mockToken);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// Helper to access private method for testing
|
|
30
|
-
const invokeFetchWithCache = async (instance: any, url: string, ttl = 60000) => {
|
|
31
|
-
return instance.fetchWithCache.call(instance, url, ttl);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
describe('fetchWithCache', () => {
|
|
35
|
-
it('should return cached data when available and not expired', async () => {
|
|
36
|
-
// Arrange
|
|
37
|
-
const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
|
|
38
|
-
const mockData = { value: 'test data' };
|
|
39
|
-
const cache = new Map();
|
|
40
|
-
cache.set(mockUrl, {
|
|
41
|
-
data: mockData,
|
|
42
|
-
timestamp: Date.now(),
|
|
43
|
-
});
|
|
44
|
-
(testDataProvider as any).cache = cache;
|
|
45
|
-
|
|
46
|
-
// Act
|
|
47
|
-
const result = await invokeFetchWithCache(testDataProvider, mockUrl);
|
|
48
|
-
|
|
49
|
-
// Assert
|
|
50
|
-
expect(result).toEqual(mockData);
|
|
51
|
-
expect(TFSServices.getItemContent).not.toHaveBeenCalled();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should fetch new data when cache is expired', async () => {
|
|
55
|
-
// Arrange
|
|
56
|
-
const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
|
|
57
|
-
const mockData = { value: 'old data' };
|
|
58
|
-
const newData = { value: 'new data' };
|
|
59
|
-
const cache = new Map();
|
|
60
|
-
cache.set(mockUrl, {
|
|
61
|
-
data: mockData,
|
|
62
|
-
timestamp: Date.now() - 70000, // Expired (default TTL is 60000ms)
|
|
63
|
-
});
|
|
64
|
-
(testDataProvider as any).cache = cache;
|
|
65
|
-
|
|
66
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(newData);
|
|
67
|
-
|
|
68
|
-
// Act
|
|
69
|
-
const result = await invokeFetchWithCache(testDataProvider, mockUrl);
|
|
70
|
-
|
|
71
|
-
// Assert
|
|
72
|
-
expect(result).toEqual(newData);
|
|
73
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(mockUrl, mockToken);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should fetch and cache new data when not in cache', async () => {
|
|
77
|
-
// Arrange
|
|
78
|
-
const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
|
|
79
|
-
const mockData = { value: 'new data' };
|
|
80
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
|
|
81
|
-
|
|
82
|
-
// Act
|
|
83
|
-
const result = await invokeFetchWithCache(testDataProvider, mockUrl);
|
|
84
|
-
|
|
85
|
-
// Assert
|
|
86
|
-
expect(result).toEqual(mockData);
|
|
87
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(mockUrl, mockToken);
|
|
88
|
-
expect((testDataProvider as any).cache.has(mockUrl)).toBeTruthy();
|
|
89
|
-
expect((testDataProvider as any).cache.get(mockUrl).data).toEqual(mockData);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('should throw and log error when fetch fails', async () => {
|
|
93
|
-
// Arrange
|
|
94
|
-
const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
|
|
95
|
-
const mockError = new Error('API call failed');
|
|
96
|
-
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
|
|
97
|
-
|
|
98
|
-
// Act & Assert
|
|
99
|
-
await expect(invokeFetchWithCache(testDataProvider, mockUrl)).rejects.toThrow('API call failed');
|
|
100
|
-
expect(logger.error).toHaveBeenCalledWith(`Error fetching ${mockUrl}: API call failed`);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe('GetTestSuiteByTestCase', () => {
|
|
105
|
-
it('should return test suites for a given test case ID', async () => {
|
|
106
|
-
// Arrange
|
|
107
|
-
const mockData = { value: [{ id: '123', name: 'Test Suite 1' }] };
|
|
108
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
|
|
109
|
-
|
|
110
|
-
// Act
|
|
111
|
-
const result = await testDataProvider.GetTestSuiteByTestCase(mockTestCaseId);
|
|
112
|
-
|
|
113
|
-
// Assert
|
|
114
|
-
expect(result).toEqual(mockData);
|
|
115
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
116
|
-
`${mockOrgUrl}_apis/testplan/suites?testCaseId=${mockTestCaseId}`,
|
|
117
|
-
mockToken
|
|
118
|
-
);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
describe('GetTestPlans', () => {
|
|
123
|
-
it('should return test plans for a given project', async () => {
|
|
124
|
-
// Arrange
|
|
125
|
-
const mockData = {
|
|
126
|
-
value: [
|
|
127
|
-
{ id: '456', name: 'Test Plan 1' },
|
|
128
|
-
{ id: '789', name: 'Test Plan 2' },
|
|
129
|
-
],
|
|
130
|
-
};
|
|
131
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
|
|
132
|
-
|
|
133
|
-
// Act
|
|
134
|
-
const result = await testDataProvider.GetTestPlans(mockProject);
|
|
135
|
-
|
|
136
|
-
// Assert
|
|
137
|
-
expect(result).toEqual(mockData);
|
|
138
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
139
|
-
`${mockOrgUrl}${mockProject}/_apis/test/plans`,
|
|
140
|
-
mockToken
|
|
141
|
-
);
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
describe('GetTestSuites', () => {
|
|
146
|
-
it('should return test suites for a given project and plan ID', async () => {
|
|
147
|
-
// Arrange
|
|
148
|
-
const mockData = {
|
|
149
|
-
value: [
|
|
150
|
-
{ id: '123', name: 'Test Suite 1' },
|
|
151
|
-
{ id: '456', name: 'Test Suite 2' },
|
|
152
|
-
],
|
|
153
|
-
};
|
|
154
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
|
|
155
|
-
|
|
156
|
-
// Act
|
|
157
|
-
const result = await testDataProvider.GetTestSuites(mockProject, mockPlanId);
|
|
158
|
-
|
|
159
|
-
// Assert
|
|
160
|
-
expect(result).toEqual(mockData);
|
|
161
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
162
|
-
`${mockOrgUrl}${mockProject}/_apis/test/Plans/${mockPlanId}/suites`,
|
|
163
|
-
mockToken
|
|
164
|
-
);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should return null and log error if fetching test suites fails', async () => {
|
|
168
|
-
// Arrange
|
|
169
|
-
const mockError = new Error('Failed to get test suites');
|
|
170
|
-
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
|
|
171
|
-
|
|
172
|
-
// Act
|
|
173
|
-
const result = await testDataProvider.GetTestSuites(mockProject, mockPlanId);
|
|
174
|
-
|
|
175
|
-
// Assert
|
|
176
|
-
expect(result).toBeNull();
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
describe('GetTestSuitesForPlan', () => {
|
|
181
|
-
it('should throw error when project is not provided', async () => {
|
|
182
|
-
// Act & Assert
|
|
183
|
-
await expect(testDataProvider.GetTestSuitesForPlan('', mockPlanId)).rejects.toThrow(
|
|
184
|
-
'Project not selected'
|
|
185
|
-
);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should throw error when plan ID is not provided', async () => {
|
|
189
|
-
// Act & Assert
|
|
190
|
-
await expect(testDataProvider.GetTestSuitesForPlan(mockProject, '')).rejects.toThrow(
|
|
191
|
-
'Plan not selected'
|
|
192
|
-
);
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
it('should return test suites for a plan', async () => {
|
|
196
|
-
// Arrange
|
|
197
|
-
const mockData = {
|
|
198
|
-
testSuites: [
|
|
199
|
-
{ id: '123', name: 'Test Suite 1' },
|
|
200
|
-
{ id: '456', name: 'Test Suite 2' },
|
|
201
|
-
],
|
|
202
|
-
};
|
|
203
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
|
|
204
|
-
|
|
205
|
-
// Act
|
|
206
|
-
const result = await testDataProvider.GetTestSuitesForPlan(mockProject, mockPlanId);
|
|
207
|
-
|
|
208
|
-
// Assert
|
|
209
|
-
expect(result).toEqual(mockData);
|
|
210
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
211
|
-
`${mockOrgUrl}/${mockProject}/_api/_testManagement/GetTestSuitesForPlan?__v=5&planId=${mockPlanId}`,
|
|
212
|
-
mockToken
|
|
213
|
-
);
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
describe('GetTestSuiteById', () => {
|
|
218
|
-
it('should call GetTestSuitesForPlan and Helper.findSuitesRecursive with correct params', async () => {
|
|
219
|
-
// Arrange
|
|
220
|
-
const mockTestSuites = { testSuites: [{ id: '123', name: 'Test Suite 1' }] };
|
|
221
|
-
const mockSuiteData = [new suiteData('Test Suite 1', '123', '456', 1)];
|
|
222
|
-
|
|
223
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockTestSuites);
|
|
224
|
-
(Helper.findSuitesRecursive as jest.Mock).mockReturnValueOnce(mockSuiteData);
|
|
225
|
-
|
|
226
|
-
// Act
|
|
227
|
-
const result = await testDataProvider.GetTestSuiteById(mockProject, mockPlanId, mockSuiteId, true);
|
|
228
|
-
|
|
229
|
-
// Assert
|
|
230
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
231
|
-
`${mockOrgUrl}/${mockProject}/_api/_testManagement/GetTestSuitesForPlan?__v=5&planId=${mockPlanId}`,
|
|
232
|
-
mockToken
|
|
233
|
-
);
|
|
234
|
-
expect(Helper.findSuitesRecursive).toHaveBeenCalledWith(
|
|
235
|
-
mockPlanId,
|
|
236
|
-
mockOrgUrl,
|
|
237
|
-
mockProject,
|
|
238
|
-
mockTestSuites.testSuites,
|
|
239
|
-
mockSuiteId,
|
|
240
|
-
true
|
|
241
|
-
);
|
|
242
|
-
expect(result).toEqual(mockSuiteData);
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
describe('GetTestCases', () => {
|
|
247
|
-
it('should return test cases for a given project, plan ID, and suite ID', async () => {
|
|
248
|
-
// Arrange
|
|
249
|
-
const mockData = {
|
|
250
|
-
count: 2,
|
|
251
|
-
value: [
|
|
252
|
-
{ testCase: { id: '101', name: 'Test Case 1', url: 'url1' } },
|
|
253
|
-
{ testCase: { id: '102', name: 'Test Case 2', url: 'url2' } },
|
|
254
|
-
],
|
|
255
|
-
};
|
|
256
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
|
|
257
|
-
|
|
258
|
-
// Act
|
|
259
|
-
const result = await testDataProvider.GetTestCases(mockProject, mockPlanId, mockSuiteId);
|
|
260
|
-
|
|
261
|
-
// Assert
|
|
262
|
-
expect(result).toEqual(mockData);
|
|
263
|
-
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
264
|
-
`${mockOrgUrl}${mockProject}/_apis/test/Plans/${mockPlanId}/suites/${mockSuiteId}/testcases/`,
|
|
265
|
-
mockToken
|
|
266
|
-
);
|
|
267
|
-
expect(logger.debug).toHaveBeenCalledWith(
|
|
268
|
-
`test cases for plan ${mockPlanId} and ${mockSuiteId} were found`
|
|
269
|
-
);
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
describe('clearCache', () => {
|
|
274
|
-
it('should clear the cache', () => {
|
|
275
|
-
// Arrange
|
|
276
|
-
const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
|
|
277
|
-
const mockData = { value: 'test data' };
|
|
278
|
-
const cache = new Map();
|
|
279
|
-
cache.set(mockUrl, {
|
|
280
|
-
data: mockData,
|
|
281
|
-
timestamp: Date.now(),
|
|
282
|
-
});
|
|
283
|
-
(testDataProvider as any).cache = cache;
|
|
284
|
-
|
|
285
|
-
// Act
|
|
286
|
-
testDataProvider.clearCache();
|
|
287
|
-
|
|
288
|
-
// Assert
|
|
289
|
-
expect((testDataProvider as any).cache.size).toBe(0);
|
|
290
|
-
expect(logger.debug).toHaveBeenCalledWith('Cache cleared');
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
describe('UpdateTestRun', () => {
|
|
295
|
-
it('should update a test run with the correct state', async () => {
|
|
296
|
-
// Arrange
|
|
297
|
-
const mockRunId = '12345';
|
|
298
|
-
const mockState = 'Completed';
|
|
299
|
-
const mockResponse = { id: mockRunId, state: mockState };
|
|
300
|
-
|
|
301
|
-
(TFSServices.postRequest as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
302
|
-
|
|
303
|
-
// Act
|
|
304
|
-
const result = await testDataProvider.UpdateTestRun(mockProject, mockRunId, mockState);
|
|
305
|
-
|
|
306
|
-
// Assert
|
|
307
|
-
expect(result).toEqual(mockResponse);
|
|
308
|
-
expect(TFSServices.postRequest).toHaveBeenCalledWith(
|
|
309
|
-
`${mockOrgUrl}${mockProject}/_apis/test/Runs/${mockRunId}?api-version=5.0`,
|
|
310
|
-
mockToken,
|
|
311
|
-
'PATCH',
|
|
312
|
-
{ state: mockState },
|
|
313
|
-
null
|
|
314
|
-
);
|
|
315
|
-
expect(logger.info).toHaveBeenCalledWith(`Update runId : ${mockRunId} to state : ${mockState}`);
|
|
316
|
-
});
|
|
317
|
-
});
|
|
318
|
-
});
|