@elisra-devops/docgen-data-provider 1.22.0 → 1.24.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.
Files changed (49) hide show
  1. package/bin/helpers/helper.js.map +1 -1
  2. package/bin/helpers/test/tfs.test.d.ts +1 -0
  3. package/bin/helpers/test/tfs.test.js +613 -0
  4. package/bin/helpers/test/tfs.test.js.map +1 -0
  5. package/bin/helpers/tfs.js +1 -1
  6. package/bin/helpers/tfs.js.map +1 -1
  7. package/bin/modules/GitDataProvider.js.map +1 -1
  8. package/bin/modules/PipelinesDataProvider.js +3 -2
  9. package/bin/modules/PipelinesDataProvider.js.map +1 -1
  10. package/bin/modules/ResultDataProvider.d.ts +200 -17
  11. package/bin/modules/ResultDataProvider.js +628 -195
  12. package/bin/modules/ResultDataProvider.js.map +1 -1
  13. package/bin/modules/TestDataProvider.js +7 -7
  14. package/bin/modules/TestDataProvider.js.map +1 -1
  15. package/bin/modules/TicketsDataProvider.d.ts +1 -1
  16. package/bin/modules/TicketsDataProvider.js +3 -2
  17. package/bin/modules/TicketsDataProvider.js.map +1 -1
  18. package/bin/modules/test/JfrogDataProvider.test.d.ts +1 -0
  19. package/bin/modules/test/JfrogDataProvider.test.js +110 -0
  20. package/bin/modules/test/JfrogDataProvider.test.js.map +1 -0
  21. package/bin/modules/test/ResultDataProvider.test.d.ts +1 -0
  22. package/bin/modules/test/ResultDataProvider.test.js +478 -0
  23. package/bin/modules/test/ResultDataProvider.test.js.map +1 -0
  24. package/bin/modules/test/gitDataProvider.test.js +424 -120
  25. package/bin/modules/test/gitDataProvider.test.js.map +1 -1
  26. package/bin/modules/test/managmentDataProvider.test.js +283 -28
  27. package/bin/modules/test/managmentDataProvider.test.js.map +1 -1
  28. package/bin/modules/test/pipelineDataProvider.test.js +229 -45
  29. package/bin/modules/test/pipelineDataProvider.test.js.map +1 -1
  30. package/bin/modules/test/testDataProvider.test.js +225 -81
  31. package/bin/modules/test/testDataProvider.test.js.map +1 -1
  32. package/bin/modules/test/ticketsDataProvider.test.js +310 -82
  33. package/bin/modules/test/ticketsDataProvider.test.js.map +1 -1
  34. package/package.json +1 -1
  35. package/src/helpers/helper.ts +16 -14
  36. package/src/helpers/test/tfs.test.ts +748 -0
  37. package/src/helpers/tfs.ts +1 -1
  38. package/src/modules/GitDataProvider.ts +10 -10
  39. package/src/modules/PipelinesDataProvider.ts +2 -2
  40. package/src/modules/ResultDataProvider.ts +834 -260
  41. package/src/modules/TestDataProvider.ts +8 -8
  42. package/src/modules/TicketsDataProvider.ts +5 -9
  43. package/src/modules/test/JfrogDataProvider.test.ts +171 -0
  44. package/src/modules/test/ResultDataProvider.test.ts +581 -0
  45. package/src/modules/test/gitDataProvider.test.ts +671 -187
  46. package/src/modules/test/managmentDataProvider.test.ts +386 -26
  47. package/src/modules/test/pipelineDataProvider.test.ts +281 -52
  48. package/src/modules/test/testDataProvider.test.ts +307 -105
  49. package/src/modules/test/ticketsDataProvider.test.ts +425 -129
@@ -1,118 +1,320 @@
1
- import DgDataProviderAzureDevOps from '../..';
1
+ import { TFSServices } from '../../helpers/tfs';
2
+ import { Helper, suiteData } from '../../helpers/helper';
3
+ import TestDataProvider from '../TestDataProvider';
4
+ import TestStepParserHelper from '../../utils/testStepParserHelper';
5
+ import logger from '../../utils/logger';
6
+ import { TestCase } from '../../models/tfs-data';
2
7
 
3
- require('dotenv').config();
4
- jest.setTimeout(600000);
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()));
5
13
 
6
- const orgUrl = process.env.ORG_URL;
7
- const token = process.env.PAT;
8
- const dgDataProviderAzureDevOps = new DgDataProviderAzureDevOps(orgUrl, token);
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';
9
22
 
10
- describe('Test module - tests', () => {
11
- test('should return test plans', async () => {
12
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
13
- let json: any = await TestDataProvider.GetTestPlans('tests');
14
- expect(json.count).toBeGreaterThanOrEqual(1);
15
- });
16
- test('should return test suites by plan', async () => {
17
- //not working yet
18
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
19
- let testSuites = await TestDataProvider.GetTestSuitesByPlan('tests', '540', true);
20
- expect(testSuites[0].name).toBe('TestSuite');
21
- });
22
- test('should return list of test cases', async () => {
23
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
24
- let attachList: any = await TestDataProvider.GetTestCasesBySuites(
25
- 'tests',
26
- '545',
27
- '546',
28
- true,
29
- true,
30
- true
31
- );
32
- expect(attachList.length > 0).toBeDefined();
33
- });
34
- test('should use Helper.findSuitesRecursive twice after restarting static value of Helper.first=True ', async () => {
35
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
36
- let suitesByPlan = await TestDataProvider.GetTestSuitesByPlan('tests', '545', true);
37
- expect(suitesByPlan.length > 0).toBeDefined();
38
- });
39
- test.skip('should return list of test cases - stress test - big testplan 1400 cases', async () => {
40
- jest.setTimeout(1000000);
41
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
42
- let attachList: any = await TestDataProvider.GetTestCasesBySuites(
43
- 'tests',
44
- '540',
45
- '549',
46
- true,
47
- true,
48
- true
49
- );
50
- expect(attachList.length > 1000).toBeDefined(); //not enough test cases for stress test
23
+ beforeEach(() => {
24
+ jest.clearAllMocks();
25
+ (Helper.suitList as any) = [];
26
+ (Helper.first as any) = false;
27
+
28
+ testDataProvider = new TestDataProvider(mockOrgUrl, mockToken);
51
29
  });
52
- test('should return test cases by suite', async () => {
53
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
54
- let json = await TestDataProvider.GetTestCases('tests', '540', '541');
55
- expect(json.count).toBeGreaterThan(0);
30
+
31
+ // Helper to access private method for testing
32
+ const invokeFetchWithCache = async (instance: any, url: string, ttl = 60000) => {
33
+ return instance.fetchWithCache.call(instance, url, ttl);
34
+ };
35
+
36
+ describe('fetchWithCache', () => {
37
+ it('should return cached data when available and not expired', async () => {
38
+ // Arrange
39
+ const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
40
+ const mockData = { value: 'test data' };
41
+ const cache = new Map();
42
+ cache.set(mockUrl, {
43
+ data: mockData,
44
+ timestamp: Date.now()
45
+ });
46
+ (testDataProvider as any).cache = cache;
47
+
48
+ // Act
49
+ const result = await invokeFetchWithCache(testDataProvider, mockUrl);
50
+
51
+ // Assert
52
+ expect(result).toEqual(mockData);
53
+ expect(TFSServices.getItemContent).not.toHaveBeenCalled();
54
+ });
55
+
56
+ it('should fetch new data when cache is expired', async () => {
57
+ // Arrange
58
+ const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
59
+ const mockData = { value: 'old data' };
60
+ const newData = { value: 'new data' };
61
+ const cache = new Map();
62
+ cache.set(mockUrl, {
63
+ data: mockData,
64
+ timestamp: Date.now() - 70000 // Expired (default TTL is 60000ms)
65
+ });
66
+ (testDataProvider as any).cache = cache;
67
+
68
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(newData);
69
+
70
+ // Act
71
+ const result = await invokeFetchWithCache(testDataProvider, mockUrl);
72
+
73
+ // Assert
74
+ expect(result).toEqual(newData);
75
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(mockUrl, mockToken);
76
+ });
77
+
78
+ it('should fetch and cache new data when not in cache', async () => {
79
+ // Arrange
80
+ const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
81
+ const mockData = { value: 'new data' };
82
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
83
+
84
+ // Act
85
+ const result = await invokeFetchWithCache(testDataProvider, mockUrl);
86
+
87
+ // Assert
88
+ expect(result).toEqual(mockData);
89
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(mockUrl, mockToken);
90
+ expect((testDataProvider as any).cache.has(mockUrl)).toBeTruthy();
91
+ expect((testDataProvider as any).cache.get(mockUrl).data).toEqual(mockData);
92
+ });
93
+
94
+ it('should throw and log error when fetch fails', async () => {
95
+ // Arrange
96
+ const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
97
+ const mockError = new Error('API call failed');
98
+ (TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
99
+
100
+ // Act & Assert
101
+ await expect(invokeFetchWithCache(testDataProvider, mockUrl)).rejects.toThrow('API call failed');
102
+ expect(logger.error).toHaveBeenCalledWith(`Error fetching ${mockUrl}: API call failed`);
103
+ });
56
104
  });
57
- test('should return test points by testcase', async () => {
58
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
59
- let json = await TestDataProvider.GetTestPoint('tests', '540', '541', '542');
60
- expect(json.count).toBeGreaterThan(0);
105
+
106
+ describe('GetTestSuiteByTestCase', () => {
107
+ it('should return test suites for a given test case ID', async () => {
108
+ // Arrange
109
+ const mockData = { value: [{ id: '123', name: 'Test Suite 1' }] };
110
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
111
+
112
+ // Act
113
+ const result = await testDataProvider.GetTestSuiteByTestCase(mockTestCaseId);
114
+
115
+ // Assert
116
+ expect(result).toEqual(mockData);
117
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
118
+ `${mockOrgUrl}_apis/testplan/suites?testCaseId=${mockTestCaseId}`,
119
+ mockToken
120
+ );
121
+ });
61
122
  });
62
- test('should return test runs by testcaseid', async () => {
63
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
64
- let json = await TestDataProvider.GetTestRunById('tests', '1000120');
65
- expect(json.id).toBe(1000120);
123
+
124
+ describe('GetTestPlans', () => {
125
+ it('should return test plans for a given project', async () => {
126
+ // Arrange
127
+ const mockData = {
128
+ value: [
129
+ { id: '456', name: 'Test Plan 1' },
130
+ { id: '789', name: 'Test Plan 2' }
131
+ ]
132
+ };
133
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
134
+
135
+ // Act
136
+ const result = await testDataProvider.GetTestPlans(mockProject);
137
+
138
+ // Assert
139
+ expect(result).toEqual(mockData);
140
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
141
+ `${mockOrgUrl}${mockProject}/_apis/test/plans`,
142
+ mockToken
143
+ );
144
+ });
66
145
  });
67
- test('should create run test according test pointId and return OK(200) as response ', async () => {
68
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
69
- let result: any = await TestDataProvider.CreateTestRun('tests', 'testrun', '540', '3');
70
- expect(result.status).toBe(200);
146
+
147
+ describe('GetTestSuites', () => {
148
+ it('should return test suites for a given project and plan ID', async () => {
149
+ // Arrange
150
+ const mockData = {
151
+ value: [
152
+ { id: '123', name: 'Test Suite 1' },
153
+ { id: '456', name: 'Test Suite 2' }
154
+ ]
155
+ };
156
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
157
+
158
+ // Act
159
+ const result = await testDataProvider.GetTestSuites(mockProject, mockPlanId);
160
+
161
+ // Assert
162
+ expect(result).toEqual(mockData);
163
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
164
+ `${mockOrgUrl}${mockProject}/_apis/test/Plans/${mockPlanId}/suites`,
165
+ mockToken
166
+ );
167
+ });
168
+
169
+ it('should return null and log error if fetching test suites fails', async () => {
170
+ // Arrange
171
+ const mockError = new Error('Failed to get test suites');
172
+ (TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
173
+
174
+ // Act
175
+ const result = await testDataProvider.GetTestSuites(mockProject, mockPlanId);
176
+
177
+ // Assert
178
+ expect(result).toBeNull();
179
+ });
71
180
  });
72
- test('should Update runId state and return OK(200) as response ', async () => {
73
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
74
- let result: any = await TestDataProvider.UpdateTestRun(
75
- 'tests',
76
- '1000124', //runId
77
- 'NeedsInvestigation' //Unspecified ,NotStarted, InProgress, Completed, Waiting, Aborted, NeedsInvestigation (State)
78
- );
79
- expect(result.status).toBe(200);
181
+
182
+ describe('GetTestSuitesForPlan', () => {
183
+ it('should throw error when project is not provided', async () => {
184
+ // Act & Assert
185
+ await expect(testDataProvider.GetTestSuitesForPlan('', mockPlanId))
186
+ .rejects.toThrow('Project not selected');
187
+ });
188
+
189
+ it('should throw error when plan ID is not provided', async () => {
190
+ // Act & Assert
191
+ await expect(testDataProvider.GetTestSuitesForPlan(mockProject, ''))
192
+ .rejects.toThrow('Plan not selected');
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
+ });
80
215
  });
81
- test('should Update test case state and return OK(200) as response ', async () => {
82
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
83
- let result: any = await TestDataProvider.UpdateTestCase(
84
- 'tests',
85
- '1000120',
86
- 2 //0-reset , 1-complite , 2-passed , 3-failed (State)
87
- );
88
- expect(result.status).toBe(200);
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
+ expect(Helper.first).toBe(true);
244
+ });
89
245
  });
90
- test('should Upload attachment for test run and return OK(200) as response ', async () => {
91
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
92
- let data = 'This is test line of data';
93
- let buff = new Buffer(data);
94
- let base64data = buff.toString('base64');
95
- let result: any = await TestDataProvider.UploadTestAttachment(
96
- '1000120', //runID
97
- 'tests',
98
- base64data, //stream
99
- 'testAttachment2.json', //fileName
100
- 'Test attachment upload', //comment
101
- 'GeneralAttachment' //attachmentType
102
- );
103
- expect(result.status).toBe(200);
246
+
247
+ describe('GetTestCases', () => {
248
+ it('should return test cases for a given project, plan ID, and suite ID', async () => {
249
+ // Arrange
250
+ const mockData = {
251
+ count: 2,
252
+ value: [
253
+ { testCase: { id: '101', name: 'Test Case 1', url: 'url1' } },
254
+ { testCase: { id: '102', name: 'Test Case 2', url: 'url2' } }
255
+ ]
256
+ };
257
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockData);
258
+
259
+ // Act
260
+ const result = await testDataProvider.GetTestCases(mockProject, mockPlanId, mockSuiteId);
261
+
262
+ // Assert
263
+ expect(result).toEqual(mockData);
264
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
265
+ `${mockOrgUrl}${mockProject}/_apis/test/Plans/${mockPlanId}/suites/${mockSuiteId}/testcases/`,
266
+ mockToken
267
+ );
268
+ expect(logger.debug).toHaveBeenCalledWith(
269
+ `test cases for plan ${mockPlanId} and ${mockSuiteId} were found`
270
+ );
271
+ });
104
272
  });
105
- test('should Get all test case data', async () => {
106
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
107
- let result: any = await TestDataProvider.GetTestSuiteByTestCase('544');
108
- expect(result).toBeDefined;
273
+
274
+ describe('clearCache', () => {
275
+ it('should clear the cache', () => {
276
+ // Arrange
277
+ const mockUrl = `${mockOrgUrl}_apis/test/endpoint`;
278
+ const mockData = { value: 'test data' };
279
+ const cache = new Map();
280
+ cache.set(mockUrl, {
281
+ data: mockData,
282
+ timestamp: Date.now()
283
+ });
284
+ (testDataProvider as any).cache = cache;
285
+
286
+ // Act
287
+ testDataProvider.clearCache();
288
+
289
+ // Assert
290
+ expect((testDataProvider as any).cache.size).toBe(0);
291
+ expect(logger.debug).toHaveBeenCalledWith('Cache cleared');
292
+ });
109
293
  });
110
- test('should Get test points by test case id', async () => {
111
- let TestDataProvider = await dgDataProviderAzureDevOps.getTestDataProvider();
112
- let result: any = await TestDataProvider.GetTestPointByTestCaseId(
113
- 'tests',
114
- '544' //testCaseId
115
- );
116
- expect(result).toBeDefined;
294
+
295
+ describe('UpdateTestRun', () => {
296
+ it('should update a test run with the correct state', async () => {
297
+ // Arrange
298
+ const mockRunId = '12345';
299
+ const mockState = 'Completed';
300
+ const mockResponse = { id: mockRunId, state: mockState };
301
+
302
+ (TFSServices.postRequest as jest.Mock).mockResolvedValueOnce(mockResponse);
303
+
304
+ // Act
305
+ const result = await testDataProvider.UpdateTestRun(mockProject, mockRunId, mockState);
306
+
307
+ // Assert
308
+ expect(result).toEqual(mockResponse);
309
+ expect(TFSServices.postRequest).toHaveBeenCalledWith(
310
+ `${mockOrgUrl}${mockProject}/_apis/test/Runs/${mockRunId}?api-version=5.0`,
311
+ mockToken,
312
+ 'PATCH',
313
+ { state: mockState },
314
+ null
315
+ );
316
+ expect(logger.info).toHaveBeenCalledWith(`Update runId : ${mockRunId} to state : ${mockState}`);
317
+ });
117
318
  });
118
- });
319
+
320
+ });