@elisra-devops/docgen-data-provider 1.104.0 → 1.106.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.
@@ -27,7 +27,7 @@ describe('TicketsDataProvider', () => {
27
27
  wiql,
28
28
  'Source',
29
29
  [],
30
- new Map()
30
+ new Map(),
31
31
  );
32
32
  expect(result).toBe(true);
33
33
  });
@@ -39,7 +39,7 @@ describe('TicketsDataProvider', () => {
39
39
  wiql,
40
40
  'Source',
41
41
  [],
42
- new Map()
42
+ new Map(),
43
43
  );
44
44
  expect(result).toBe(false);
45
45
  });
@@ -51,7 +51,7 @@ describe('TicketsDataProvider', () => {
51
51
  wiql,
52
52
  'Source',
53
53
  ['Epic', 'Feature'],
54
- new Map()
54
+ new Map(),
55
55
  );
56
56
  expect(result).toBe(false);
57
57
  });
@@ -63,7 +63,7 @@ describe('TicketsDataProvider', () => {
63
63
  wiql,
64
64
  'Target',
65
65
  ['Requirement', 'Bug'],
66
- new Map()
66
+ new Map(),
67
67
  );
68
68
  expect(result).toBe(true);
69
69
  });
@@ -75,7 +75,7 @@ describe('TicketsDataProvider', () => {
75
75
  wiql,
76
76
  'Target',
77
77
  ['Bug'],
78
- new Map()
78
+ new Map(),
79
79
  );
80
80
  expect(result).toBe(false);
81
81
  });
@@ -93,13 +93,98 @@ describe('TicketsDataProvider', () => {
93
93
  });
94
94
  });
95
95
 
96
+ describe('fetchSysRsQueries', () => {
97
+ it('should use sysrs root, exclude trace folders from system requirements and resolve both trace directions', async () => {
98
+ const rootQueries = { id: 'root' };
99
+ const sysRsRoot = { id: 'sysrs-root', name: 'SYSRS' };
100
+ const subsystemToSystemFolder = { id: 'fwd-folder', name: 'System To Customer' };
101
+ const systemToSubsystemFolder = { id: 'rev-folder', name: 'System To Subsystem' };
102
+
103
+ const getDocTypeRootSpy = jest
104
+ .spyOn(ticketsDataProvider as any, 'getDocTypeRoot')
105
+ .mockResolvedValue({ root: sysRsRoot, found: true });
106
+ const fetchSystemRequirementQueriesSpy = jest
107
+ .spyOn(ticketsDataProvider as any, 'fetchSystemRequirementQueries')
108
+ .mockResolvedValue({ systemRequirementsQueryTree: { id: 'system-tree' } });
109
+ const findChildFolderByPossibleNamesSpy = jest
110
+ .spyOn(ticketsDataProvider as any, 'findChildFolderByPossibleNames')
111
+ .mockResolvedValueOnce(subsystemToSystemFolder)
112
+ .mockResolvedValueOnce(systemToSubsystemFolder);
113
+ const fetchRequirementsTraceQueriesForFolderSpy = jest
114
+ .spyOn(ticketsDataProvider as any, 'fetchRequirementsTraceQueriesForFolder')
115
+ .mockResolvedValueOnce({ id: 'fwd-trace-tree' })
116
+ .mockResolvedValueOnce({ id: 'rev-trace-tree' });
117
+
118
+ const result = await (ticketsDataProvider as any).fetchSysRsQueries(rootQueries);
119
+
120
+ expect(getDocTypeRootSpy).toHaveBeenCalledWith(rootQueries, 'sysrs');
121
+ expect(fetchSystemRequirementQueriesSpy).toHaveBeenCalledWith(sysRsRoot, [
122
+ 'System To Customer',
123
+ 'System To Subsystem',
124
+ ]);
125
+
126
+ expect(findChildFolderByPossibleNamesSpy).toHaveBeenNthCalledWith(
127
+ 1,
128
+ sysRsRoot,
129
+ expect.arrayContaining(['system to customer', 'subsystem to system', 'customer to system']),
130
+ );
131
+ expect(findChildFolderByPossibleNamesSpy).toHaveBeenNthCalledWith(
132
+ 2,
133
+ sysRsRoot,
134
+ expect.arrayContaining(['system to subsystem', 'system-to-subsystem']),
135
+ );
136
+
137
+ expect(fetchRequirementsTraceQueriesForFolderSpy).toHaveBeenNthCalledWith(1, subsystemToSystemFolder);
138
+ expect(fetchRequirementsTraceQueriesForFolderSpy).toHaveBeenNthCalledWith(2, systemToSubsystemFolder);
139
+
140
+ expect(result).toEqual({
141
+ systemRequirementsQueries: { systemRequirementsQueryTree: { id: 'system-tree' } },
142
+ subsystemToSystemRequirementsQueries: { id: 'fwd-trace-tree' },
143
+ systemToSubsystemRequirementsQueries: { id: 'rev-trace-tree' },
144
+ });
145
+ });
146
+
147
+ it('should fall back to root queries and return null trace trees when trace folders are missing', async () => {
148
+ const rootQueries = { id: 'root' };
149
+
150
+ jest
151
+ .spyOn(ticketsDataProvider as any, 'getDocTypeRoot')
152
+ .mockResolvedValue({ root: rootQueries, found: false });
153
+ const fetchSystemRequirementQueriesSpy = jest
154
+ .spyOn(ticketsDataProvider as any, 'fetchSystemRequirementQueries')
155
+ .mockResolvedValue({ systemRequirementsQueryTree: { id: 'system-tree' } });
156
+ jest
157
+ .spyOn(ticketsDataProvider as any, 'findChildFolderByPossibleNames')
158
+ .mockResolvedValueOnce(null)
159
+ .mockResolvedValueOnce(null);
160
+ const fetchRequirementsTraceQueriesForFolderSpy = jest
161
+ .spyOn(ticketsDataProvider as any, 'fetchRequirementsTraceQueriesForFolder')
162
+ .mockResolvedValueOnce(null)
163
+ .mockResolvedValueOnce(null);
164
+
165
+ const result = await (ticketsDataProvider as any).fetchSysRsQueries(rootQueries);
166
+
167
+ expect(fetchSystemRequirementQueriesSpy).toHaveBeenCalledWith(rootQueries, [
168
+ 'System To Customer',
169
+ 'System To Subsystem',
170
+ ]);
171
+ expect(fetchRequirementsTraceQueriesForFolderSpy).toHaveBeenNthCalledWith(1, null);
172
+ expect(fetchRequirementsTraceQueriesForFolderSpy).toHaveBeenNthCalledWith(2, null);
173
+ expect(result).toEqual({
174
+ systemRequirementsQueries: { systemRequirementsQueryTree: { id: 'system-tree' } },
175
+ subsystemToSystemRequirementsQueries: null,
176
+ systemToSubsystemRequirementsQueries: null,
177
+ });
178
+ });
179
+ });
180
+
96
181
  describe('findChildFolderByPossibleNames', () => {
97
182
  it('should return null when parent is missing or possibleNames is empty', async () => {
98
183
  await expect(
99
- (ticketsDataProvider as any).findChildFolderByPossibleNames(null, ['a'])
184
+ (ticketsDataProvider as any).findChildFolderByPossibleNames(null, ['a']),
100
185
  ).resolves.toBeNull();
101
186
  await expect(
102
- (ticketsDataProvider as any).findChildFolderByPossibleNames({ hasChildren: false }, [])
187
+ (ticketsDataProvider as any).findChildFolderByPossibleNames({ hasChildren: false }, []),
103
188
  ).resolves.toBeNull();
104
189
  });
105
190
 
@@ -194,7 +279,7 @@ describe('TicketsDataProvider', () => {
194
279
  starting,
195
280
  fetcher,
196
281
  'ctx',
197
- validator
282
+ validator,
198
283
  );
199
284
  expect(res.usedFolder).toBe(starting);
200
285
  expect(fetcher).toHaveBeenCalledTimes(1);
@@ -221,7 +306,7 @@ describe('TicketsDataProvider', () => {
221
306
  a,
222
307
  fetcher,
223
308
  'ctx',
224
- validator
309
+ validator,
225
310
  );
226
311
  expect(res.usedFolder).toBe(root);
227
312
  expect(res.result).toEqual({ last: true });
@@ -258,7 +343,7 @@ describe('TicketsDataProvider', () => {
258
343
  // Assert
259
344
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
260
345
  `${mockOrgUrl}${mockProject}/_apis/wit/workitems/${mockId}?$expand=All`,
261
- mockToken
346
+ mockToken,
262
347
  );
263
348
  expect(result).toEqual(mockWorkItem);
264
349
  });
@@ -325,7 +410,7 @@ describe('TicketsDataProvider', () => {
325
410
  // Assert
326
411
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
327
412
  `${mockOrgUrl}${mockProject}/_apis/wit/queries/Shared%20Queries?$depth=2&$expand=all`,
328
- mockToken
413
+ mockToken,
329
414
  );
330
415
  expect(result).toEqual({
331
416
  reqTestQueries: { reqTestTree: {}, testReqTree: {} },
@@ -358,7 +443,7 @@ describe('TicketsDataProvider', () => {
358
443
  // Assert
359
444
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
360
445
  `${mockOrgUrl}${mockProject}/_apis/wit/queries/${mockPath}?$depth=2&$expand=all`,
361
- mockToken
446
+ mockToken,
362
447
  );
363
448
  expect(result).toEqual({
364
449
  systemOverviewQueryTree: {},
@@ -564,8 +649,8 @@ describe('TicketsDataProvider', () => {
564
649
  await expect(
565
650
  (ticketsDataProvider as any).parseDirectLinkedQueryResultForTableFormat(
566
651
  { columns: [], workItemRelations: [], queryType: QueryType.OneHop } as any,
567
- new Map()
568
- )
652
+ new Map(),
653
+ ),
569
654
  ).rejects.toThrow('No related work items were found');
570
655
  });
571
656
 
@@ -600,7 +685,7 @@ describe('TicketsDataProvider', () => {
600
685
  columns: [{ referenceName: 'CustomerRequirementId', name: 'CustomerRequirementId' }],
601
686
  workItemRelations,
602
687
  } as any,
603
- testCaseToRelatedWiMap
688
+ testCaseToRelatedWiMap,
604
689
  );
605
690
 
606
691
  expect(fetchSpy).toHaveBeenCalled();
@@ -627,8 +712,8 @@ describe('TicketsDataProvider', () => {
627
712
  columns: [],
628
713
  workItemRelations: [{ source: { id: 1 }, target: null }],
629
714
  } as any,
630
- new Map()
631
- )
715
+ new Map(),
716
+ ),
632
717
  ).rejects.toThrow('Target relation is missing');
633
718
  });
634
719
  });
@@ -646,7 +731,7 @@ describe('TicketsDataProvider', () => {
646
731
  {},
647
732
  wiql,
648
733
  ['Bug'],
649
- new Map()
734
+ new Map(),
650
735
  );
651
736
  expect(res).toBe(false);
652
737
  });
@@ -657,7 +742,7 @@ describe('TicketsDataProvider', () => {
657
742
  {},
658
743
  wiql,
659
744
  ['Bug'],
660
- new Map()
745
+ new Map(),
661
746
  );
662
747
  expect(res).toBe(false);
663
748
  });
@@ -710,7 +795,7 @@ describe('TicketsDataProvider', () => {
710
795
  const resultedRefNameMap = new Map<string, string>();
711
796
 
712
797
  expect(() =>
713
- (ticketsDataProvider as any).filterFieldsByColumns(item, columnsToFilterMap, resultedRefNameMap)
798
+ (ticketsDataProvider as any).filterFieldsByColumns(item, columnsToFilterMap, resultedRefNameMap),
714
799
  ).toThrow();
715
800
  expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('Cannot filter columns'));
716
801
  });
@@ -747,7 +832,7 @@ describe('TicketsDataProvider', () => {
747
832
  expect.objectContaining({
748
833
  name: 'Bug',
749
834
  icon: expect.objectContaining({ dataUrl: 'data:image/png;base64,xxx' }),
750
- })
835
+ }),
751
836
  );
752
837
  expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('Failed to download icon'));
753
838
  });
@@ -830,7 +915,7 @@ describe('TicketsDataProvider', () => {
830
915
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
831
916
  `${mockOrgUrl}${mockProject}/${mockTeamName}/_apis/work/teamsettings/iterations`,
832
917
  mockToken,
833
- 'get'
918
+ 'get',
834
919
  );
835
920
  expect(result).toEqual(mockIterations);
836
921
  });
@@ -849,7 +934,7 @@ describe('TicketsDataProvider', () => {
849
934
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
850
935
  `${mockOrgUrl}${mockProject}/_apis/work/teamsettings/iterations`,
851
936
  mockToken,
852
- 'get'
937
+ 'get',
853
938
  );
854
939
  expect(result).toEqual(mockIterations);
855
940
  });
@@ -870,7 +955,7 @@ describe('TicketsDataProvider', () => {
870
955
  mockProject,
871
956
  mockWiBody,
872
957
  mockWiType,
873
- mockByPass
958
+ mockByPass,
874
959
  );
875
960
 
876
961
  // Assert
@@ -881,7 +966,7 @@ describe('TicketsDataProvider', () => {
881
966
  mockWiBody,
882
967
  {
883
968
  'Content-Type': 'application/json-patch+json',
884
- }
969
+ },
885
970
  );
886
971
  expect(result).toEqual(mockResponse);
887
972
  });
@@ -902,7 +987,7 @@ describe('TicketsDataProvider', () => {
902
987
  mockProject,
903
988
  mockWiBody,
904
989
  mockWorkItemId,
905
- mockByPass
990
+ mockByPass,
906
991
  );
907
992
 
908
993
  // Assert
@@ -913,7 +998,7 @@ describe('TicketsDataProvider', () => {
913
998
  mockWiBody,
914
999
  {
915
1000
  'Content-Type': 'application/json-patch+json',
916
- }
1001
+ },
917
1002
  );
918
1003
  expect(result).toEqual(mockResponse);
919
1004
  });
@@ -943,7 +1028,7 @@ describe('TicketsDataProvider', () => {
943
1028
  // Assert
944
1029
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
945
1030
  `${mockOrgUrl}${mockProject}/_apis/wit/workitems/${mockId}?$expand=All`,
946
- mockToken
1031
+ mockToken,
947
1032
  );
948
1033
  expect(result.length).toBe(1);
949
1034
 
@@ -1008,7 +1093,7 @@ describe('TicketsDataProvider', () => {
1008
1093
  // Assert
1009
1094
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
1010
1095
  `${mockOrgUrl}${mockProject}/_apis/wit/workitems/${mockId}?$expand=All`,
1011
- mockToken
1096
+ mockToken,
1012
1097
  );
1013
1098
  expect(result.length).toBe(1);
1014
1099
  expect(result[0].rel).toBe('AttachedFile');
@@ -1156,7 +1241,7 @@ describe('TicketsDataProvider', () => {
1156
1241
  // Assert
1157
1242
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
1158
1243
  `${mockOrgUrl}${mockProject}/_apis/wit/workitemtypes/${mockItemType}/fields`,
1159
- mockToken
1244
+ mockToken,
1160
1245
  );
1161
1246
  // Should filter out ID and Title
1162
1247
  expect(result).toHaveLength(2);
@@ -1254,7 +1339,7 @@ describe('TicketsDataProvider', () => {
1254
1339
  const res = await ticketsDataProvider.GetQueryResultsFromWiql(
1255
1340
  'https://example.com/wiql',
1256
1341
  false,
1257
- new Map()
1342
+ new Map(),
1258
1343
  );
1259
1344
  expect(res).toBeUndefined();
1260
1345
  });
@@ -1407,7 +1492,7 @@ describe('TicketsDataProvider', () => {
1407
1492
  undefined,
1408
1493
  false,
1409
1494
  ['skipme'],
1410
- false
1495
+ false,
1411
1496
  );
1412
1497
  expect(res).toEqual({ tree1: null, tree2: null });
1413
1498
  });
@@ -1438,12 +1523,12 @@ describe('TicketsDataProvider', () => {
1438
1523
  false,
1439
1524
  null,
1440
1525
  ['Epic'],
1441
- ['Feature']
1526
+ ['Feature'],
1442
1527
  );
1443
1528
 
1444
1529
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
1445
1530
  'https://example.com/q?$depth=2&$expand=all',
1446
- mockToken
1531
+ mockToken,
1447
1532
  );
1448
1533
  expect(res.tree1).toEqual({ id: 'root', pId: 'root' });
1449
1534
  expect(res.tree2).toBeNull();
@@ -1466,7 +1551,7 @@ describe('TicketsDataProvider', () => {
1466
1551
  'missing',
1467
1552
  false,
1468
1553
  [],
1469
- true
1554
+ true,
1470
1555
  );
1471
1556
 
1472
1557
  expect(res.tree1).toEqual({ id: 'q', pId: null });
@@ -1489,7 +1574,7 @@ describe('TicketsDataProvider', () => {
1489
1574
  false,
1490
1575
  null,
1491
1576
  ['Epic'],
1492
- ['Feature']
1577
+ ['Feature'],
1493
1578
  );
1494
1579
 
1495
1580
  expect(res.tree1).toBeNull();
@@ -1534,7 +1619,7 @@ describe('TicketsDataProvider', () => {
1534
1619
  [],
1535
1620
  undefined,
1536
1621
  undefined,
1537
- true
1622
+ true,
1538
1623
  );
1539
1624
 
1540
1625
  expect(res.tree1).not.toBeNull();
@@ -1564,7 +1649,7 @@ describe('TicketsDataProvider', () => {
1564
1649
  [],
1565
1650
  undefined,
1566
1651
  undefined,
1567
- true
1652
+ true,
1568
1653
  );
1569
1654
 
1570
1655
  expect(res.tree1).toBeNull();
@@ -1591,7 +1676,7 @@ describe('TicketsDataProvider', () => {
1591
1676
  false,
1592
1677
  null,
1593
1678
  allowedTypes,
1594
- allowedTypes
1679
+ allowedTypes,
1595
1680
  );
1596
1681
 
1597
1682
  expect(res.tree1).not.toBeNull();
@@ -1622,7 +1707,7 @@ describe('TicketsDataProvider', () => {
1622
1707
  undefined,
1623
1708
  false,
1624
1709
  [],
1625
- true
1710
+ true,
1626
1711
  );
1627
1712
 
1628
1713
  expect(res.tree1).not.toBeNull();
@@ -1647,7 +1732,7 @@ describe('TicketsDataProvider', () => {
1647
1732
  [],
1648
1733
  undefined,
1649
1734
  undefined,
1650
- true
1735
+ true,
1651
1736
  );
1652
1737
 
1653
1738
  expect(res.tree1).toBeNull();
@@ -1719,7 +1804,7 @@ describe('TicketsDataProvider', () => {
1719
1804
 
1720
1805
  expect(TFSServices.getItemContent).toHaveBeenCalledWith(
1721
1806
  'https://example.com/q3?$depth=2&$expand=all',
1722
- mockToken
1807
+ mockToken,
1723
1808
  );
1724
1809
  expect(res.tree1).toEqual(expect.objectContaining({ id: 'q3', pId: 'q3' }));
1725
1810
  });
@@ -1809,6 +1894,70 @@ describe('TicketsDataProvider', () => {
1809
1894
  });
1810
1895
  });
1811
1896
 
1897
+ describe('init query result items', () => {
1898
+ it('should include fields and workItemType in tree query item mapping', async () => {
1899
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce({
1900
+ fields: {
1901
+ 'System.Title': 'REQ-42',
1902
+ 'Microsoft.VSTS.CMMI.Symptom': 'Symptom description',
1903
+ 'System.Description': 'Fallback description',
1904
+ 'System.WorkItemType': 'Requirement',
1905
+ },
1906
+ _links: { html: { href: 'https://example.com/wi/42' } },
1907
+ });
1908
+
1909
+ const allItems: Record<number, any> = {};
1910
+ await (ticketsDataProvider as any).initTreeQueryResultItem(
1911
+ { id: 42, url: 'https://example.com/wi/42' },
1912
+ allItems,
1913
+ );
1914
+
1915
+ expect(allItems[42]).toEqual(
1916
+ expect.objectContaining({
1917
+ id: 42,
1918
+ title: 'REQ-42',
1919
+ description: 'Symptom description',
1920
+ htmlUrl: 'https://example.com/wi/42',
1921
+ fields: expect.objectContaining({
1922
+ 'System.WorkItemType': 'Requirement',
1923
+ }),
1924
+ workItemType: 'Requirement',
1925
+ children: [],
1926
+ }),
1927
+ );
1928
+ });
1929
+
1930
+ it('should include fields and fallback description in flat query item mapping', async () => {
1931
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce({
1932
+ fields: {
1933
+ 'System.Title': 'REQ-84',
1934
+ 'System.Description': 'System description',
1935
+ 'System.WorkItemType': 'Feature',
1936
+ },
1937
+ _links: { html: { href: 'https://example.com/wi/84' } },
1938
+ });
1939
+
1940
+ const workItemMap = new Map<number, any>();
1941
+ await (ticketsDataProvider as any).initFlatQueryResultItem(
1942
+ { id: 84, url: 'https://example.com/wi/84' },
1943
+ workItemMap,
1944
+ );
1945
+
1946
+ expect(workItemMap.get(84)).toEqual(
1947
+ expect.objectContaining({
1948
+ id: 84,
1949
+ title: 'REQ-84',
1950
+ description: 'System description',
1951
+ htmlUrl: 'https://example.com/wi/84',
1952
+ fields: expect.objectContaining({
1953
+ 'System.WorkItemType': 'Feature',
1954
+ }),
1955
+ workItemType: 'Feature',
1956
+ }),
1957
+ );
1958
+ });
1959
+ });
1960
+
1812
1961
  describe('GetQueryResultsByWiqlHref', () => {
1813
1962
  it('should fetch and model query results', async () => {
1814
1963
  // Arrange
@@ -1848,6 +1997,81 @@ describe('TicketsDataProvider', () => {
1848
1997
  });
1849
1998
 
1850
1999
  describe('GetSharedQueries - docType branches', () => {
2000
+ it('should handle STP docType', async () => {
2001
+ // Arrange
2002
+ const mockQueries = {
2003
+ children: [{ name: 'STP', isFolder: true, children: [] }],
2004
+ };
2005
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValue(mockQueries);
2006
+
2007
+ // Act
2008
+ const result = await ticketsDataProvider.GetSharedQueries(mockProject, '', 'stp');
2009
+
2010
+ // Assert
2011
+ expect(result).toBeDefined();
2012
+ });
2013
+
2014
+ it('should fallback to STD root when STP root is missing', async () => {
2015
+ const rootQueries = { id: 'root', children: [] };
2016
+ const stdRoot = { id: 'std-root', children: [] };
2017
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValue(rootQueries);
2018
+
2019
+ const getDocTypeRootSpy = jest
2020
+ .spyOn(ticketsDataProvider as any, 'getDocTypeRoot')
2021
+ .mockImplementation(async (...args: any[]) => {
2022
+ const docTypeName = String(args[1] || '');
2023
+ if (docTypeName === 'stp') return { root: rootQueries, found: false };
2024
+ if (docTypeName === 'std') return { root: stdRoot, found: true };
2025
+ return { root: rootQueries, found: false };
2026
+ });
2027
+
2028
+ const fetchDocTypeBranchesSpy = jest
2029
+ .spyOn(ticketsDataProvider as any, 'fetchDocTypeBranches')
2030
+ .mockResolvedValue({
2031
+ reqToTest: { result: { reqTestTree: { id: 'req-tree' }, testReqTree: { id: 'fallback-tree' } } },
2032
+ testToReq: { result: { testReqTree: { id: 'test-tree' } } },
2033
+ mom: { result: { linkedMomTree: { id: 'mom-tree' } } },
2034
+ });
2035
+
2036
+ const result = await ticketsDataProvider.GetSharedQueries(mockProject, '', 'stp');
2037
+
2038
+ expect(getDocTypeRootSpy).toHaveBeenNthCalledWith(1, rootQueries, 'stp');
2039
+ expect(getDocTypeRootSpy).toHaveBeenNthCalledWith(2, rootQueries, 'std');
2040
+ expect(fetchDocTypeBranchesSpy).toHaveBeenCalledWith(rootQueries, stdRoot, expect.any(Array));
2041
+ expect(result.reqTestQueries.reqTestTree).toEqual({ id: 'req-tree' });
2042
+ expect(result.reqTestQueries.testReqTree).toEqual({ id: 'test-tree' });
2043
+ expect(result.linkedMomQueries.linkedMomTree).toEqual({ id: 'mom-tree' });
2044
+ });
2045
+
2046
+ it('should prefer STP root over STD when both exist', async () => {
2047
+ const rootQueries = { id: 'root', children: [] };
2048
+ const stpRoot = { id: 'stp-root', children: [] };
2049
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValue(rootQueries);
2050
+
2051
+ const getDocTypeRootSpy = jest
2052
+ .spyOn(ticketsDataProvider as any, 'getDocTypeRoot')
2053
+ .mockImplementation(async (...args: any[]) => {
2054
+ const docTypeName = String(args[1] || '');
2055
+ if (docTypeName === 'stp') return { root: stpRoot, found: true };
2056
+ if (docTypeName === 'std') return { root: { id: 'std-root', children: [] }, found: true };
2057
+ return { root: rootQueries, found: false };
2058
+ });
2059
+
2060
+ const fetchDocTypeBranchesSpy = jest
2061
+ .spyOn(ticketsDataProvider as any, 'fetchDocTypeBranches')
2062
+ .mockResolvedValue({
2063
+ reqToTest: { result: { reqTestTree: { id: 'req-tree' }, testReqTree: null } },
2064
+ testToReq: { result: { testReqTree: { id: 'test-tree' } } },
2065
+ mom: { result: { linkedMomTree: null } },
2066
+ });
2067
+
2068
+ await ticketsDataProvider.GetSharedQueries(mockProject, '', 'stp');
2069
+
2070
+ expect(getDocTypeRootSpy).toHaveBeenCalledTimes(1);
2071
+ expect(getDocTypeRootSpy).toHaveBeenCalledWith(rootQueries, 'stp');
2072
+ expect(fetchDocTypeBranchesSpy).toHaveBeenCalledWith(rootQueries, stpRoot, expect.any(Array));
2073
+ });
2074
+
1851
2075
  it('should handle STR docType', async () => {
1852
2076
  // Arrange
1853
2077
  const mockQueries = {
@@ -1890,6 +2114,23 @@ describe('TicketsDataProvider', () => {
1890
2114
  expect(result).toBeDefined();
1891
2115
  });
1892
2116
 
2117
+ it('should handle SYSRS docType', async () => {
2118
+ // Arrange
2119
+ const mockQueries = {
2120
+ children: [{ name: 'SYSRS', isFolder: true, children: [] }],
2121
+ };
2122
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValue(mockQueries);
2123
+
2124
+ // Act
2125
+ const result = await ticketsDataProvider.GetSharedQueries(mockProject, '', 'sysrs');
2126
+
2127
+ // Assert
2128
+ expect(result).toBeDefined();
2129
+ expect(result).toHaveProperty('systemRequirementsQueries');
2130
+ expect(result).toHaveProperty('subsystemToSystemRequirementsQueries');
2131
+ expect(result).toHaveProperty('systemToSubsystemRequirementsQueries');
2132
+ });
2133
+
1893
2134
  it('should handle unknown docType', async () => {
1894
2135
  // Arrange
1895
2136
  const mockQueries = { children: [] };
@@ -2195,7 +2436,7 @@ describe('TicketsDataProvider', () => {
2195
2436
  const res = await ticketsDataProvider.GetCategorizedRequirementsByType(wiqlHref);
2196
2437
  expect(res).toEqual({ categories: {}, totalCount: 0 });
2197
2438
  expect(logger.warn).toHaveBeenCalledWith(
2198
- expect.stringContaining('No work items found in query result')
2439
+ expect.stringContaining('No work items found in query result'),
2199
2440
  );
2200
2441
  });
2201
2442
  });