@elisra-devops/docgen-data-provider 1.63.11 → 1.63.13
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/bin/modules/GitDataProvider.d.ts +1 -1
- package/bin/modules/GitDataProvider.js +6 -3
- package/bin/modules/GitDataProvider.js.map +1 -1
- package/bin/modules/MangementDataProvider.js +7 -1
- package/bin/modules/MangementDataProvider.js.map +1 -1
- package/bin/modules/TicketsDataProvider.d.ts +0 -3
- package/bin/modules/TicketsDataProvider.js +22 -20
- package/bin/modules/TicketsDataProvider.js.map +1 -1
- package/bin/modules/test/gitDataProvider.test.js +23 -28
- package/bin/modules/test/gitDataProvider.test.js.map +1 -1
- package/bin/modules/test/managmentDataProvider.test.js +26 -30
- package/bin/modules/test/managmentDataProvider.test.js.map +1 -1
- package/bin/modules/test/ticketsDataProvider.test.js +55 -29
- package/bin/modules/test/ticketsDataProvider.test.js.map +1 -1
- package/package.json +2 -1
- package/src/modules/GitDataProvider.ts +6 -3
- package/src/modules/MangementDataProvider.ts +6 -1
- package/src/modules/TicketsDataProvider.ts +25 -22
- package/src/modules/test/gitDataProvider.test.ts +50 -96
- package/src/modules/test/managmentDataProvider.test.ts +30 -31
- package/src/modules/test/ticketsDataProvider.test.ts +68 -40
|
@@ -69,7 +69,9 @@ export default class TicketsDataProvider {
|
|
|
69
69
|
const fieldsArr = Array.isArray(fieldsResp?.value) ? fieldsResp.value : [];
|
|
70
70
|
const candidates = fieldsArr
|
|
71
71
|
.filter((f: any) => {
|
|
72
|
-
const nm = String(f?.name || '')
|
|
72
|
+
const nm = String(f?.name || '')
|
|
73
|
+
.toLowerCase()
|
|
74
|
+
.replace(/_/g, ' ');
|
|
73
75
|
return nm.includes('requirement type');
|
|
74
76
|
})
|
|
75
77
|
.map((f: any) => f?.referenceName)
|
|
@@ -569,7 +571,7 @@ export default class TicketsDataProvider {
|
|
|
569
571
|
queries,
|
|
570
572
|
false,
|
|
571
573
|
null,
|
|
572
|
-
['
|
|
574
|
+
['epic', 'feature', 'requirement'],
|
|
573
575
|
[],
|
|
574
576
|
undefined,
|
|
575
577
|
undefined,
|
|
@@ -643,8 +645,8 @@ export default class TicketsDataProvider {
|
|
|
643
645
|
queries,
|
|
644
646
|
onlySourceSide,
|
|
645
647
|
null,
|
|
646
|
-
['
|
|
647
|
-
['
|
|
648
|
+
['epic', 'feature', 'requirement'],
|
|
649
|
+
['epic', 'feature', 'requirement'],
|
|
648
650
|
'sys', // Source area filter for tree1: System area paths
|
|
649
651
|
'soft' // Target area filter for tree1: Software area paths (tree2 will be reversed automatically)
|
|
650
652
|
);
|
|
@@ -660,8 +662,8 @@ export default class TicketsDataProvider {
|
|
|
660
662
|
folder,
|
|
661
663
|
false,
|
|
662
664
|
null,
|
|
663
|
-
['
|
|
664
|
-
['
|
|
665
|
+
['epic', 'feature', 'requirement'],
|
|
666
|
+
['epic', 'feature', 'requirement'],
|
|
665
667
|
undefined,
|
|
666
668
|
undefined,
|
|
667
669
|
true
|
|
@@ -1771,9 +1773,7 @@ export default class TicketsDataProvider {
|
|
|
1771
1773
|
if (typesOk) {
|
|
1772
1774
|
const allowTree1 =
|
|
1773
1775
|
!onlyTestReq &&
|
|
1774
|
-
(sourceAreaFilter
|
|
1775
|
-
? this.matchesFlatAreaCondition(wiql, sourceAreaFilter || '')
|
|
1776
|
-
: true);
|
|
1776
|
+
(sourceAreaFilter ? this.matchesFlatAreaCondition(wiql, sourceAreaFilter || '') : true);
|
|
1777
1777
|
const allowTree2 = targetAreaFilter
|
|
1778
1778
|
? this.matchesFlatAreaCondition(wiql, targetAreaFilter || '')
|
|
1779
1779
|
: true;
|
|
@@ -1939,9 +1939,6 @@ export default class TicketsDataProvider {
|
|
|
1939
1939
|
* - Source.[System.WorkItemType] = 'Epic'
|
|
1940
1940
|
* - Source.[System.WorkItemType] IN ('Epic', 'Feature', 'Requirement')
|
|
1941
1941
|
*
|
|
1942
|
-
* @param wiql - The WIQL string to evaluate.
|
|
1943
|
-
* @param source - An array of source work item types to check for in the WIQL.
|
|
1944
|
-
* @param target - An array of target work item types to check for in the WIQL.
|
|
1945
1942
|
* @returns A boolean indicating whether the WIQL includes at least one valid source work item type
|
|
1946
1943
|
* and at least one valid target work item type.
|
|
1947
1944
|
*/
|
|
@@ -1965,9 +1962,12 @@ export default class TicketsDataProvider {
|
|
|
1965
1962
|
context: 'Source' | 'Target',
|
|
1966
1963
|
allowedTypes: string[]
|
|
1967
1964
|
): boolean {
|
|
1965
|
+
const wiqlStr = String(wiql || '');
|
|
1966
|
+
|
|
1968
1967
|
// If allowedTypes is empty, accept any work item type (for backward compatibility)
|
|
1969
|
-
if (allowedTypes.length === 0) {
|
|
1970
|
-
|
|
1968
|
+
if (!allowedTypes || allowedTypes.length === 0) {
|
|
1969
|
+
const fieldPresenceRegex = new RegExp(`${context}\\.\\[System.WorkItemType\\]`, 'i');
|
|
1970
|
+
return fieldPresenceRegex.test(wiqlStr);
|
|
1971
1971
|
}
|
|
1972
1972
|
|
|
1973
1973
|
const fieldPattern = `${context}.\\[System.WorkItemType\\]`;
|
|
@@ -1979,20 +1979,20 @@ export default class TicketsDataProvider {
|
|
|
1979
1979
|
const inRegex = new RegExp(`${fieldPattern}\\s+IN\\s*\\(([^)]+)\\)`, 'gi');
|
|
1980
1980
|
|
|
1981
1981
|
const foundTypes = new Set<string>();
|
|
1982
|
+
let match: RegExpExecArray | null;
|
|
1982
1983
|
|
|
1983
1984
|
// Extract types from equality operators
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
foundTypes.add(match[1].trim());
|
|
1985
|
+
while ((match = equalityRegex.exec(wiqlStr)) !== null) {
|
|
1986
|
+
foundTypes.add(String(match[1]).trim().toLowerCase());
|
|
1987
1987
|
}
|
|
1988
1988
|
|
|
1989
1989
|
// Extract types from IN operators
|
|
1990
|
-
while ((match = inRegex.exec(
|
|
1990
|
+
while ((match = inRegex.exec(wiqlStr)) !== null) {
|
|
1991
1991
|
const typesString = match[1];
|
|
1992
1992
|
// Extract all quoted values from the IN clause
|
|
1993
1993
|
const typeMatches = typesString.matchAll(/'([^']+)'/g);
|
|
1994
1994
|
for (const typeMatch of typeMatches) {
|
|
1995
|
-
foundTypes.add(typeMatch[1].trim());
|
|
1995
|
+
foundTypes.add(String(typeMatch[1]).trim().toLowerCase());
|
|
1996
1996
|
}
|
|
1997
1997
|
}
|
|
1998
1998
|
|
|
@@ -2001,9 +2001,10 @@ export default class TicketsDataProvider {
|
|
|
2001
2001
|
return false;
|
|
2002
2002
|
}
|
|
2003
2003
|
|
|
2004
|
-
// Check if all found types are in the allowedTypes array
|
|
2004
|
+
// Check if all found types are in the allowedTypes array (case-insensitive)
|
|
2005
|
+
const allowedSet = new Set(allowedTypes.map((t) => String(t).toLowerCase()));
|
|
2005
2006
|
for (const type of foundTypes) {
|
|
2006
|
-
if (!
|
|
2007
|
+
if (!allowedSet.has(type)) {
|
|
2007
2008
|
// Found a type that's not in the allowed list - reject this query
|
|
2008
2009
|
return false;
|
|
2009
2010
|
}
|
|
@@ -2067,7 +2068,9 @@ export default class TicketsDataProvider {
|
|
|
2067
2068
|
* Compares only the leaf segment of the path and performs a case-insensitive substring match.
|
|
2068
2069
|
*/
|
|
2069
2070
|
private matchesFlatAreaCondition(wiql: string, areaFilter: string): boolean {
|
|
2070
|
-
const filter = String(areaFilter || '')
|
|
2071
|
+
const filter = String(areaFilter || '')
|
|
2072
|
+
.trim()
|
|
2073
|
+
.toLowerCase();
|
|
2071
2074
|
if (!filter) return true;
|
|
2072
2075
|
|
|
2073
2076
|
const wiqlLower = String(wiql || '').toLowerCase();
|
|
@@ -24,7 +24,7 @@ describe('GitDataProvider - GetCommitForPipeline', () => {
|
|
|
24
24
|
const mockResponse = {
|
|
25
25
|
id: mockBuildId,
|
|
26
26
|
sourceVersion: mockCommitSha,
|
|
27
|
-
status: 'completed'
|
|
27
|
+
status: 'completed',
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
@@ -47,8 +47,9 @@ describe('GitDataProvider - GetCommitForPipeline', () => {
|
|
|
47
47
|
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
|
|
48
48
|
|
|
49
49
|
// Act & Assert
|
|
50
|
-
await expect(gitDataProvider.GetCommitForPipeline(mockProjectId, mockBuildId))
|
|
51
|
-
|
|
50
|
+
await expect(gitDataProvider.GetCommitForPipeline(mockProjectId, mockBuildId)).rejects.toThrow(
|
|
51
|
+
'API call failed'
|
|
52
|
+
);
|
|
52
53
|
|
|
53
54
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
54
55
|
`${mockOrgUrl}${mockProjectId}/_apis/build/builds/${mockBuildId}`,
|
|
@@ -61,7 +62,7 @@ describe('GitDataProvider - GetCommitForPipeline', () => {
|
|
|
61
62
|
// Arrange
|
|
62
63
|
const mockResponse = {
|
|
63
64
|
id: mockBuildId,
|
|
64
|
-
status: 'completed'
|
|
65
|
+
status: 'completed',
|
|
65
66
|
// No sourceVersion property
|
|
66
67
|
};
|
|
67
68
|
|
|
@@ -135,8 +136,8 @@ describe('GitDataProvider - GetTeamProjectGitReposList', () => {
|
|
|
135
136
|
value: [
|
|
136
137
|
{ id: 'repo2', name: 'ZRepo' },
|
|
137
138
|
{ id: 'repo1', name: 'ARepo' },
|
|
138
|
-
{ id: 'repo3', name: 'MRepo' }
|
|
139
|
-
]
|
|
139
|
+
{ id: 'repo3', name: 'MRepo' },
|
|
140
|
+
],
|
|
140
141
|
};
|
|
141
142
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockRepos);
|
|
142
143
|
|
|
@@ -176,8 +177,7 @@ describe('GitDataProvider - GetTeamProjectGitReposList', () => {
|
|
|
176
177
|
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
|
|
177
178
|
|
|
178
179
|
// Act & Assert
|
|
179
|
-
await expect(gitDataProvider.GetTeamProjectGitReposList(mockTeamProject))
|
|
180
|
-
.rejects.toThrow('API Error');
|
|
180
|
+
await expect(gitDataProvider.GetTeamProjectGitReposList(mockTeamProject)).rejects.toThrow('API Error');
|
|
181
181
|
});
|
|
182
182
|
});
|
|
183
183
|
|
|
@@ -228,12 +228,7 @@ describe('GitDataProvider - GetFileFromGitRepo', () => {
|
|
|
228
228
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
229
229
|
|
|
230
230
|
// Act
|
|
231
|
-
await gitDataProvider.GetFileFromGitRepo(
|
|
232
|
-
mockProjectName,
|
|
233
|
-
mockRepoId,
|
|
234
|
-
mockFileName,
|
|
235
|
-
specialVersion
|
|
236
|
-
);
|
|
231
|
+
await gitDataProvider.GetFileFromGitRepo(mockProjectName, mockRepoId, mockFileName, specialVersion);
|
|
237
232
|
|
|
238
233
|
// Assert
|
|
239
234
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
@@ -328,11 +323,7 @@ describe('GitDataProvider - CheckIfItemExist', () => {
|
|
|
328
323
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
329
324
|
|
|
330
325
|
// Act
|
|
331
|
-
const result = await gitDataProvider.CheckIfItemExist(
|
|
332
|
-
mockGitApiUrl,
|
|
333
|
-
mockItemPath,
|
|
334
|
-
mockVersion
|
|
335
|
-
);
|
|
326
|
+
const result = await gitDataProvider.CheckIfItemExist(mockGitApiUrl, mockItemPath, mockVersion);
|
|
336
327
|
|
|
337
328
|
// Assert
|
|
338
329
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
@@ -351,11 +342,7 @@ describe('GitDataProvider - CheckIfItemExist', () => {
|
|
|
351
342
|
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(new Error('Not found'));
|
|
352
343
|
|
|
353
344
|
// Act
|
|
354
|
-
const result = await gitDataProvider.CheckIfItemExist(
|
|
355
|
-
mockGitApiUrl,
|
|
356
|
-
mockItemPath,
|
|
357
|
-
mockVersion
|
|
358
|
-
);
|
|
345
|
+
const result = await gitDataProvider.CheckIfItemExist(mockGitApiUrl, mockItemPath, mockVersion);
|
|
359
346
|
|
|
360
347
|
// Assert
|
|
361
348
|
expect(result).toBe(false);
|
|
@@ -366,11 +353,7 @@ describe('GitDataProvider - CheckIfItemExist', () => {
|
|
|
366
353
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(null);
|
|
367
354
|
|
|
368
355
|
// Act
|
|
369
|
-
const result = await gitDataProvider.CheckIfItemExist(
|
|
370
|
-
mockGitApiUrl,
|
|
371
|
-
mockItemPath,
|
|
372
|
-
mockVersion
|
|
373
|
-
);
|
|
356
|
+
const result = await gitDataProvider.CheckIfItemExist(mockGitApiUrl, mockItemPath, mockVersion);
|
|
374
357
|
|
|
375
358
|
// Assert
|
|
376
359
|
expect(result).toBe(false);
|
|
@@ -383,11 +366,7 @@ describe('GitDataProvider - CheckIfItemExist', () => {
|
|
|
383
366
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
384
367
|
|
|
385
368
|
// Act
|
|
386
|
-
await gitDataProvider.CheckIfItemExist(
|
|
387
|
-
mockGitApiUrl,
|
|
388
|
-
mockItemPath,
|
|
389
|
-
specialVersion
|
|
390
|
-
);
|
|
369
|
+
await gitDataProvider.CheckIfItemExist(mockGitApiUrl, mockItemPath, specialVersion);
|
|
391
370
|
|
|
392
371
|
// Assert
|
|
393
372
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
@@ -416,10 +395,7 @@ describe('GitDataProvider - GetPullRequestsInCommitRangeWithoutLinkedItems', ()
|
|
|
416
395
|
it('should return filtered pull requests matching commit ids', async () => {
|
|
417
396
|
// Arrange
|
|
418
397
|
const mockCommits = {
|
|
419
|
-
value: [
|
|
420
|
-
{ commitId: 'commit-1' },
|
|
421
|
-
{ commitId: 'commit-2' }
|
|
422
|
-
]
|
|
398
|
+
value: [{ commitId: 'commit-1' }, { commitId: 'commit-2' }],
|
|
423
399
|
};
|
|
424
400
|
|
|
425
401
|
const mockPullRequests = {
|
|
@@ -432,7 +408,7 @@ describe('GitDataProvider - GetPullRequestsInCommitRangeWithoutLinkedItems', ()
|
|
|
432
408
|
creationDate: '2023-01-01',
|
|
433
409
|
closedDate: '2023-01-02',
|
|
434
410
|
description: 'Description 1',
|
|
435
|
-
lastMergeCommit: { commitId: 'commit-1' }
|
|
411
|
+
lastMergeCommit: { commitId: 'commit-1' },
|
|
436
412
|
},
|
|
437
413
|
{
|
|
438
414
|
pullRequestId: 102,
|
|
@@ -441,7 +417,7 @@ describe('GitDataProvider - GetPullRequestsInCommitRangeWithoutLinkedItems', ()
|
|
|
441
417
|
creationDate: '2023-02-01',
|
|
442
418
|
closedDate: '2023-02-02',
|
|
443
419
|
description: 'Description 2',
|
|
444
|
-
lastMergeCommit: { commitId: 'commit-3' } // Not in our commit range
|
|
420
|
+
lastMergeCommit: { commitId: 'commit-3' }, // Not in our commit range
|
|
445
421
|
},
|
|
446
422
|
{
|
|
447
423
|
pullRequestId: 103,
|
|
@@ -450,9 +426,9 @@ describe('GitDataProvider - GetPullRequestsInCommitRangeWithoutLinkedItems', ()
|
|
|
450
426
|
creationDate: '2023-03-01',
|
|
451
427
|
closedDate: '2023-03-02',
|
|
452
428
|
description: 'Description 3',
|
|
453
|
-
lastMergeCommit: { commitId: 'commit-2' }
|
|
454
|
-
}
|
|
455
|
-
]
|
|
429
|
+
lastMergeCommit: { commitId: 'commit-2' },
|
|
430
|
+
},
|
|
431
|
+
],
|
|
456
432
|
};
|
|
457
433
|
|
|
458
434
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockPullRequests);
|
|
@@ -466,7 +442,9 @@ describe('GitDataProvider - GetPullRequestsInCommitRangeWithoutLinkedItems', ()
|
|
|
466
442
|
|
|
467
443
|
// Assert
|
|
468
444
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
469
|
-
expect.stringContaining(
|
|
445
|
+
expect.stringContaining(
|
|
446
|
+
`${mockOrgUrl}${mockProjectId}/_apis/git/repositories/${mockRepoId}/pullrequests`
|
|
447
|
+
),
|
|
470
448
|
mockToken,
|
|
471
449
|
'get'
|
|
472
450
|
);
|
|
@@ -482,8 +460,8 @@ describe('GitDataProvider - GetPullRequestsInCommitRangeWithoutLinkedItems', ()
|
|
|
482
460
|
// Arrange
|
|
483
461
|
const mockCommits = {
|
|
484
462
|
value: [
|
|
485
|
-
{ commitId: 'commit-999' } // Not matching any PRs
|
|
486
|
-
]
|
|
463
|
+
{ commitId: 'commit-999' }, // Not matching any PRs
|
|
464
|
+
],
|
|
487
465
|
};
|
|
488
466
|
|
|
489
467
|
const mockPullRequests = {
|
|
@@ -491,13 +469,13 @@ describe('GitDataProvider - GetPullRequestsInCommitRangeWithoutLinkedItems', ()
|
|
|
491
469
|
value: [
|
|
492
470
|
{
|
|
493
471
|
pullRequestId: 101,
|
|
494
|
-
lastMergeCommit: { commitId: 'commit-1' }
|
|
472
|
+
lastMergeCommit: { commitId: 'commit-1' },
|
|
495
473
|
},
|
|
496
474
|
{
|
|
497
475
|
pullRequestId: 102,
|
|
498
|
-
lastMergeCommit: { commitId: 'commit-2' }
|
|
499
|
-
}
|
|
500
|
-
]
|
|
476
|
+
lastMergeCommit: { commitId: 'commit-2' },
|
|
477
|
+
},
|
|
478
|
+
],
|
|
501
479
|
};
|
|
502
480
|
|
|
503
481
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockPullRequests);
|
|
@@ -520,11 +498,9 @@ describe('GitDataProvider - GetPullRequestsInCommitRangeWithoutLinkedItems', ()
|
|
|
520
498
|
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
|
|
521
499
|
|
|
522
500
|
// Act & Assert
|
|
523
|
-
await expect(
|
|
524
|
-
mockProjectId,
|
|
525
|
-
|
|
526
|
-
mockCommits
|
|
527
|
-
)).rejects.toThrow('API Error');
|
|
501
|
+
await expect(
|
|
502
|
+
gitDataProvider.GetPullRequestsInCommitRangeWithoutLinkedItems(mockProjectId, mockRepoId, mockCommits)
|
|
503
|
+
).rejects.toThrow('API Error');
|
|
528
504
|
});
|
|
529
505
|
});
|
|
530
506
|
|
|
@@ -546,21 +522,17 @@ describe('GitDataProvider - GetRepoReferences', () => {
|
|
|
546
522
|
count: 2,
|
|
547
523
|
value: [
|
|
548
524
|
{ name: 'refs/tags/v1.0.0', objectId: 'tag-1' },
|
|
549
|
-
{ name: 'refs/tags/v2.0.0', objectId: 'tag-2' }
|
|
550
|
-
]
|
|
525
|
+
{ name: 'refs/tags/v2.0.0', objectId: 'tag-2' },
|
|
526
|
+
],
|
|
551
527
|
};
|
|
552
528
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockTags);
|
|
553
529
|
|
|
554
530
|
// Act
|
|
555
|
-
const result = await gitDataProvider.GetRepoReferences(
|
|
556
|
-
mockProjectId,
|
|
557
|
-
mockRepoId,
|
|
558
|
-
'tag'
|
|
559
|
-
);
|
|
531
|
+
const result = await gitDataProvider.GetRepoReferences(mockProjectId, mockRepoId, 'tag');
|
|
560
532
|
|
|
561
533
|
// Assert
|
|
562
534
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
563
|
-
`${mockOrgUrl}${mockProjectId}/_apis/git/repositories/${mockRepoId}/refs/tags?api-version=5.1`,
|
|
535
|
+
`${mockOrgUrl}${mockProjectId}/_apis/git/repositories/${mockRepoId}/refs/tags?peelTags=true&api-version=5.1`,
|
|
564
536
|
mockToken,
|
|
565
537
|
'get'
|
|
566
538
|
);
|
|
@@ -577,17 +549,13 @@ describe('GitDataProvider - GetRepoReferences', () => {
|
|
|
577
549
|
count: 2,
|
|
578
550
|
value: [
|
|
579
551
|
{ name: 'refs/heads/main', objectId: 'branch-1' },
|
|
580
|
-
{ name: 'refs/heads/develop', objectId: 'branch-2' }
|
|
581
|
-
]
|
|
552
|
+
{ name: 'refs/heads/develop', objectId: 'branch-2' },
|
|
553
|
+
],
|
|
582
554
|
};
|
|
583
555
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockBranches);
|
|
584
556
|
|
|
585
557
|
// Act
|
|
586
|
-
const result = await gitDataProvider.GetRepoReferences(
|
|
587
|
-
mockProjectId,
|
|
588
|
-
mockRepoId,
|
|
589
|
-
'branch'
|
|
590
|
-
);
|
|
558
|
+
const result = await gitDataProvider.GetRepoReferences(mockProjectId, mockRepoId, 'branch');
|
|
591
559
|
|
|
592
560
|
// Assert
|
|
593
561
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
@@ -604,11 +572,9 @@ describe('GitDataProvider - GetRepoReferences', () => {
|
|
|
604
572
|
|
|
605
573
|
it('should throw error for unsupported git object type', async () => {
|
|
606
574
|
// Act & Assert
|
|
607
|
-
await expect(
|
|
608
|
-
mockProjectId,
|
|
609
|
-
|
|
610
|
-
'invalid-type'
|
|
611
|
-
)).rejects.toThrow('Unsupported git object type: invalid-type');
|
|
575
|
+
await expect(
|
|
576
|
+
gitDataProvider.GetRepoReferences(mockProjectId, mockRepoId, 'invalid-type')
|
|
577
|
+
).rejects.toThrow('Unsupported git object type: invalid-type');
|
|
612
578
|
});
|
|
613
579
|
|
|
614
580
|
it('should return empty array when no references exist', async () => {
|
|
@@ -617,11 +583,7 @@ describe('GitDataProvider - GetRepoReferences', () => {
|
|
|
617
583
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockEmptyRefs);
|
|
618
584
|
|
|
619
585
|
// Act
|
|
620
|
-
const result = await gitDataProvider.GetRepoReferences(
|
|
621
|
-
mockProjectId,
|
|
622
|
-
mockRepoId,
|
|
623
|
-
'branch'
|
|
624
|
-
);
|
|
586
|
+
const result = await gitDataProvider.GetRepoReferences(mockProjectId, mockRepoId, 'branch');
|
|
625
587
|
|
|
626
588
|
// Assert
|
|
627
589
|
expect(result).toEqual([]);
|
|
@@ -648,11 +610,7 @@ describe('GitDataProvider - GetJsonFileFromGitRepo', () => {
|
|
|
648
610
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
649
611
|
|
|
650
612
|
// Act
|
|
651
|
-
const result = await gitDataProvider.GetJsonFileFromGitRepo(
|
|
652
|
-
mockProjectName,
|
|
653
|
-
mockRepoName,
|
|
654
|
-
mockFilePath
|
|
655
|
-
);
|
|
613
|
+
const result = await gitDataProvider.GetJsonFileFromGitRepo(mockProjectName, mockRepoName, mockFilePath);
|
|
656
614
|
|
|
657
615
|
// Assert
|
|
658
616
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
@@ -669,11 +627,9 @@ describe('GitDataProvider - GetJsonFileFromGitRepo', () => {
|
|
|
669
627
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockInvalidJson);
|
|
670
628
|
|
|
671
629
|
// Act & Assert
|
|
672
|
-
await expect(
|
|
673
|
-
mockProjectName,
|
|
674
|
-
|
|
675
|
-
mockFilePath
|
|
676
|
-
)).rejects.toThrow(SyntaxError);
|
|
630
|
+
await expect(
|
|
631
|
+
gitDataProvider.GetJsonFileFromGitRepo(mockProjectName, mockRepoName, mockFilePath)
|
|
632
|
+
).rejects.toThrow(SyntaxError);
|
|
677
633
|
});
|
|
678
634
|
|
|
679
635
|
it('should handle API errors appropriately', async () => {
|
|
@@ -682,10 +638,8 @@ describe('GitDataProvider - GetJsonFileFromGitRepo', () => {
|
|
|
682
638
|
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
|
|
683
639
|
|
|
684
640
|
// Act & Assert
|
|
685
|
-
await expect(
|
|
686
|
-
mockProjectName,
|
|
687
|
-
|
|
688
|
-
mockFilePath
|
|
689
|
-
)).rejects.toThrow('API Error');
|
|
641
|
+
await expect(
|
|
642
|
+
gitDataProvider.GetJsonFileFromGitRepo(mockProjectName, mockRepoName, mockFilePath)
|
|
643
|
+
).rejects.toThrow('API Error');
|
|
690
644
|
});
|
|
691
|
-
});
|
|
645
|
+
});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { TFSServices } from '../../helpers/tfs';
|
|
2
2
|
import MangementDataProvider from '../MangementDataProvider';
|
|
3
|
+
import logger from '../../utils/logger';
|
|
3
4
|
|
|
4
5
|
jest.mock('../../helpers/tfs');
|
|
6
|
+
jest.mock('../../utils/logger');
|
|
5
7
|
|
|
6
8
|
describe('MangementDataProvider', () => {
|
|
7
9
|
let managementDataProvider: MangementDataProvider;
|
|
@@ -19,8 +21,8 @@ describe('MangementDataProvider', () => {
|
|
|
19
21
|
const mockResponse = {
|
|
20
22
|
value: [
|
|
21
23
|
{ id: 'link-1', name: 'Child' },
|
|
22
|
-
{ id: 'link-2', name: 'Related' }
|
|
23
|
-
]
|
|
24
|
+
{ id: 'link-2', name: 'Related' },
|
|
25
|
+
],
|
|
24
26
|
};
|
|
25
27
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
26
28
|
|
|
@@ -44,8 +46,7 @@ describe('MangementDataProvider', () => {
|
|
|
44
46
|
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
|
|
45
47
|
|
|
46
48
|
// Act & Assert
|
|
47
|
-
await expect(managementDataProvider.GetCllectionLinkTypes())
|
|
48
|
-
.rejects.toThrow('API call failed');
|
|
49
|
+
await expect(managementDataProvider.GetCllectionLinkTypes()).rejects.toThrow('API call failed');
|
|
49
50
|
|
|
50
51
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
51
52
|
`${mockOrgUrl}_apis/wit/workitemrelationtypes`,
|
|
@@ -64,8 +65,8 @@ describe('MangementDataProvider', () => {
|
|
|
64
65
|
count: 2,
|
|
65
66
|
value: [
|
|
66
67
|
{ id: 'project-1', name: 'Project One' },
|
|
67
|
-
{ id: 'project-2', name: 'Project Two' }
|
|
68
|
-
]
|
|
68
|
+
{ id: 'project-2', name: 'Project Two' },
|
|
69
|
+
],
|
|
69
70
|
};
|
|
70
71
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
71
72
|
|
|
@@ -86,8 +87,7 @@ describe('MangementDataProvider', () => {
|
|
|
86
87
|
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
|
|
87
88
|
|
|
88
89
|
// Act & Assert
|
|
89
|
-
await expect(managementDataProvider.GetProjects())
|
|
90
|
-
.rejects.toThrow('Projects API call failed');
|
|
90
|
+
await expect(managementDataProvider.GetProjects()).rejects.toThrow('Projects API call failed');
|
|
91
91
|
|
|
92
92
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
93
93
|
`${mockOrgUrl}_apis/projects?$top=1000`,
|
|
@@ -103,8 +103,8 @@ describe('MangementDataProvider', () => {
|
|
|
103
103
|
count: 2,
|
|
104
104
|
value: [
|
|
105
105
|
{ id: 'project-1', name: 'Project One' },
|
|
106
|
-
{ id: 'project-2', name: 'Project Two' }
|
|
107
|
-
]
|
|
106
|
+
{ id: 'project-2', name: 'Project Two' },
|
|
107
|
+
],
|
|
108
108
|
};
|
|
109
109
|
const expectedProject = { id: 'project-2', name: 'Project Two' };
|
|
110
110
|
|
|
@@ -125,8 +125,8 @@ describe('MangementDataProvider', () => {
|
|
|
125
125
|
count: 2,
|
|
126
126
|
value: [
|
|
127
127
|
{ id: 'project-1', name: 'Project One' },
|
|
128
|
-
{ id: 'project-2', name: 'Project Two' }
|
|
129
|
-
]
|
|
128
|
+
{ id: 'project-2', name: 'Project Two' },
|
|
129
|
+
],
|
|
130
130
|
};
|
|
131
131
|
|
|
132
132
|
// Mock GetProjects to return our mock data
|
|
@@ -147,15 +147,15 @@ describe('MangementDataProvider', () => {
|
|
|
147
147
|
// Mock GetProjects to throw an error
|
|
148
148
|
jest.spyOn(managementDataProvider, 'GetProjects').mockRejectedValueOnce(expectedError);
|
|
149
149
|
|
|
150
|
-
// Mock
|
|
151
|
-
const
|
|
150
|
+
// Mock logger.error to capture the error
|
|
151
|
+
const loggerErrorSpy = jest.spyOn(logger, 'error');
|
|
152
152
|
|
|
153
153
|
// Act
|
|
154
154
|
const result = await managementDataProvider.GetProjectByName('Any Project');
|
|
155
155
|
|
|
156
156
|
// Assert
|
|
157
157
|
expect(managementDataProvider.GetProjects).toHaveBeenCalledTimes(1);
|
|
158
|
-
expect(
|
|
158
|
+
expect(loggerErrorSpy).toHaveBeenCalledWith(expectedError);
|
|
159
159
|
expect(result).toEqual({});
|
|
160
160
|
});
|
|
161
161
|
});
|
|
@@ -185,8 +185,9 @@ describe('MangementDataProvider', () => {
|
|
|
185
185
|
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
|
|
186
186
|
|
|
187
187
|
// Act & Assert
|
|
188
|
-
await expect(managementDataProvider.GetProjectByID(projectId))
|
|
189
|
-
|
|
188
|
+
await expect(managementDataProvider.GetProjectByID(projectId)).rejects.toThrow(
|
|
189
|
+
'Project API call failed'
|
|
190
|
+
);
|
|
190
191
|
|
|
191
192
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
192
193
|
`${mockOrgUrl}_apis/projects/${projectId}`,
|
|
@@ -201,7 +202,7 @@ describe('MangementDataProvider', () => {
|
|
|
201
202
|
const mockResponse = {
|
|
202
203
|
id: 'user-123',
|
|
203
204
|
displayName: 'Test User',
|
|
204
|
-
emailAddress: 'test@example.com'
|
|
205
|
+
emailAddress: 'test@example.com',
|
|
205
206
|
};
|
|
206
207
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
207
208
|
|
|
@@ -222,8 +223,7 @@ describe('MangementDataProvider', () => {
|
|
|
222
223
|
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(expectedError);
|
|
223
224
|
|
|
224
225
|
// Act & Assert
|
|
225
|
-
await expect(managementDataProvider.GetUserProfile())
|
|
226
|
-
.rejects.toThrow('User profile API call failed');
|
|
226
|
+
await expect(managementDataProvider.GetUserProfile()).rejects.toThrow('User profile API call failed');
|
|
227
227
|
|
|
228
228
|
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
229
229
|
`${mockOrgUrl}_api/_common/GetUserProfile?__v=5`,
|
|
@@ -245,6 +245,7 @@ describe('MangementDataProvider', () => {
|
|
|
245
245
|
expect(provider.token).toBe(customToken);
|
|
246
246
|
});
|
|
247
247
|
});
|
|
248
|
+
|
|
248
249
|
describe('MangementDataProvider - Additional Tests', () => {
|
|
249
250
|
let managementDataProvider: MangementDataProvider;
|
|
250
251
|
const mockOrgUrl = 'https://dev.azure.com/organization/';
|
|
@@ -260,7 +261,7 @@ describe('MangementDataProvider - Additional Tests', () => {
|
|
|
260
261
|
// Arrange
|
|
261
262
|
const mockEmptyProjects = {
|
|
262
263
|
count: 0,
|
|
263
|
-
value: []
|
|
264
|
+
value: [],
|
|
264
265
|
};
|
|
265
266
|
jest.spyOn(managementDataProvider, 'GetProjects').mockResolvedValueOnce(mockEmptyProjects);
|
|
266
267
|
|
|
@@ -275,29 +276,27 @@ describe('MangementDataProvider - Additional Tests', () => {
|
|
|
275
276
|
it('should handle projects response with missing value property', async () => {
|
|
276
277
|
// Arrange
|
|
277
278
|
const mockInvalidProjects = {
|
|
278
|
-
count: 0
|
|
279
|
+
count: 0,
|
|
279
280
|
// no value property
|
|
280
281
|
};
|
|
281
282
|
jest.spyOn(managementDataProvider, 'GetProjects').mockResolvedValueOnce(mockInvalidProjects);
|
|
282
283
|
|
|
283
|
-
// Mock
|
|
284
|
-
const
|
|
284
|
+
// Mock logger.error to capture the error
|
|
285
|
+
const loggerErrorSpy = jest.spyOn(logger, 'error');
|
|
285
286
|
|
|
286
287
|
// Act
|
|
287
288
|
const result = await managementDataProvider.GetProjectByName('Any Project');
|
|
288
289
|
|
|
289
290
|
// Assert
|
|
290
291
|
expect(result).toEqual({});
|
|
291
|
-
expect(
|
|
292
|
+
expect(loggerErrorSpy).toHaveBeenCalled();
|
|
292
293
|
});
|
|
293
294
|
|
|
294
295
|
it('should be case sensitive when matching project names', async () => {
|
|
295
296
|
// Arrange
|
|
296
297
|
const mockProjects = {
|
|
297
298
|
count: 1,
|
|
298
|
-
value: [
|
|
299
|
-
{ id: 'project-1', name: 'Project One' }
|
|
300
|
-
]
|
|
299
|
+
value: [{ id: 'project-1', name: 'Project One' }],
|
|
301
300
|
};
|
|
302
301
|
jest.spyOn(managementDataProvider, 'GetProjects').mockResolvedValueOnce(mockProjects);
|
|
303
302
|
|
|
@@ -379,8 +378,8 @@ describe('MangementDataProvider - Additional Tests', () => {
|
|
|
379
378
|
// Contains unexpected fields
|
|
380
379
|
unusualField: 'unusual value',
|
|
381
380
|
nestedData: {
|
|
382
|
-
someProperty: 'some value'
|
|
383
|
-
}
|
|
381
|
+
someProperty: 'some value',
|
|
382
|
+
},
|
|
384
383
|
};
|
|
385
384
|
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(unusualProfileData);
|
|
386
385
|
|
|
@@ -391,4 +390,4 @@ describe('MangementDataProvider - Additional Tests', () => {
|
|
|
391
390
|
expect(result).toEqual(unusualProfileData);
|
|
392
391
|
});
|
|
393
392
|
});
|
|
394
|
-
});
|
|
393
|
+
});
|