@elisra-devops/docgen-data-provider 1.22.0 → 1.23.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 +199 -17
  11. package/bin/modules/ResultDataProvider.js +611 -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 +815 -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,34 +1,394 @@
1
- import DgDataProviderAzureDevOps from "../..";
1
+ import { TFSServices } from '../../helpers/tfs';
2
+ import MangementDataProvider from '../MangementDataProvider';
2
3
 
3
- require("dotenv").config();
4
- jest.setTimeout(60000);
4
+ jest.mock('../../helpers/tfs');
5
5
 
6
- const orgUrl = process.env.ORG_URL;
7
- const token = process.env.PAT;
8
- const dgDataProviderAzureDevOps = new DgDataProviderAzureDevOps(orgUrl,token);
6
+ describe('MangementDataProvider', () => {
7
+ let managementDataProvider: MangementDataProvider;
8
+ const mockOrgUrl = 'https://dev.azure.com/organization/';
9
+ const mockToken = 'mock-token';
9
10
 
11
+ beforeEach(() => {
12
+ jest.clearAllMocks();
13
+ managementDataProvider = new MangementDataProvider(mockOrgUrl, mockToken);
14
+ });
15
+
16
+ describe('GetCllectionLinkTypes', () => {
17
+ it('should return collection link types when API call succeeds', async () => {
18
+ // Arrange
19
+ const mockResponse = {
20
+ value: [
21
+ { id: 'link-1', name: 'Child' },
22
+ { id: 'link-2', name: 'Related' }
23
+ ]
24
+ };
25
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
26
+
27
+ // Act
28
+ const result = await managementDataProvider.GetCllectionLinkTypes();
29
+
30
+ // Assert
31
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
32
+ `${mockOrgUrl}_apis/wit/workitemrelationtypes`,
33
+ mockToken,
34
+ 'get',
35
+ null,
36
+ null
37
+ );
38
+ expect(result).toEqual(mockResponse);
39
+ });
40
+
41
+ it('should throw an error when the API call fails', async () => {
42
+ // Arrange
43
+ const expectedError = new Error('API call failed');
44
+ (TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
45
+
46
+ // Act & Assert
47
+ await expect(managementDataProvider.GetCllectionLinkTypes())
48
+ .rejects.toThrow('API call failed');
49
+
50
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
51
+ `${mockOrgUrl}_apis/wit/workitemrelationtypes`,
52
+ mockToken,
53
+ 'get',
54
+ null,
55
+ null
56
+ );
57
+ });
58
+ });
59
+
60
+ describe('GetProjects', () => {
61
+ it('should return projects when API call succeeds', async () => {
62
+ // Arrange
63
+ const mockResponse = {
64
+ count: 2,
65
+ value: [
66
+ { id: 'project-1', name: 'Project One' },
67
+ { id: 'project-2', name: 'Project Two' }
68
+ ]
69
+ };
70
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
71
+
72
+ // Act
73
+ const result = await managementDataProvider.GetProjects();
74
+
75
+ // Assert
76
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
77
+ `${mockOrgUrl}_apis/projects?$top=1000`,
78
+ mockToken
79
+ );
80
+ expect(result).toEqual(mockResponse);
81
+ });
82
+
83
+ it('should throw an error when the API call fails', async () => {
84
+ // Arrange
85
+ const expectedError = new Error('Projects API call failed');
86
+ (TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
87
+
88
+ // Act & Assert
89
+ await expect(managementDataProvider.GetProjects())
90
+ .rejects.toThrow('Projects API call failed');
91
+
92
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
93
+ `${mockOrgUrl}_apis/projects?$top=1000`,
94
+ mockToken
95
+ );
96
+ });
97
+ });
98
+
99
+ describe('GetProjectByName', () => {
100
+ it('should return a project when project exists with given name', async () => {
101
+ // Arrange
102
+ const mockProjects = {
103
+ count: 2,
104
+ value: [
105
+ { id: 'project-1', name: 'Project One' },
106
+ { id: 'project-2', name: 'Project Two' }
107
+ ]
108
+ };
109
+ const expectedProject = { id: 'project-2', name: 'Project Two' };
110
+
111
+ // Mock GetProjects to return our mock data
112
+ jest.spyOn(managementDataProvider, 'GetProjects').mockResolvedValueOnce(mockProjects);
113
+
114
+ // Act
115
+ const result = await managementDataProvider.GetProjectByName('Project Two');
116
+
117
+ // Assert
118
+ expect(managementDataProvider.GetProjects).toHaveBeenCalledTimes(1);
119
+ expect(result).toEqual(expectedProject);
120
+ });
121
+
122
+ it('should return empty object when project does not exist with given name', async () => {
123
+ // Arrange
124
+ const mockProjects = {
125
+ count: 2,
126
+ value: [
127
+ { id: 'project-1', name: 'Project One' },
128
+ { id: 'project-2', name: 'Project Two' }
129
+ ]
130
+ };
131
+
132
+ // Mock GetProjects to return our mock data
133
+ jest.spyOn(managementDataProvider, 'GetProjects').mockResolvedValueOnce(mockProjects);
134
+
135
+ // Act
136
+ const result = await managementDataProvider.GetProjectByName('Non-Existent Project');
137
+
138
+ // Assert
139
+ expect(managementDataProvider.GetProjects).toHaveBeenCalledTimes(1);
140
+ expect(result).toEqual({});
141
+ });
142
+
143
+ it('should return empty object and log error when GetProjects throws', async () => {
144
+ // Arrange
145
+ const expectedError = new Error('Projects API call failed');
146
+
147
+ // Mock GetProjects to throw an error
148
+ jest.spyOn(managementDataProvider, 'GetProjects').mockRejectedValueOnce(expectedError);
149
+
150
+ // Mock console.log to capture the error
151
+ const consoleLogSpy = jest.spyOn(console, 'log');
152
+
153
+ // Act
154
+ const result = await managementDataProvider.GetProjectByName('Any Project');
155
+
156
+ // Assert
157
+ expect(managementDataProvider.GetProjects).toHaveBeenCalledTimes(1);
158
+ expect(consoleLogSpy).toHaveBeenCalledWith(expectedError);
159
+ expect(result).toEqual({});
160
+ });
161
+ });
162
+
163
+ describe('GetProjectByID', () => {
164
+ it('should return a project when API call succeeds', async () => {
165
+ // Arrange
166
+ const projectId = 'project-123';
167
+ const mockResponse = { id: projectId, name: 'Project 123' };
168
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
169
+
170
+ // Act
171
+ const result = await managementDataProvider.GetProjectByID(projectId);
172
+
173
+ // Assert
174
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
175
+ `${mockOrgUrl}_apis/projects/${projectId}`,
176
+ mockToken
177
+ );
178
+ expect(result).toEqual(mockResponse);
179
+ });
180
+
181
+ it('should throw an error when the API call fails', async () => {
182
+ // Arrange
183
+ const projectId = 'project-123';
184
+ const expectedError = new Error('Project API call failed');
185
+ (TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
186
+
187
+ // Act & Assert
188
+ await expect(managementDataProvider.GetProjectByID(projectId))
189
+ .rejects.toThrow('Project API call failed');
190
+
191
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
192
+ `${mockOrgUrl}_apis/projects/${projectId}`,
193
+ mockToken
194
+ );
195
+ });
196
+ });
197
+
198
+ describe('GetUserProfile', () => {
199
+ it('should return user profile when API call succeeds', async () => {
200
+ // Arrange
201
+ const mockResponse = {
202
+ id: 'user-123',
203
+ displayName: 'Test User',
204
+ emailAddress: 'test@example.com'
205
+ };
206
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
207
+
208
+ // Act
209
+ const result = await managementDataProvider.GetUserProfile();
210
+
211
+ // Assert
212
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
213
+ `${mockOrgUrl}_api/_common/GetUserProfile?__v=5`,
214
+ mockToken
215
+ );
216
+ expect(result).toEqual(mockResponse);
217
+ });
218
+
219
+ it('should throw an error when the API call fails', async () => {
220
+ // Arrange
221
+ const expectedError = new Error('User profile API call failed');
222
+ (TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
10
223
 
11
- describe("Common functions module - tests", () => {
12
- test("should return all collecttion projects", async () => {
13
- let managmentDataProvider = await dgDataProviderAzureDevOps.getMangementDataProvider();
14
- let json = await managmentDataProvider.GetProjects();
15
- expect(json.count).toBeGreaterThanOrEqual(1);
224
+ // Act & Assert
225
+ await expect(managementDataProvider.GetUserProfile())
226
+ .rejects.toThrow('User profile API call failed');
227
+
228
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
229
+ `${mockOrgUrl}_api/_common/GetUserProfile?__v=5`,
230
+ mockToken
231
+ );
232
+ });
16
233
  });
17
- test("should return project by name", async () => {
18
- let managmentDataProvider = await dgDataProviderAzureDevOps.getMangementDataProvider();
19
- let json = await managmentDataProvider.GetProjectByName("tests");
20
- expect(json.name).toBe("tests");
234
+
235
+ it('should initialize with the provided organization URL and token', () => {
236
+ // Arrange
237
+ const customOrgUrl = 'https://dev.azure.com/custom-org/';
238
+ const customToken = 'custom-token';
239
+
240
+ // Act
241
+ const provider = new MangementDataProvider(customOrgUrl, customToken);
242
+
243
+ // Assert
244
+ expect(provider.orgUrl).toBe(customOrgUrl);
245
+ expect(provider.token).toBe(customToken);
21
246
  });
22
- test("should return project by id", async () => {
23
- let managmentDataProvider = await dgDataProviderAzureDevOps.getMangementDataProvider();
24
- let json = await managmentDataProvider.GetProjectByID(
25
- "45a48633-890c-42bb-ace3-148d17806857"
26
- );
27
- expect(json.name).toBe("tests");
247
+ });
248
+ describe('MangementDataProvider - Additional Tests', () => {
249
+ let managementDataProvider: MangementDataProvider;
250
+ const mockOrgUrl = 'https://dev.azure.com/organization/';
251
+ const mockToken = 'mock-token';
252
+
253
+ beforeEach(() => {
254
+ jest.clearAllMocks();
255
+ managementDataProvider = new MangementDataProvider(mockOrgUrl, mockToken);
28
256
  });
29
- test("should return all collecttion link types", async () => {
30
- let managmentDataProvider = await dgDataProviderAzureDevOps.getMangementDataProvider();
31
- let json = await managmentDataProvider.GetCllectionLinkTypes();
32
- expect(json.count).toBeGreaterThan(1);
257
+
258
+ describe('GetProjectByName - Edge Cases', () => {
259
+ it('should return empty object when projects list is empty', async () => {
260
+ // Arrange
261
+ const mockEmptyProjects = {
262
+ count: 0,
263
+ value: []
264
+ };
265
+ jest.spyOn(managementDataProvider, 'GetProjects').mockResolvedValueOnce(mockEmptyProjects);
266
+
267
+ // Act
268
+ const result = await managementDataProvider.GetProjectByName('Any Project');
269
+
270
+ // Assert
271
+ expect(managementDataProvider.GetProjects).toHaveBeenCalledTimes(1);
272
+ expect(result).toEqual({});
273
+ });
274
+
275
+ it('should handle projects response with missing value property', async () => {
276
+ // Arrange
277
+ const mockInvalidProjects = {
278
+ count: 0
279
+ // no value property
280
+ };
281
+ jest.spyOn(managementDataProvider, 'GetProjects').mockResolvedValueOnce(mockInvalidProjects);
282
+
283
+ // Mock console.log to capture the error
284
+ const consoleLogSpy = jest.spyOn(console, 'log');
285
+
286
+ // Act
287
+ const result = await managementDataProvider.GetProjectByName('Any Project');
288
+
289
+ // Assert
290
+ expect(result).toEqual({});
291
+ expect(consoleLogSpy).toHaveBeenCalled();
292
+ });
293
+
294
+ it('should be case sensitive when matching project names', async () => {
295
+ // Arrange
296
+ const mockProjects = {
297
+ count: 1,
298
+ value: [
299
+ { id: 'project-1', name: 'Project One' }
300
+ ]
301
+ };
302
+ jest.spyOn(managementDataProvider, 'GetProjects').mockResolvedValueOnce(mockProjects);
303
+
304
+ // Act
305
+ const result = await managementDataProvider.GetProjectByName('project one'); // lowercase vs Project One
306
+
307
+ // Assert
308
+ expect(result).toEqual({});
309
+ });
310
+ });
311
+
312
+ describe('GetProjectByID - Edge Cases', () => {
313
+ it('should handle project IDs with special characters', async () => {
314
+ // Arrange
315
+ const projectId = 'project/with-special_chars%123';
316
+ const mockResponse = { id: projectId, name: 'Special Project' };
317
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
318
+
319
+ // Act
320
+ const result = await managementDataProvider.GetProjectByID(projectId);
321
+
322
+ // Assert
323
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
324
+ `${mockOrgUrl}_apis/projects/${projectId}`,
325
+ mockToken
326
+ );
327
+ expect(result).toEqual(mockResponse);
328
+ });
329
+ });
330
+
331
+ describe('Url Construction', () => {
332
+ it('should handle orgUrl with trailing slash properly', async () => {
333
+ // Arrange
334
+ const orgUrlWithTrailingSlash = 'https://dev.azure.com/organization/';
335
+ const provider = new MangementDataProvider(orgUrlWithTrailingSlash, mockToken);
336
+ const mockResponse = { value: [] };
337
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
338
+
339
+ // Act
340
+ await provider.GetCllectionLinkTypes();
341
+
342
+ // Assert
343
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
344
+ `${orgUrlWithTrailingSlash}_apis/wit/workitemrelationtypes`,
345
+ mockToken,
346
+ 'get',
347
+ null,
348
+ null
349
+ );
350
+ });
351
+
352
+ it('should handle orgUrl without trailing slash properly', async () => {
353
+ // Arrange
354
+ const orgUrlWithoutTrailingSlash = 'https://dev.azure.com/organization';
355
+ const provider = new MangementDataProvider(orgUrlWithoutTrailingSlash, mockToken);
356
+ const mockResponse = { value: [] };
357
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
358
+
359
+ // Act
360
+ await provider.GetCllectionLinkTypes();
361
+
362
+ // Assert
363
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
364
+ `${orgUrlWithoutTrailingSlash}_apis/wit/workitemrelationtypes`,
365
+ mockToken,
366
+ 'get',
367
+ null,
368
+ null
369
+ );
370
+ });
371
+ });
372
+
373
+ describe('GetUserProfile - Edge Cases', () => {
374
+ it('should handle unusual profile data structure', async () => {
375
+ // Arrange
376
+ const unusualProfileData = {
377
+ // Missing typical fields like displayName
378
+ id: 'user-123',
379
+ // Contains unexpected fields
380
+ unusualField: 'unusual value',
381
+ nestedData: {
382
+ someProperty: 'some value'
383
+ }
384
+ };
385
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(unusualProfileData);
386
+
387
+ // Act
388
+ const result = await managementDataProvider.GetUserProfile();
389
+
390
+ // Assert
391
+ expect(result).toEqual(unusualProfileData);
392
+ });
33
393
  });
34
- }); //describe
394
+ });