@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.
Files changed (92) hide show
  1. package/.github/workflows/ci.yml +26 -9
  2. package/.github/workflows/release.yml +9 -10
  3. package/README.md +50 -24
  4. package/bin/helpers/tfs.d.ts +3 -0
  5. package/bin/helpers/tfs.js +44 -7
  6. package/bin/helpers/tfs.js.map +1 -1
  7. package/bin/modules/GitDataProvider.d.ts +10 -0
  8. package/bin/modules/GitDataProvider.js +10 -0
  9. package/bin/modules/GitDataProvider.js.map +1 -1
  10. package/bin/modules/TestDataProvider.js +0 -1
  11. package/bin/modules/TestDataProvider.js.map +1 -1
  12. package/bin/modules/TicketsDataProvider.d.ts +63 -24
  13. package/bin/modules/TicketsDataProvider.js +216 -114
  14. package/bin/modules/TicketsDataProvider.js.map +1 -1
  15. package/bin/tests/helpers/helper.test.js +279 -0
  16. package/bin/tests/helpers/helper.test.js.map +1 -0
  17. package/bin/{helpers/test → tests/helpers}/tfs.test.js +312 -49
  18. package/bin/tests/helpers/tfs.test.js.map +1 -0
  19. package/bin/tests/index.test.js +25 -0
  20. package/bin/tests/index.test.js.map +1 -0
  21. package/bin/tests/models/tfs-data.test.js +160 -0
  22. package/bin/tests/models/tfs-data.test.js.map +1 -0
  23. package/bin/{modules/test → tests/modules}/JfrogDataProvider.test.js +9 -9
  24. package/bin/tests/modules/JfrogDataProvider.test.js.map +1 -0
  25. package/bin/tests/modules/ResultDataProvider.test.js +1942 -0
  26. package/bin/tests/modules/ResultDataProvider.test.js.map +1 -0
  27. package/bin/tests/modules/gitDataProvider.test.js +1888 -0
  28. package/bin/tests/modules/gitDataProvider.test.js.map +1 -0
  29. package/bin/{modules/test → tests/modules}/managmentDataProvider.test.js +13 -1
  30. package/bin/tests/modules/managmentDataProvider.test.js.map +1 -0
  31. package/bin/tests/modules/pipelineDataProvider.test.d.ts +1 -0
  32. package/bin/tests/modules/pipelineDataProvider.test.js +783 -0
  33. package/bin/tests/modules/pipelineDataProvider.test.js.map +1 -0
  34. package/bin/tests/modules/testDataProvider.test.d.ts +1 -0
  35. package/bin/tests/modules/testDataProvider.test.js +717 -0
  36. package/bin/tests/modules/testDataProvider.test.js.map +1 -0
  37. package/bin/tests/modules/ticketsDataProvider.test.d.ts +1 -0
  38. package/bin/tests/modules/ticketsDataProvider.test.js +1681 -0
  39. package/bin/tests/modules/ticketsDataProvider.test.js.map +1 -0
  40. package/bin/tests/utils/DataProviderUtils.test.d.ts +1 -0
  41. package/bin/tests/utils/DataProviderUtils.test.js +61 -0
  42. package/bin/tests/utils/DataProviderUtils.test.js.map +1 -0
  43. package/bin/tests/utils/testStepParserHelper.test.d.ts +1 -0
  44. package/bin/tests/utils/testStepParserHelper.test.js +359 -0
  45. package/bin/tests/utils/testStepParserHelper.test.js.map +1 -0
  46. package/package.json +9 -1
  47. package/src/helpers/tfs.ts +51 -7
  48. package/src/modules/GitDataProvider.ts +10 -0
  49. package/src/modules/TestDataProvider.ts +0 -1
  50. package/src/modules/TicketsDataProvider.ts +298 -141
  51. package/src/tests/helpers/helper.test.ts +337 -0
  52. package/src/tests/helpers/tfs.test.ts +1092 -0
  53. package/src/tests/index.test.ts +28 -0
  54. package/src/tests/models/tfs-data.test.ts +203 -0
  55. package/src/tests/modules/JfrogDataProvider.test.ts +167 -0
  56. package/src/tests/modules/ResultDataProvider.test.ts +2571 -0
  57. package/src/tests/modules/gitDataProvider.test.ts +2628 -0
  58. package/src/{modules/test → tests/modules}/managmentDataProvider.test.ts +33 -1
  59. package/src/tests/modules/pipelineDataProvider.test.ts +1038 -0
  60. package/src/tests/modules/testDataProvider.test.ts +1046 -0
  61. package/src/tests/modules/ticketsDataProvider.test.ts +2204 -0
  62. package/src/tests/utils/DataProviderUtils.test.ts +76 -0
  63. package/src/tests/utils/testStepParserHelper.test.ts +437 -0
  64. package/tsconfig.json +1 -0
  65. package/bin/helpers/test/tfs.test.js.map +0 -1
  66. package/bin/modules/test/JfrogDataProvider.test.js.map +0 -1
  67. package/bin/modules/test/ResultDataProvider.test.js +0 -444
  68. package/bin/modules/test/ResultDataProvider.test.js.map +0 -1
  69. package/bin/modules/test/gitDataProvider.test.js +0 -428
  70. package/bin/modules/test/gitDataProvider.test.js.map +0 -1
  71. package/bin/modules/test/managmentDataProvider.test.js.map +0 -1
  72. package/bin/modules/test/pipelineDataProvider.test.js +0 -237
  73. package/bin/modules/test/pipelineDataProvider.test.js.map +0 -1
  74. package/bin/modules/test/testDataProvider.test.js +0 -234
  75. package/bin/modules/test/testDataProvider.test.js.map +0 -1
  76. package/bin/modules/test/ticketsDataProvider.test.js +0 -348
  77. package/bin/modules/test/ticketsDataProvider.test.js.map +0 -1
  78. package/src/helpers/test/tfs.test.ts +0 -748
  79. package/src/modules/test/JfrogDataProvider.test.ts +0 -171
  80. package/src/modules/test/ResultDataProvider.test.ts +0 -542
  81. package/src/modules/test/gitDataProvider.test.ts +0 -645
  82. package/src/modules/test/pipelineDataProvider.test.ts +0 -292
  83. package/src/modules/test/testDataProvider.test.ts +0 -318
  84. package/src/modules/test/ticketsDataProvider.test.ts +0 -462
  85. /package/bin/{helpers/test/tfs.test.d.ts → tests/helpers/helper.test.d.ts} +0 -0
  86. /package/bin/{modules/test/JfrogDataProvider.test.d.ts → tests/helpers/tfs.test.d.ts} +0 -0
  87. /package/bin/{modules/test/ResultDataProvider.test.d.ts → tests/index.test.d.ts} +0 -0
  88. /package/bin/{modules/test/gitDataProvider.test.d.ts → tests/models/tfs-data.test.d.ts} +0 -0
  89. /package/bin/{modules/test/managmentDataProvider.test.d.ts → tests/modules/JfrogDataProvider.test.d.ts} +0 -0
  90. /package/bin/{modules/test/pipelineDataProvider.test.d.ts → tests/modules/ResultDataProvider.test.d.ts} +0 -0
  91. /package/bin/{modules/test/testDataProvider.test.d.ts → tests/modules/gitDataProvider.test.d.ts} +0 -0
  92. /package/bin/{modules/test/ticketsDataProvider.test.d.ts → tests/modules/managmentDataProvider.test.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.test.js","sourceRoot":"","sources":["../../../src/tests/helpers/helper.test.ts"],"names":[],"mappings":"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"}
@@ -5,11 +5,11 @@ const axios_1 = require("axios");
5
5
  jest.mock('axios');
6
6
  // Set up the mock axios instance that axios.create will return
7
7
  const mockAxiosInstance = {
8
- request: jest.fn()
8
+ request: jest.fn(),
9
9
  };
10
10
  axios_1.default.create.mockReturnValue(mockAxiosInstance);
11
11
  // NOW import TFSServices (it will use our mock)
12
- const tfs_1 = require("../tfs");
12
+ const tfs_1 = require("../../helpers/tfs");
13
13
  const logger_1 = require("../../utils/logger");
14
14
  // Mock logger
15
15
  jest.mock('../../utils/logger');
@@ -40,7 +40,22 @@ describe('TFSServices', () => {
40
40
  expect(mockAxiosInstance.request).toHaveBeenCalledWith({
41
41
  url,
42
42
  headers: { 'Content-Type': 'application/zip' },
43
- auth: { username: '', password: pat }
43
+ auth: { username: '', password: pat },
44
+ });
45
+ });
46
+ it('should use bearer Authorization header when token is bearer-prefixed', async () => {
47
+ // Arrange
48
+ const url = 'https://example.com/file.zip';
49
+ const token = 'bearer:abc123';
50
+ const mockResponse = { data: Buffer.from('zip-file-content') };
51
+ mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
52
+ // Act
53
+ const result = await tfs_1.TFSServices.downloadZipFile(url, token);
54
+ // Assert
55
+ expect(result).toEqual(mockResponse);
56
+ expect(mockAxiosInstance.request).toHaveBeenCalledWith({
57
+ url,
58
+ headers: { 'Content-Type': 'application/zip', Authorization: 'Bearer abc123' },
44
59
  });
45
60
  });
46
61
  it('should log and throw error when download fails', async () => {
@@ -62,7 +77,7 @@ describe('TFSServices', () => {
62
77
  const pat = 'token123';
63
78
  const mockResponse = {
64
79
  data: Buffer.from('image-data'),
65
- headers: { 'content-type': 'image/png' }
80
+ headers: { 'content-type': 'image/png' },
66
81
  };
67
82
  // Configure mock response
68
83
  mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
@@ -74,7 +89,27 @@ describe('TFSServices', () => {
74
89
  url,
75
90
  method: 'get',
76
91
  auth: { username: '', password: pat },
77
- responseType: 'arraybuffer'
92
+ responseType: 'arraybuffer',
93
+ }));
94
+ });
95
+ it('should send bearer Authorization header when bearer token is provided', async () => {
96
+ // Arrange
97
+ const url = 'https://example.com/image.png';
98
+ const token = 'bearer:abc123';
99
+ const mockResponse = {
100
+ data: Buffer.from('image-data'),
101
+ headers: { 'content-type': 'image/png' },
102
+ };
103
+ mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
104
+ // Act
105
+ const result = await tfs_1.TFSServices.fetchAzureDevOpsImageAsBase64(url, token);
106
+ // Assert
107
+ expect(result).toEqual('data:image/png;base64,aW1hZ2UtZGF0YQ==');
108
+ expect(mockAxiosInstance.request).toHaveBeenCalledWith(expect.objectContaining({
109
+ url,
110
+ method: 'get',
111
+ responseType: 'arraybuffer',
112
+ headers: expect.objectContaining({ Authorization: 'Bearer abc123' }),
78
113
  }));
79
114
  });
80
115
  it('should handle errors and retry for retryable errors', async () => {
@@ -85,11 +120,9 @@ describe('TFSServices', () => {
85
120
  const rateLimitError = new Error('Rate limit exceeded');
86
121
  rateLimitError.response = { status: 429 };
87
122
  // Configure mock to fail once then succeed
88
- mockAxiosInstance.request
89
- .mockRejectedValueOnce(rateLimitError)
90
- .mockResolvedValueOnce({
123
+ mockAxiosInstance.request.mockRejectedValueOnce(rateLimitError).mockResolvedValueOnce({
91
124
  data: Buffer.from('image-data'),
92
- headers: { 'content-type': 'image/png' }
125
+ headers: { 'content-type': 'image/png' },
93
126
  });
94
127
  // Mock setTimeout to execute immediately
95
128
  jest.spyOn(global, 'setTimeout').mockImplementation((fn) => {
@@ -120,7 +153,23 @@ describe('TFSServices', () => {
120
153
  url: url.replace(/ /g, '%20'),
121
154
  method: 'get',
122
155
  auth: { username: '', password: pat },
123
- timeout: 10000 // Verify the actual timeout value is 10000ms
156
+ timeout: 10000, // Verify the actual timeout value is 10000ms
157
+ }));
158
+ });
159
+ it('should use bearer Authorization header when bearer token is provided', async () => {
160
+ // Arrange
161
+ const url = 'https://example.com/api/item';
162
+ const token = 'bearer:abc123';
163
+ const mockResponse = { data: { id: 123, name: 'Test Item' } };
164
+ mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
165
+ // Act
166
+ const result = await tfs_1.TFSServices.getItemContent(url, token);
167
+ // Assert
168
+ expect(result).toEqual(mockResponse.data);
169
+ expect(mockAxiosInstance.request).toHaveBeenCalledWith(expect.objectContaining({
170
+ url: url.replace(/ /g, '%20'),
171
+ method: 'get',
172
+ headers: expect.objectContaining({ Authorization: 'Bearer abc123' }),
124
173
  }));
125
174
  });
126
175
  it('should fail when request times out', async () => {
@@ -196,6 +245,41 @@ describe('TFSServices', () => {
196
245
  expect(mockAxiosInstance.request).toHaveBeenCalledWith(expect.objectContaining({ url: 'https://example.com/api/item%20with%20spaces' }));
197
246
  });
198
247
  });
248
+ describe('getItemContentWithHeaders', () => {
249
+ it('should return data and headers from response', async () => {
250
+ // Arrange
251
+ const url = 'https://example.com/api/item';
252
+ const pat = 'token123';
253
+ const mockResponse = {
254
+ data: { id: 123, name: 'Test Item' },
255
+ headers: { 'x-custom-header': 'value' },
256
+ };
257
+ // Configure mock response
258
+ mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
259
+ // Act
260
+ const result = await tfs_1.TFSServices.getItemContentWithHeaders(url, pat);
261
+ // Assert
262
+ expect(result).toEqual({
263
+ data: mockResponse.data,
264
+ headers: mockResponse.headers,
265
+ });
266
+ });
267
+ it('should handle spaces in URL', async () => {
268
+ // Arrange
269
+ const url = 'https://example.com/api/item with spaces';
270
+ const pat = 'token123';
271
+ const mockResponse = {
272
+ data: { id: 123 },
273
+ headers: {},
274
+ };
275
+ // Configure mock response
276
+ mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
277
+ // Act
278
+ await tfs_1.TFSServices.getItemContentWithHeaders(url, pat);
279
+ // Assert
280
+ expect(mockAxiosInstance.request).toHaveBeenCalledWith(expect.objectContaining({ url: 'https://example.com/api/item%20with%20spaces' }));
281
+ });
282
+ });
199
283
  describe('getJfrogRequest', () => {
200
284
  it('should make a successful GET request to JFrog', async () => {
201
285
  // Arrange
@@ -211,7 +295,7 @@ describe('TFSServices', () => {
211
295
  expect(mockAxiosInstance.request).toHaveBeenCalledWith({
212
296
  url,
213
297
  method: 'GET',
214
- headers
298
+ headers,
215
299
  });
216
300
  });
217
301
  it('should handle errors from JFrog API', async () => {
@@ -244,7 +328,30 @@ describe('TFSServices', () => {
244
328
  method: 'post',
245
329
  auth: { username: '', password: pat },
246
330
  data,
247
- headers: { headers: { 'Content-Type': 'application/json' } }
331
+ headers: { headers: { 'Content-Type': 'application/json' } },
332
+ });
333
+ });
334
+ it('should use bearer Authorization header when bearer token is provided', async () => {
335
+ // Arrange
336
+ const url = 'https://example.com/api/resource';
337
+ const token = 'bearer:abc123';
338
+ const data = { name: 'New Resource' };
339
+ const mockResponse = { data: { id: 123, name: 'New Resource' } };
340
+ mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
341
+ // Act
342
+ const result = await tfs_1.TFSServices.postRequest(url, token, 'post', data);
343
+ // Assert
344
+ expect(result).toEqual(mockResponse);
345
+ expect(mockAxiosInstance.request).toHaveBeenCalledWith({
346
+ url,
347
+ method: 'post',
348
+ data,
349
+ headers: {
350
+ headers: {
351
+ 'Content-Type': 'application/json',
352
+ Authorization: 'Bearer abc123',
353
+ },
354
+ },
248
355
  });
249
356
  });
250
357
  it('should work with custom headers and methods', async () => {
@@ -265,7 +372,7 @@ describe('TFSServices', () => {
265
372
  method: 'put',
266
373
  auth: { username: '', password: pat },
267
374
  data,
268
- headers: customHeaders
375
+ headers: customHeaders,
269
376
  });
270
377
  });
271
378
  it('should handle errors in POST requests', async () => {
@@ -355,18 +462,22 @@ describe('TFSServices', () => {
355
462
  const url = 'https://example.com/api/large-dataset';
356
463
  const pat = 'token123';
357
464
  // Create 5 large responses of different sizes
358
- const responses = Array(5).fill(0).map((_, i) => {
465
+ const responses = Array(5)
466
+ .fill(0)
467
+ .map((_, i) => {
359
468
  // Create increasingly large responses (500KB, 1MB, 1.5MB, 2MB, 2.5MB)
360
469
  const size = 25000 * (i + 1);
361
470
  return {
362
471
  data: {
363
- items: Array(size).fill(0).map((_, j) => ({
472
+ items: Array(size)
473
+ .fill(0)
474
+ .map((_, j) => ({
364
475
  id: j,
365
476
  name: `Item ${j}`,
366
477
  description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
367
- data: `value-${j}-${Math.random().toString(36).substring(2, 15)}`
368
- }))
369
- }
478
+ data: `value-${j}-${Math.random().toString(36).substring(2, 15)}`,
479
+ })),
480
+ },
370
481
  };
371
482
  });
372
483
  // Configure the mock to return the different responses in sequence
@@ -402,27 +513,23 @@ describe('TFSServices', () => {
402
513
  serverError.response = { status: 503 };
403
514
  // Response 1
404
515
  mockAxiosInstance.request.mockResolvedValueOnce({
405
- data: { id: 1, success: true }
516
+ data: { id: 1, success: true },
406
517
  });
407
518
  // Response 2 - fails with rate limit first, then succeeds
408
- mockAxiosInstance.request
409
- .mockRejectedValueOnce(rateLimitError)
410
- .mockResolvedValueOnce({
411
- data: { id: 2, success: true }
519
+ mockAxiosInstance.request.mockRejectedValueOnce(rateLimitError).mockResolvedValueOnce({
520
+ data: { id: 2, success: true },
412
521
  });
413
522
  // Response 3
414
523
  mockAxiosInstance.request.mockResolvedValueOnce({
415
- data: { id: 3, success: true }
524
+ data: { id: 3, success: true },
416
525
  });
417
526
  // Response 4 - fails with server error first, then succeeds
418
- mockAxiosInstance.request
419
- .mockRejectedValueOnce(serverError)
420
- .mockResolvedValueOnce({
421
- data: { id: 4, success: true }
527
+ mockAxiosInstance.request.mockRejectedValueOnce(serverError).mockResolvedValueOnce({
528
+ data: { id: 4, success: true },
422
529
  });
423
530
  // Response 5
424
531
  mockAxiosInstance.request.mockResolvedValueOnce({
425
- data: { id: 5, success: true }
532
+ data: { id: 5, success: true },
426
533
  });
427
534
  // Mock setTimeout to execute immediately for retry delay
428
535
  jest.spyOn(global, 'setTimeout').mockImplementation((fn) => {
@@ -437,7 +544,7 @@ describe('TFSServices', () => {
437
544
  }
438
545
  // Assert
439
546
  expect(results.length).toBe(5);
440
- expect(results.map(r => r.id)).toEqual([1, 2, 3, 4, 5]);
547
+ expect(results.map((r) => r.id)).toEqual([1, 2, 3, 4, 5]);
441
548
  // Check total number of requests (5 successful responses + 2 retries)
442
549
  expect(mockAxiosInstance.request).toHaveBeenCalledTimes(7);
443
550
  });
@@ -448,23 +555,27 @@ describe('TFSServices', () => {
448
555
  const url = 'https://example.com/api/resource';
449
556
  const pat = 'token123';
450
557
  // Create 5 increasingly large payloads
451
- const payloads = Array(5).fill(0).map((_, i) => {
558
+ const payloads = Array(5)
559
+ .fill(0)
560
+ .map((_, i) => {
452
561
  // Create payloads of increasing size (100KB, 200KB, 300KB, 400KB, 500KB)
453
562
  const size = 5000 * (i + 1);
454
563
  return {
455
564
  name: `Resource ${i + 1}`,
456
565
  description: `Large resource ${i + 1}`,
457
- items: Array(size).fill(0).map((_, j) => ({
566
+ items: Array(size)
567
+ .fill(0)
568
+ .map((_, j) => ({
458
569
  id: j,
459
570
  value: `item-${j}-${Math.random().toString(36).substring(2, 15)}`,
460
- timestamp: new Date().toISOString()
461
- }))
571
+ timestamp: new Date().toISOString(),
572
+ })),
462
573
  };
463
574
  });
464
575
  // Set up mock responses
465
576
  for (let i = 0; i < payloads.length; i++) {
466
577
  mockAxiosInstance.request.mockResolvedValueOnce({
467
- data: { id: i + 1, status: 'created', itemCount: payloads[i].items.length }
578
+ data: { id: i + 1, status: 'created', itemCount: payloads[i].items.length },
468
579
  });
469
580
  }
470
581
  // Act - Make multiple sequential POST requests
@@ -486,12 +597,14 @@ describe('TFSServices', () => {
486
597
  const url = 'https://example.com/api/resource';
487
598
  const pat = 'token123';
488
599
  // Create test data
489
- const payloads = Array(5).fill(0).map((_, i) => ({ name: `Resource ${i + 1}` }));
600
+ const payloads = Array(5)
601
+ .fill(0)
602
+ .map((_, i) => ({ name: `Resource ${i + 1}` }));
490
603
  // Validation error
491
604
  const validationError = new Error('Validation error');
492
605
  validationError.response = {
493
606
  status: 400,
494
- data: { message: 'Invalid data', details: 'Field X is required' }
607
+ data: { message: 'Invalid data', details: 'Field X is required' },
495
608
  };
496
609
  // Server error
497
610
  const serverError = new Error('Server error');
@@ -499,33 +612,31 @@ describe('TFSServices', () => {
499
612
  // Configure mock responses/errors for each request
500
613
  // 1. Success
501
614
  mockAxiosInstance.request.mockResolvedValueOnce({
502
- data: { id: 1, status: 'created' }
615
+ data: { id: 1, status: 'created' },
503
616
  });
504
617
  // 2. Validation error
505
618
  mockAxiosInstance.request.mockRejectedValueOnce(validationError);
506
619
  // 3. Success
507
620
  mockAxiosInstance.request.mockResolvedValueOnce({
508
- data: { id: 3, status: 'created' }
621
+ data: { id: 3, status: 'created' },
509
622
  });
510
623
  // 4. Server error
511
624
  mockAxiosInstance.request.mockRejectedValueOnce(serverError);
512
625
  // 5. Success
513
626
  mockAxiosInstance.request.mockResolvedValueOnce({
514
- data: { id: 5, status: 'created' }
627
+ data: { id: 5, status: 'created' },
515
628
  });
516
629
  // Act & Assert
517
630
  // Request 1 - should succeed
518
631
  const result1 = await tfs_1.TFSServices.postRequest(url, pat, 'post', payloads[0]);
519
632
  expect(result1.data.id).toBe(1);
520
633
  // Request 2 - should fail with validation error
521
- await expect(tfs_1.TFSServices.postRequest(url, pat, 'post', payloads[1]))
522
- .rejects.toThrow('Validation error');
634
+ await expect(tfs_1.TFSServices.postRequest(url, pat, 'post', payloads[1])).rejects.toThrow('Validation error');
523
635
  // Request 3 - should succeed despite previous failure
524
636
  const result3 = await tfs_1.TFSServices.postRequest(url, pat, 'post', payloads[2]);
525
637
  expect(result3.data.id).toBe(3);
526
638
  // Request 4 - should fail with server error
527
- await expect(tfs_1.TFSServices.postRequest(url, pat, 'post', payloads[3]))
528
- .rejects.toThrow('Server error');
639
+ await expect(tfs_1.TFSServices.postRequest(url, pat, 'post', payloads[3])).rejects.toThrow('Server error');
529
640
  // Request 5 - should succeed despite previous failure
530
641
  const result5 = await tfs_1.TFSServices.postRequest(url, pat, 'post', payloads[4]);
531
642
  expect(result5.data.id).toBe(5);
@@ -548,18 +659,18 @@ describe('TFSServices', () => {
548
659
  return {
549
660
  id: `node-${current}-${Math.random()}`,
550
661
  level: current,
551
- children
662
+ children,
552
663
  };
553
664
  };
554
665
  // Create a complex payload with depth 5 and breadth 5 (5^5 = 3,125 nodes)
555
666
  const complexPayload = {
556
667
  name: 'Complex Resource',
557
668
  type: 'hierarchical',
558
- rootNode: createNestedObject(5, 5)
669
+ rootNode: createNestedObject(5, 5),
559
670
  };
560
671
  // Configure mock response
561
672
  mockAxiosInstance.request.mockResolvedValueOnce({
562
- data: { id: 123, status: 'created', complexity: 'high' }
673
+ data: { id: 123, status: 'created', complexity: 'high' },
563
674
  });
564
675
  // Act
565
676
  const result = await tfs_1.TFSServices.postRequest(url, pat, 'post', complexPayload);
@@ -570,10 +681,162 @@ describe('TFSServices', () => {
570
681
  expect(mockAxiosInstance.request).toHaveBeenCalledWith(expect.objectContaining({
571
682
  url,
572
683
  method: 'post',
573
- data: complexPayload
684
+ data: complexPayload,
574
685
  }));
575
686
  });
576
687
  });
688
+ describe('fetchAzureDevOpsImageAsBase64 - non-image content', () => {
689
+ it('should throw error when content type is not an image', async () => {
690
+ // Arrange
691
+ const url = 'https://example.com/file.txt';
692
+ const pat = 'token123';
693
+ const mockResponse = {
694
+ data: Buffer.from('text content'),
695
+ headers: { 'content-type': 'text/plain' },
696
+ };
697
+ // Configure mock response
698
+ mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
699
+ // Act & Assert
700
+ await expect(tfs_1.TFSServices.fetchAzureDevOpsImageAsBase64(url, pat)).rejects.toThrow("Expected image content but received 'text/plain'");
701
+ });
702
+ it('should handle content-type with charset', async () => {
703
+ // Arrange
704
+ const url = 'https://example.com/image.png';
705
+ const pat = 'token123';
706
+ const mockResponse = {
707
+ data: Buffer.from('image-data'),
708
+ headers: { 'content-type': 'image/png; charset=utf-8' },
709
+ };
710
+ // Configure mock response
711
+ mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
712
+ // Act
713
+ const result = await tfs_1.TFSServices.fetchAzureDevOpsImageAsBase64(url, pat);
714
+ // Assert
715
+ expect(result).toEqual('data:image/png;base64,aW1hZ2UtZGF0YQ==');
716
+ });
717
+ it('should use default content type when header is missing', async () => {
718
+ // Arrange
719
+ const url = 'https://example.com/image.png';
720
+ const pat = 'token123';
721
+ const mockResponse = {
722
+ data: Buffer.from('image-data'),
723
+ headers: {},
724
+ };
725
+ // Configure mock response
726
+ mockAxiosInstance.request.mockResolvedValueOnce(mockResponse);
727
+ // Act & Assert - should throw because application/octet-stream is not an image
728
+ await expect(tfs_1.TFSServices.fetchAzureDevOpsImageAsBase64(url, pat)).rejects.toThrow("Expected image content but received 'application/octet-stream'");
729
+ });
730
+ });
731
+ describe('getItemContent - file not found handling', () => {
732
+ it('should throw specific error when file is not found', async () => {
733
+ // Arrange
734
+ const url = 'https://example.com/api/missing-file';
735
+ const pat = 'token123';
736
+ // Create a "not found" error
737
+ const notFoundError = new Error('The file could not be found');
738
+ notFoundError.response = {
739
+ status: 404,
740
+ data: { message: 'The file could not be found' },
741
+ };
742
+ // Configure mock to throw not found error
743
+ mockAxiosInstance.request.mockRejectedValueOnce(notFoundError);
744
+ // Act & Assert
745
+ await expect(tfs_1.TFSServices.getItemContent(url, pat)).rejects.toThrow('File not found or insufficient permissions');
746
+ });
747
+ });
748
+ describe('logDetailedError - various error formats', () => {
749
+ it('should handle error with string response data', async () => {
750
+ // Arrange
751
+ const url = 'https://example.com/api/error';
752
+ const pat = 'token123';
753
+ const errorWithStringData = new Error('Server error');
754
+ errorWithStringData.response = {
755
+ status: 500,
756
+ data: 'Internal Server Error - detailed message here that is quite long',
757
+ };
758
+ // Configure mock to fail
759
+ mockAxiosInstance.request.mockRejectedValue(errorWithStringData);
760
+ // Mock setTimeout to execute immediately
761
+ jest.spyOn(global, 'setTimeout').mockImplementation((fn) => {
762
+ fn();
763
+ return {};
764
+ });
765
+ // Act & Assert
766
+ await expect(tfs_1.TFSServices.getItemContent(url, pat)).rejects.toThrow();
767
+ expect(logger_1.default.error).toHaveBeenCalled();
768
+ });
769
+ it('should handle error with object response data containing message', async () => {
770
+ // Arrange
771
+ const url = 'https://example.com/api/error';
772
+ const pat = 'token123';
773
+ const errorWithObjectData = new Error('Server error');
774
+ errorWithObjectData.response = {
775
+ status: 500,
776
+ data: { message: 'Detailed error message' },
777
+ };
778
+ // Configure mock to fail
779
+ mockAxiosInstance.request.mockRejectedValue(errorWithObjectData);
780
+ // Mock setTimeout to execute immediately
781
+ jest.spyOn(global, 'setTimeout').mockImplementation((fn) => {
782
+ fn();
783
+ return {};
784
+ });
785
+ // Act & Assert
786
+ await expect(tfs_1.TFSServices.getItemContent(url, pat)).rejects.toThrow();
787
+ expect(logger_1.default.error).toHaveBeenCalled();
788
+ });
789
+ it('should handle error without response object', async () => {
790
+ // Arrange
791
+ const url = 'https://example.com/api/error';
792
+ const pat = 'token123';
793
+ const errorWithoutResponse = new Error('Network error');
794
+ // Configure mock to fail
795
+ mockAxiosInstance.request.mockRejectedValue(errorWithoutResponse);
796
+ // Mock setTimeout to execute immediately
797
+ jest.spyOn(global, 'setTimeout').mockImplementation((fn) => {
798
+ fn();
799
+ return {};
800
+ });
801
+ // Act & Assert
802
+ await expect(tfs_1.TFSServices.getItemContent(url, pat)).rejects.toThrow();
803
+ expect(logger_1.default.error).toHaveBeenCalled();
804
+ });
805
+ });
806
+ describe('getErrorMessage - various error formats', () => {
807
+ it('should extract message from response.data.message', async () => {
808
+ // Arrange
809
+ const url = 'https://example.com/api/error';
810
+ const pat = 'token123';
811
+ const error = new Error('Error');
812
+ error.response = {
813
+ status: 400,
814
+ data: { message: 'The file could not be found' },
815
+ };
816
+ mockAxiosInstance.request.mockRejectedValueOnce(error);
817
+ // Act & Assert
818
+ await expect(tfs_1.TFSServices.getItemContent(url, pat)).rejects.toThrow();
819
+ });
820
+ it('should handle error with only response status', async () => {
821
+ // Arrange
822
+ const url = 'https://example.com/api/error';
823
+ const pat = 'token123';
824
+ const error = new Error('Error');
825
+ error.response = { status: 403 };
826
+ mockAxiosInstance.request.mockRejectedValueOnce(error);
827
+ // Act & Assert
828
+ await expect(tfs_1.TFSServices.getItemContent(url, pat)).rejects.toThrow();
829
+ });
830
+ it('should handle error with no message property', async () => {
831
+ // Arrange
832
+ const url = 'https://example.com/api/error';
833
+ const pat = 'token123';
834
+ const error = {};
835
+ mockAxiosInstance.request.mockRejectedValueOnce(error);
836
+ // Act & Assert
837
+ await expect(tfs_1.TFSServices.getItemContent(url, pat)).rejects.toThrow();
838
+ });
839
+ });
577
840
  describe('High volume sequential operations', () => {
578
841
  it('should handle a high volume of sequential API calls', async () => {
579
842
  // Arrange
@@ -583,7 +846,7 @@ describe('TFSServices', () => {
583
846
  // Configure mock responses for all requests
584
847
  for (let i = 0; i < requestCount; i++) {
585
848
  mockAxiosInstance.request.mockResolvedValueOnce({
586
- data: { id: i, success: true, timestamp: new Date().toISOString() }
849
+ data: { id: i, success: true, timestamp: new Date().toISOString() },
587
850
  });
588
851
  }
589
852
  // Act