@elisra-devops/docgen-data-provider 1.63.12 → 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.
Files changed (94) hide show
  1. package/.github/workflows/ci.yml +26 -9
  2. package/.github/workflows/release.yml +9 -10
  3. package/bin/helpers/tfs.d.ts +3 -0
  4. package/bin/helpers/tfs.js +44 -7
  5. package/bin/helpers/tfs.js.map +1 -1
  6. package/bin/modules/GitDataProvider.d.ts +10 -0
  7. package/bin/modules/GitDataProvider.js +10 -0
  8. package/bin/modules/GitDataProvider.js.map +1 -1
  9. package/bin/modules/MangementDataProvider.js +7 -1
  10. package/bin/modules/MangementDataProvider.js.map +1 -1
  11. package/bin/modules/TestDataProvider.js +0 -1
  12. package/bin/modules/TestDataProvider.js.map +1 -1
  13. package/bin/modules/TicketsDataProvider.d.ts +63 -27
  14. package/bin/modules/TicketsDataProvider.js +226 -122
  15. package/bin/modules/TicketsDataProvider.js.map +1 -1
  16. package/bin/tests/helpers/helper.test.js +279 -0
  17. package/bin/tests/helpers/helper.test.js.map +1 -0
  18. package/bin/{helpers/test → tests/helpers}/tfs.test.js +312 -49
  19. package/bin/tests/helpers/tfs.test.js.map +1 -0
  20. package/bin/tests/index.test.js +25 -0
  21. package/bin/tests/index.test.js.map +1 -0
  22. package/bin/tests/models/tfs-data.test.js +160 -0
  23. package/bin/tests/models/tfs-data.test.js.map +1 -0
  24. package/bin/{modules/test → tests/modules}/JfrogDataProvider.test.js +9 -9
  25. package/bin/tests/modules/JfrogDataProvider.test.js.map +1 -0
  26. package/bin/tests/modules/ResultDataProvider.test.js +1942 -0
  27. package/bin/tests/modules/ResultDataProvider.test.js.map +1 -0
  28. package/bin/tests/modules/gitDataProvider.test.js +1888 -0
  29. package/bin/tests/modules/gitDataProvider.test.js.map +1 -0
  30. package/bin/{modules/test → tests/modules}/managmentDataProvider.test.js +39 -31
  31. package/bin/tests/modules/managmentDataProvider.test.js.map +1 -0
  32. package/bin/tests/modules/pipelineDataProvider.test.d.ts +1 -0
  33. package/bin/tests/modules/pipelineDataProvider.test.js +783 -0
  34. package/bin/tests/modules/pipelineDataProvider.test.js.map +1 -0
  35. package/bin/tests/modules/testDataProvider.test.d.ts +1 -0
  36. package/bin/tests/modules/testDataProvider.test.js +717 -0
  37. package/bin/tests/modules/testDataProvider.test.js.map +1 -0
  38. package/bin/tests/modules/ticketsDataProvider.test.d.ts +1 -0
  39. package/bin/tests/modules/ticketsDataProvider.test.js +1681 -0
  40. package/bin/tests/modules/ticketsDataProvider.test.js.map +1 -0
  41. package/bin/tests/utils/DataProviderUtils.test.d.ts +1 -0
  42. package/bin/tests/utils/DataProviderUtils.test.js +61 -0
  43. package/bin/tests/utils/DataProviderUtils.test.js.map +1 -0
  44. package/bin/tests/utils/testStepParserHelper.test.d.ts +1 -0
  45. package/bin/tests/utils/testStepParserHelper.test.js +359 -0
  46. package/bin/tests/utils/testStepParserHelper.test.js.map +1 -0
  47. package/package.json +10 -1
  48. package/src/helpers/tfs.ts +51 -7
  49. package/src/modules/GitDataProvider.ts +10 -0
  50. package/src/modules/MangementDataProvider.ts +6 -1
  51. package/src/modules/TestDataProvider.ts +0 -1
  52. package/src/modules/TicketsDataProvider.ts +311 -151
  53. package/src/tests/helpers/helper.test.ts +337 -0
  54. package/src/tests/helpers/tfs.test.ts +1092 -0
  55. package/src/tests/index.test.ts +28 -0
  56. package/src/tests/models/tfs-data.test.ts +203 -0
  57. package/src/tests/modules/JfrogDataProvider.test.ts +167 -0
  58. package/src/tests/modules/ResultDataProvider.test.ts +2571 -0
  59. package/src/tests/modules/gitDataProvider.test.ts +2628 -0
  60. package/src/{modules/test → tests/modules}/managmentDataProvider.test.ts +63 -32
  61. package/src/tests/modules/pipelineDataProvider.test.ts +1038 -0
  62. package/src/tests/modules/testDataProvider.test.ts +1046 -0
  63. package/src/tests/modules/ticketsDataProvider.test.ts +2204 -0
  64. package/src/tests/utils/DataProviderUtils.test.ts +76 -0
  65. package/src/tests/utils/testStepParserHelper.test.ts +437 -0
  66. package/tsconfig.json +1 -0
  67. package/bin/helpers/test/tfs.test.js.map +0 -1
  68. package/bin/modules/test/JfrogDataProvider.test.js.map +0 -1
  69. package/bin/modules/test/ResultDataProvider.test.js +0 -444
  70. package/bin/modules/test/ResultDataProvider.test.js.map +0 -1
  71. package/bin/modules/test/gitDataProvider.test.js +0 -433
  72. package/bin/modules/test/gitDataProvider.test.js.map +0 -1
  73. package/bin/modules/test/managmentDataProvider.test.js.map +0 -1
  74. package/bin/modules/test/pipelineDataProvider.test.js +0 -237
  75. package/bin/modules/test/pipelineDataProvider.test.js.map +0 -1
  76. package/bin/modules/test/testDataProvider.test.js +0 -234
  77. package/bin/modules/test/testDataProvider.test.js.map +0 -1
  78. package/bin/modules/test/ticketsDataProvider.test.js +0 -322
  79. package/bin/modules/test/ticketsDataProvider.test.js.map +0 -1
  80. package/src/helpers/test/tfs.test.ts +0 -748
  81. package/src/modules/test/JfrogDataProvider.test.ts +0 -171
  82. package/src/modules/test/ResultDataProvider.test.ts +0 -542
  83. package/src/modules/test/gitDataProvider.test.ts +0 -691
  84. package/src/modules/test/pipelineDataProvider.test.ts +0 -292
  85. package/src/modules/test/testDataProvider.test.ts +0 -318
  86. package/src/modules/test/ticketsDataProvider.test.ts +0 -434
  87. /package/bin/{helpers/test/tfs.test.d.ts → tests/helpers/helper.test.d.ts} +0 -0
  88. /package/bin/{modules/test/JfrogDataProvider.test.d.ts → tests/helpers/tfs.test.d.ts} +0 -0
  89. /package/bin/{modules/test/ResultDataProvider.test.d.ts → tests/index.test.d.ts} +0 -0
  90. /package/bin/{modules/test/gitDataProvider.test.d.ts → tests/models/tfs-data.test.d.ts} +0 -0
  91. /package/bin/{modules/test/managmentDataProvider.test.d.ts → tests/modules/JfrogDataProvider.test.d.ts} +0 -0
  92. /package/bin/{modules/test/pipelineDataProvider.test.d.ts → tests/modules/ResultDataProvider.test.d.ts} +0 -0
  93. /package/bin/{modules/test/testDataProvider.test.d.ts → tests/modules/gitDataProvider.test.d.ts} +0 -0
  94. /package/bin/{modules/test/ticketsDataProvider.test.d.ts → tests/modules/managmentDataProvider.test.d.ts} +0 -0
@@ -1,434 +0,0 @@
1
- import { TFSServices } from '../../helpers/tfs';
2
- import TicketsDataProvider from '../TicketsDataProvider';
3
- import logger from '../../utils/logger';
4
- import { Helper } from '../../helpers/helper';
5
- import { QueryType } from '../../models/tfs-data';
6
-
7
- jest.mock('../../helpers/tfs');
8
- jest.mock('../../utils/logger');
9
- jest.mock('../../helpers/helper');
10
-
11
- describe('TicketsDataProvider', () => {
12
- let ticketsDataProvider: TicketsDataProvider;
13
- const mockOrgUrl = 'https://dev.azure.com/organization/';
14
- const mockToken = 'mock-token';
15
- const mockProject = 'test-project';
16
-
17
- beforeEach(() => {
18
- jest.clearAllMocks();
19
- ticketsDataProvider = new TicketsDataProvider(mockOrgUrl, mockToken);
20
- });
21
-
22
- describe('FetchImageAsBase64', () => {
23
- it('should fetch image as base64', async () => {
24
- // Arrange
25
- const mockUrl = 'https://example.com/image.jpg';
26
- const mockBase64 = 'base64-encoded-image';
27
- (TFSServices.fetchAzureDevOpsImageAsBase64 as jest.Mock).mockResolvedValueOnce(mockBase64);
28
-
29
- // Act
30
- const result = await ticketsDataProvider.FetchImageAsBase64(mockUrl);
31
-
32
- // Assert
33
- expect(TFSServices.fetchAzureDevOpsImageAsBase64).toHaveBeenCalledWith(
34
- mockUrl, mockToken, 'get', null
35
- );
36
- expect(result).toBe(mockBase64);
37
- });
38
- });
39
-
40
- describe('GetWorkItem', () => {
41
- it('should fetch work item with correct URL', async () => {
42
- // Arrange
43
- const mockId = '123';
44
- const mockWorkItem = { id: 123, fields: { 'System.Title': 'Test Work Item' } };
45
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockWorkItem);
46
-
47
- // Act
48
- const result = await ticketsDataProvider.GetWorkItem(mockProject, mockId);
49
-
50
- // Assert
51
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(
52
- `${mockOrgUrl}${mockProject}/_apis/wit/workitems/${mockId}?$expand=All`,
53
- mockToken
54
- );
55
- expect(result).toEqual(mockWorkItem);
56
- });
57
- });
58
-
59
- describe('GetLinksByIds', () => {
60
- it('should retrieve links by ids', async () => {
61
- // Arrange
62
- const mockIds = [1, 2];
63
- const mockWorkItems = [
64
- { id: 1, fields: { 'System.Title': 'Item 1' } },
65
- { id: 2, fields: { 'System.Title': 'Item 2' } }
66
- ];
67
- const mockLinksMap = new Map();
68
- mockLinksMap.set('1', { id: '1', rels: ['3'] });
69
- mockLinksMap.set('2', { id: '2', rels: [] });
70
-
71
- const mockRelatedItems = [{ id: 3, fields: { 'System.Title': 'Related Item' } }];
72
- const mockTraceItem = { id: '1', title: 'Item 1', url: 'url', customerId: 'customer', links: [] };
73
-
74
- jest.spyOn(ticketsDataProvider, 'PopulateWorkItemsByIds').mockResolvedValueOnce(mockWorkItems);
75
- jest.spyOn(ticketsDataProvider, 'GetRelationsIds').mockResolvedValueOnce(mockLinksMap);
76
- jest.spyOn(ticketsDataProvider, 'GetParentLink')
77
- .mockResolvedValueOnce(mockTraceItem)
78
- .mockResolvedValueOnce({ id: '2', title: 'Item 2', url: 'url', customerId: 'customer', links: [] });
79
- jest.spyOn(ticketsDataProvider, 'PopulateWorkItemsByIds').mockResolvedValueOnce(mockRelatedItems);
80
- jest.spyOn(ticketsDataProvider, 'GetLinks').mockResolvedValueOnce([]);
81
-
82
- // Act
83
- const result = await ticketsDataProvider.GetLinksByIds(mockProject, mockIds);
84
-
85
- // Assert
86
- expect(result.length).toBe(2);
87
- expect(ticketsDataProvider.PopulateWorkItemsByIds).toHaveBeenCalledWith(mockIds, mockProject);
88
- expect(ticketsDataProvider.GetRelationsIds).toHaveBeenCalledWith(mockWorkItems);
89
- });
90
- });
91
-
92
- describe('GetSharedQueries', () => {
93
- it('should fetch STD shared queries with correct URL', async () => {
94
- // Arrange
95
- const mockPath = '';
96
- const mockDocType = 'STD';
97
- const mockQueries = { name: 'Query 1' };
98
- const mockResponse = { reqTestTree: {}, testReqTree: {} };
99
-
100
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockQueries);
101
- jest.spyOn(ticketsDataProvider as any, 'fetchLinkedQueries').mockResolvedValueOnce(mockResponse);
102
-
103
- // Act
104
- const result = await ticketsDataProvider.GetSharedQueries(mockProject, mockPath, mockDocType);
105
-
106
- // Assert
107
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(
108
- `${mockOrgUrl}${mockProject}/_apis/wit/queries/Shared%20Queries?$depth=2&$expand=all`,
109
- mockToken
110
- );
111
- expect(result).toEqual(mockResponse);
112
- });
113
-
114
- it('should fetch SVD shared queries and call fetchAnyQueries', async () => {
115
- // Arrange
116
- const mockPath = 'Custom Path';
117
- const mockDocType = 'SVD';
118
- const mockQueries = { name: 'Query 1' };
119
- const mockResponse = { systemOverviewQueryTree: {}, knownBugsQueryTree: {} };
120
-
121
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockQueries);
122
- jest.spyOn(ticketsDataProvider as any, 'fetchAnyQueries').mockResolvedValueOnce(mockResponse);
123
-
124
- // Act
125
- const result = await ticketsDataProvider.GetSharedQueries(mockProject, mockPath, mockDocType);
126
-
127
- // Assert
128
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(
129
- `${mockOrgUrl}${mockProject}/_apis/wit/queries/${mockPath}?$depth=2&$expand=all`,
130
- mockToken
131
- );
132
- expect(result).toEqual(mockResponse);
133
- });
134
-
135
- it('should handle errors', async () => {
136
- // Arrange
137
- const mockPath = '';
138
- const mockError = new Error('API error');
139
-
140
- (TFSServices.getItemContent as jest.Mock).mockImplementationOnce(() => {
141
- return Promise.reject(mockError);
142
- });
143
-
144
- // Act & Assert
145
- await expect(ticketsDataProvider.GetSharedQueries(mockProject, mockPath))
146
- .rejects.toThrow('API error');
147
- expect(logger.error).toHaveBeenCalled();
148
- });
149
- });
150
-
151
- describe('GetQueryResultsFromWiql', () => {
152
- it('should handle OneHop query with table format', async () => {
153
- // Arrange
154
- const mockWiqlHref = 'https://example.com/wiql';
155
- const mockTestCaseMap = new Map<number, Set<any>>();
156
- const mockQueryResult = {
157
- queryType: QueryType.OneHop,
158
- columns: [],
159
- workItemRelations: [{ source: null, target: { id: 1, url: 'url' } }]
160
- };
161
- const mockTableResult = {
162
- sourceTargetsMap: new Map(),
163
- sortingSourceColumnsMap: new Map(),
164
- sortingTargetsColumnsMap: new Map()
165
- };
166
-
167
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockQueryResult);
168
- jest.spyOn(ticketsDataProvider as any, 'parseDirectLinkedQueryResultForTableFormat')
169
- .mockResolvedValueOnce(mockTableResult);
170
-
171
- // Act
172
- const result = await ticketsDataProvider.GetQueryResultsFromWiql(
173
- mockWiqlHref, true, mockTestCaseMap
174
- );
175
-
176
- // Assert
177
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(mockWiqlHref, mockToken);
178
- expect(result).toEqual(mockTableResult);
179
- });
180
-
181
- it('should throw error when wiqlHref is empty', async () => {
182
- // Arrange
183
- const mockTestCaseMap = new Map<number, Set<any>>();
184
-
185
- // Act & Assert
186
- const result = await ticketsDataProvider.GetQueryResultsFromWiql('', false, mockTestCaseMap);
187
- expect(logger.error).toHaveBeenCalled();
188
- expect(result).toBeUndefined();
189
- });
190
- });
191
-
192
- describe('GetModeledQuery', () => {
193
- it('should structure query list correctly', () => {
194
- // Arrange
195
- const mockQueryList = [
196
- {
197
- name: 'Query 1',
198
- _links: { wiql: 'http://example.com/wiql1' },
199
- id: 'q1'
200
- },
201
- {
202
- name: 'Query 2',
203
- _links: { wiql: null },
204
- id: 'q2'
205
- }
206
- ];
207
-
208
- // Act
209
- const result = ticketsDataProvider.GetModeledQuery(mockQueryList);
210
-
211
- // Assert
212
- expect(result).toEqual([
213
- { queryName: 'Query 1', wiql: 'http://example.com/wiql1', id: 'q1' },
214
- { queryName: 'Query 2', wiql: null, id: 'q2' }
215
- ]);
216
- });
217
- });
218
-
219
- describe('PopulateWorkItemsByIds', () => {
220
- it('should fetch work items in batches of 200', async () => {
221
- // Arrange
222
- const mockIds = Array.from({ length: 250 }, (_, i) => i + 1);
223
- const mockResponse1 = { value: mockIds.slice(0, 200).map(id => ({ id })) };
224
- const mockResponse2 = { value: mockIds.slice(200).map(id => ({ id })) };
225
-
226
- (TFSServices.getItemContent as jest.Mock)
227
- .mockResolvedValueOnce(mockResponse1)
228
- .mockResolvedValueOnce(mockResponse2);
229
-
230
- // Act
231
- const result = await ticketsDataProvider.PopulateWorkItemsByIds(mockIds, mockProject);
232
-
233
- // Assert
234
- expect(TFSServices.getItemContent).toHaveBeenCalledTimes(2);
235
- expect(result.length).toBe(250);
236
- });
237
-
238
- it('should handle errors and return empty array', async () => {
239
- // Arrange
240
- const mockIds = [1, 2, 3];
241
- const mockError = new Error('API error');
242
-
243
- (TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
244
-
245
- // Act
246
- const result = await ticketsDataProvider.PopulateWorkItemsByIds(mockIds, mockProject);
247
-
248
- // Assert
249
- expect(result).toEqual([]);
250
- expect(logger.error).toHaveBeenCalled();
251
- });
252
- });
253
-
254
- describe('GetIterationsByTeamName', () => {
255
- it('should fetch iterations with team name specified', async () => {
256
- // Arrange
257
- const mockTeamName = 'test-team';
258
- const mockIterations = ['iteration1', 'iteration2'];
259
-
260
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockIterations);
261
-
262
- // Act
263
- const result = await ticketsDataProvider.GetIterationsByTeamName(mockProject, mockTeamName);
264
-
265
- // Assert
266
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(
267
- `${mockOrgUrl}${mockProject}/${mockTeamName}/_apis/work/teamsettings/iterations`,
268
- mockToken,
269
- 'get'
270
- );
271
- expect(result).toEqual(mockIterations);
272
- });
273
-
274
- it('should fetch iterations without team name', async () => {
275
- // Arrange
276
- const mockTeamName = '';
277
- const mockIterations = ['iteration1', 'iteration2'];
278
-
279
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockIterations);
280
-
281
- // Act
282
- const result = await ticketsDataProvider.GetIterationsByTeamName(mockProject, mockTeamName);
283
-
284
- // Assert
285
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(
286
- `${mockOrgUrl}${mockProject}/_apis/work/teamsettings/iterations`,
287
- mockToken,
288
- 'get'
289
- );
290
- expect(result).toEqual(mockIterations);
291
- });
292
- });
293
-
294
- describe('CreateNewWorkItem', () => {
295
- it('should create work item with correct parameters', async () => {
296
- // Arrange
297
- const mockWiBody = [{ op: 'add', path: '/fields/System.Title', value: 'New Item' }];
298
- const mockWiType = 'Bug';
299
- const mockByPass = true;
300
- const mockResponse = { id: 123, fields: { 'System.Title': 'New Item' } };
301
-
302
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
303
-
304
- // Act
305
- const result = await ticketsDataProvider.CreateNewWorkItem(
306
- mockProject, mockWiBody, mockWiType, mockByPass
307
- );
308
-
309
- // Assert
310
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(
311
- `${mockOrgUrl}${mockProject}/_apis/wit/workitems/$${mockWiType}?bypassRules=true`,
312
- mockToken,
313
- 'POST',
314
- mockWiBody,
315
- {
316
- 'Content-Type': 'application/json-patch+json'
317
- }
318
- );
319
- expect(result).toEqual(mockResponse);
320
- });
321
- });
322
-
323
- describe('UpdateWorkItem', () => {
324
- it('should update work item with correct parameters', async () => {
325
- // Arrange
326
- const mockWiBody = [{ op: 'add', path: '/fields/System.Title', value: 'Updated Item' }];
327
- const mockWorkItemId = 123;
328
- const mockByPass = true;
329
- const mockResponse = { id: 123, fields: { 'System.Title': 'Updated Item' } };
330
-
331
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
332
-
333
- // Act
334
- const result = await ticketsDataProvider.UpdateWorkItem(
335
- mockProject, mockWiBody, mockWorkItemId, mockByPass
336
- );
337
-
338
- // Assert
339
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(
340
- `${mockOrgUrl}${mockProject}/_apis/wit/workitems/${mockWorkItemId}?bypassRules=true`,
341
- mockToken,
342
- 'patch',
343
- mockWiBody,
344
- {
345
- 'Content-Type': 'application/json-patch+json'
346
- }
347
- );
348
- expect(result).toEqual(mockResponse);
349
- });
350
- });
351
-
352
- describe('GetWorkitemAttachments', () => {
353
- it('should return attachments for work item', async () => {
354
- // Arrange
355
- const mockId = '123';
356
- const mockWorkItem = {
357
- relations: [
358
- {
359
- rel: 'AttachedFile',
360
- url: 'https://example.com/attachment/1',
361
- attributes: { name: 'file.txt' }
362
- }
363
- ]
364
- };
365
-
366
- // Mock the TFSServices.getItemContent directly to return our mock data
367
- // This is what will be called by the new TicketsDataProvider instance
368
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockWorkItem);
369
-
370
- // Act
371
- const result = await ticketsDataProvider.GetWorkitemAttachments(mockProject, mockId);
372
-
373
- // Assert
374
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(
375
- `${mockOrgUrl}${mockProject}/_apis/wit/workitems/${mockId}?$expand=All`,
376
- mockToken
377
- );
378
- expect(result.length).toBe(1);
379
-
380
- // Check that the downloadUrl was added correctly
381
- expect(result[0]).toHaveProperty('downloadUrl', 'https://example.com/attachment/1/file.txt');
382
- expect(result[0].rel).toBe('AttachedFile');
383
- });
384
-
385
- it('should handle work item with no relations', async () => {
386
- // Arrange
387
- const mockId = '123';
388
- const mockWorkItem = { relations: null };
389
-
390
- jest.spyOn(ticketsDataProvider, 'GetWorkItem').mockResolvedValueOnce(mockWorkItem);
391
-
392
- // Act
393
- const result = await ticketsDataProvider.GetWorkitemAttachments(mockProject, mockId);
394
-
395
- // Assert
396
- expect(result).toEqual([]);
397
- });
398
-
399
- it('should filter out non-attachment relations', async () => {
400
- // Arrange
401
- const mockId = '123';
402
- const mockWorkItem = {
403
- relations: [
404
- {
405
- rel: 'Parent',
406
- url: 'https://example.com/parent/1',
407
- attributes: { name: 'parent' }
408
- },
409
- {
410
- rel: 'AttachedFile',
411
- url: 'https://example.com/attachment/1',
412
- attributes: { name: 'file.txt' }
413
- }
414
- ]
415
- };
416
-
417
- // Mock TFSServices.getItemContent directly instead of GetWorkItem
418
- (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockWorkItem);
419
-
420
- // Act
421
- const result = await ticketsDataProvider.GetWorkitemAttachments(mockProject, mockId);
422
-
423
- // Assert
424
- expect(TFSServices.getItemContent).toHaveBeenCalledWith(
425
- `${mockOrgUrl}${mockProject}/_apis/wit/workitems/${mockId}?$expand=All`,
426
- mockToken
427
- );
428
- expect(result.length).toBe(1);
429
- expect(result[0].rel).toBe('AttachedFile');
430
- // Only the AttachedFile relation should be in the result
431
- expect(result.some(item => item.rel === 'Parent')).toBe(false);
432
- });
433
- });
434
- });