@elisra-devops/docgen-data-provider 1.136.3 → 1.136.5
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/ResultDataProvider.js +4 -1
- package/bin/modules/ResultDataProvider.js.map +1 -1
- package/bin/modules/TicketsDataProvider.d.ts +2 -0
- package/bin/modules/TicketsDataProvider.js +45 -4
- package/bin/modules/TicketsDataProvider.js.map +1 -1
- package/bin/tests/modules/ResultDataProvider.test.js +69 -0
- package/bin/tests/modules/ResultDataProvider.test.js.map +1 -1
- package/bin/tests/modules/ticketsDataProvider.test.js +66 -0
- package/bin/tests/modules/ticketsDataProvider.test.js.map +1 -1
- package/package.json +1 -1
- package/src/modules/ResultDataProvider.ts +6 -1
- package/src/modules/TicketsDataProvider.ts +46 -4
- package/src/tests/modules/ResultDataProvider.test.ts +115 -0
- package/src/tests/modules/ticketsDataProvider.test.ts +77 -0
|
@@ -4300,6 +4300,32 @@ describe('ResultDataProvider', () => {
|
|
|
4300
4300
|
|
|
4301
4301
|
expect(res.testCaseResult).toEqual(expect.objectContaining({ url: '' }));
|
|
4302
4302
|
});
|
|
4303
|
+
|
|
4304
|
+
it('should pass latest test case properties flag to the point result fetch', async () => {
|
|
4305
|
+
const fetchResultDataBaseSpy = jest
|
|
4306
|
+
.spyOn(resultDataProvider as any, 'fetchResultDataBase')
|
|
4307
|
+
.mockResolvedValue({});
|
|
4308
|
+
|
|
4309
|
+
await (resultDataProvider as any).fetchResultDataForTestReporter(
|
|
4310
|
+
mockProjectName,
|
|
4311
|
+
'suite1',
|
|
4312
|
+
{ lastRunId: 456, lastResultId: 789, testCaseId: 123 },
|
|
4313
|
+
['Custom.SortIndex@testCaseWorkItemField'],
|
|
4314
|
+
false,
|
|
4315
|
+
false,
|
|
4316
|
+
false,
|
|
4317
|
+
true
|
|
4318
|
+
);
|
|
4319
|
+
|
|
4320
|
+
expect(fetchResultDataBaseSpy.mock.calls[0][5]).toEqual([
|
|
4321
|
+
['Custom.SortIndex@testCaseWorkItemField'],
|
|
4322
|
+
false,
|
|
4323
|
+
{ lastRunId: 456, lastResultId: 789, testCaseId: 123 },
|
|
4324
|
+
false,
|
|
4325
|
+
false,
|
|
4326
|
+
true,
|
|
4327
|
+
]);
|
|
4328
|
+
});
|
|
4303
4329
|
});
|
|
4304
4330
|
|
|
4305
4331
|
describe('fetchResultDataBasedOnWiBase', () => {
|
|
@@ -4352,6 +4378,95 @@ describe('ResultDataProvider', () => {
|
|
|
4352
4378
|
);
|
|
4353
4379
|
});
|
|
4354
4380
|
|
|
4381
|
+
it('should use latest test case fields for executed points when latest properties mode is enabled', async () => {
|
|
4382
|
+
const point = {
|
|
4383
|
+
testCaseId: '123',
|
|
4384
|
+
testCaseName: 'TC 123',
|
|
4385
|
+
outcome: 'passed',
|
|
4386
|
+
lastRunId: 456,
|
|
4387
|
+
lastResultId: 789,
|
|
4388
|
+
testSuite: { id: '1', name: 'Suite' },
|
|
4389
|
+
};
|
|
4390
|
+
|
|
4391
|
+
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce({
|
|
4392
|
+
id: 123,
|
|
4393
|
+
rev: 10,
|
|
4394
|
+
fields: {
|
|
4395
|
+
'System.State': 'Active',
|
|
4396
|
+
'System.CreatedDate': '2024-01-01T00:00:00',
|
|
4397
|
+
'Microsoft.VSTS.TCM.Priority': 1,
|
|
4398
|
+
'Custom.SortIndex': 3,
|
|
4399
|
+
'Microsoft.VSTS.TCM.Steps': '<steps></steps>',
|
|
4400
|
+
},
|
|
4401
|
+
relations: null,
|
|
4402
|
+
});
|
|
4403
|
+
|
|
4404
|
+
const selectedFields = ['Custom.SortIndex@testCaseWorkItemField'];
|
|
4405
|
+
const res = await (resultDataProvider as any).fetchResultDataBasedOnWiBase(
|
|
4406
|
+
mockProjectName,
|
|
4407
|
+
'456',
|
|
4408
|
+
'789',
|
|
4409
|
+
true,
|
|
4410
|
+
selectedFields,
|
|
4411
|
+
false,
|
|
4412
|
+
point,
|
|
4413
|
+
false,
|
|
4414
|
+
false,
|
|
4415
|
+
true
|
|
4416
|
+
);
|
|
4417
|
+
|
|
4418
|
+
const calledUrls = (TFSServices.getItemContent as jest.Mock).mock.calls.map((args: any[]) => String(args[0]));
|
|
4419
|
+
expect(calledUrls.some((url: string) => url.includes('/_apis/test/runs/456/results/789'))).toBe(false);
|
|
4420
|
+
expect(calledUrls.some((url: string) => url.includes('/_apis/wit/workItems/123?$expand=all'))).toBe(true);
|
|
4421
|
+
expect(res).toEqual(
|
|
4422
|
+
expect.objectContaining({
|
|
4423
|
+
testCaseRevision: 10,
|
|
4424
|
+
filteredFields: { 'Custom.SortIndex': 3 },
|
|
4425
|
+
})
|
|
4426
|
+
);
|
|
4427
|
+
});
|
|
4428
|
+
|
|
4429
|
+
it('should log latest properties mode when bypassing run revision data', async () => {
|
|
4430
|
+
const point = {
|
|
4431
|
+
testCaseId: '123',
|
|
4432
|
+
testCaseName: 'TC 123',
|
|
4433
|
+
outcome: 'passed',
|
|
4434
|
+
lastRunId: 456,
|
|
4435
|
+
lastResultId: 789,
|
|
4436
|
+
testSuite: { id: '1', name: 'Suite' },
|
|
4437
|
+
};
|
|
4438
|
+
|
|
4439
|
+
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce({
|
|
4440
|
+
id: 123,
|
|
4441
|
+
rev: 10,
|
|
4442
|
+
fields: {
|
|
4443
|
+
'System.State': 'Active',
|
|
4444
|
+
'System.CreatedDate': '2024-01-01T00:00:00',
|
|
4445
|
+
'Microsoft.VSTS.TCM.Priority': 1,
|
|
4446
|
+
'Custom.SortIndex': 3,
|
|
4447
|
+
'Microsoft.VSTS.TCM.Steps': '<steps></steps>',
|
|
4448
|
+
},
|
|
4449
|
+
relations: null,
|
|
4450
|
+
});
|
|
4451
|
+
|
|
4452
|
+
await (resultDataProvider as any).fetchResultDataBasedOnWiBase(
|
|
4453
|
+
mockProjectName,
|
|
4454
|
+
'456',
|
|
4455
|
+
'789',
|
|
4456
|
+
true,
|
|
4457
|
+
['Custom.SortIndex@testCaseWorkItemField'],
|
|
4458
|
+
false,
|
|
4459
|
+
point,
|
|
4460
|
+
false,
|
|
4461
|
+
false,
|
|
4462
|
+
true
|
|
4463
|
+
);
|
|
4464
|
+
|
|
4465
|
+
expect(logger.debug).toHaveBeenCalledWith(
|
|
4466
|
+
expect.stringContaining('[TestReporter][LatestProperties] Fetching latest test case work item')
|
|
4467
|
+
);
|
|
4468
|
+
});
|
|
4469
|
+
|
|
4355
4470
|
it('should fetch no-run test case by suite test-case revision when provided', async () => {
|
|
4356
4471
|
const point = {
|
|
4357
4472
|
testCaseId: '123',
|
|
@@ -911,6 +911,44 @@ describe('TicketsDataProvider', () => {
|
|
|
911
911
|
),
|
|
912
912
|
).rejects.toThrow('Target relation is missing');
|
|
913
913
|
});
|
|
914
|
+
|
|
915
|
+
it('should order sourceTargetsMap by the query sortColumns (Node Name asc, Customer ID asc)', async () => {
|
|
916
|
+
// Root work items arrive in relation order 1, 2, 3 — sortColumns should reorder them
|
|
917
|
+
// by System.NodeName then CustomerRequirementId regardless of fetch order.
|
|
918
|
+
const rootFieldsById: Record<number, any> = {
|
|
919
|
+
1: { 'System.WorkItemType': 'Requirement', 'System.NodeName': 'B', CustomerRequirementId: 'C-20' },
|
|
920
|
+
2: { 'System.WorkItemType': 'Requirement', 'System.NodeName': 'A', CustomerRequirementId: 'C-10' },
|
|
921
|
+
3: { 'System.WorkItemType': 'Requirement', 'System.NodeName': 'A', CustomerRequirementId: 'C-5' },
|
|
922
|
+
};
|
|
923
|
+
jest
|
|
924
|
+
.spyOn(ticketsDataProvider as any, 'fetchWIForQueryResult')
|
|
925
|
+
.mockImplementation(async (...args: any[]) => {
|
|
926
|
+
const rel = args[0];
|
|
927
|
+
const id = rel?.target?.id ?? rel?.source?.id;
|
|
928
|
+
return { id, fields: rootFieldsById[id] };
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
const res = await (ticketsDataProvider as any).parseDirectLinkedQueryResultForTableFormat(
|
|
932
|
+
{
|
|
933
|
+
queryType: QueryType.OneHop,
|
|
934
|
+
columns: [],
|
|
935
|
+
sortColumns: [
|
|
936
|
+
{ field: { referenceName: 'System.NodeName' }, descending: false },
|
|
937
|
+
{ field: { referenceName: 'CustomerRequirementId' }, descending: false },
|
|
938
|
+
],
|
|
939
|
+
workItemRelations: [
|
|
940
|
+
{ source: null, target: { id: 1 } },
|
|
941
|
+
{ source: null, target: { id: 2 } },
|
|
942
|
+
{ source: null, target: { id: 3 } },
|
|
943
|
+
],
|
|
944
|
+
} as any,
|
|
945
|
+
new Map(),
|
|
946
|
+
);
|
|
947
|
+
|
|
948
|
+
const orderedIds = Array.from(res.sourceTargetsMap.keys()).map((k: any) => k.id);
|
|
949
|
+
// Expect Node Name A-group (ids 3,2 sorted by Customer ID 5 then 10) before Node Name B (id 1)
|
|
950
|
+
expect(orderedIds).toEqual([3, 2, 1]);
|
|
951
|
+
});
|
|
914
952
|
});
|
|
915
953
|
|
|
916
954
|
describe('fetchWIForQueryResult', () => {
|
|
@@ -952,6 +990,45 @@ describe('TicketsDataProvider', () => {
|
|
|
952
990
|
});
|
|
953
991
|
});
|
|
954
992
|
|
|
993
|
+
describe('parseFlatQueryResultForTableFormat', () => {
|
|
994
|
+
it('should order fetchedWorkItems by the query sortColumns (Node Name asc, Customer ID asc)', async () => {
|
|
995
|
+
const fieldsById: Record<number, any> = {
|
|
996
|
+
1: { 'System.WorkItemType': 'Requirement', 'System.NodeName': 'B', CustomerRequirementId: 'C-20' },
|
|
997
|
+
2: { 'System.WorkItemType': 'Requirement', 'System.NodeName': 'A', CustomerRequirementId: 'C-10' },
|
|
998
|
+
3: { 'System.WorkItemType': 'Requirement', 'System.NodeName': 'A', CustomerRequirementId: 'C-5' },
|
|
999
|
+
};
|
|
1000
|
+
jest
|
|
1001
|
+
.spyOn(ticketsDataProvider as any, 'fetchWIForQueryResult')
|
|
1002
|
+
.mockImplementation(async (...args: any[]) => {
|
|
1003
|
+
const wi = args[0];
|
|
1004
|
+
return { id: wi.id, fields: fieldsById[wi.id] };
|
|
1005
|
+
});
|
|
1006
|
+
|
|
1007
|
+
const res = await (ticketsDataProvider as any).parseFlatQueryResultForTableFormat({
|
|
1008
|
+
queryType: QueryType.Flat,
|
|
1009
|
+
columns: [{ referenceName: 'CustomerRequirementId', name: 'CustomerRequirementId' }],
|
|
1010
|
+
sortColumns: [
|
|
1011
|
+
{ field: { referenceName: 'System.NodeName' }, descending: false },
|
|
1012
|
+
{ field: { referenceName: 'CustomerRequirementId' }, descending: false },
|
|
1013
|
+
],
|
|
1014
|
+
workItems: [{ id: 1 }, { id: 2 }, { id: 3 }],
|
|
1015
|
+
} as any);
|
|
1016
|
+
|
|
1017
|
+
const orderedIds = res.fetchedWorkItems.map((wi: any) => wi.id);
|
|
1018
|
+
expect(orderedIds).toEqual([3, 2, 1]);
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
it('should throw when workItems is an empty array', async () => {
|
|
1022
|
+
await expect(
|
|
1023
|
+
(ticketsDataProvider as any).parseFlatQueryResultForTableFormat({
|
|
1024
|
+
queryType: QueryType.Flat,
|
|
1025
|
+
columns: [],
|
|
1026
|
+
workItems: [],
|
|
1027
|
+
} as any),
|
|
1028
|
+
).rejects.toThrow('No work items were found');
|
|
1029
|
+
});
|
|
1030
|
+
});
|
|
1031
|
+
|
|
955
1032
|
describe('isFlatQueryAllowedByTypeOrId', () => {
|
|
956
1033
|
it('should accept when allowedTypes is empty and WIQL references [System.WorkItemType]', async () => {
|
|
957
1034
|
const wiql = "SELECT * FROM WorkItems WHERE [System.WorkItemType] = 'Bug'";
|