@elisra-devops/docgen-data-provider 1.92.0 → 1.94.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.
@@ -558,6 +558,25 @@ describe('ResultDataProvider', () => {
558
558
  const result = await resultDataProvider.fetchTestCasesBySuiteId(mockProjectName, mockTestPlanId, mockSuiteId);
559
559
  // Assert
560
560
  expect(result).toEqual(mockTestCases.value);
561
+ expect(tfs_1.TFSServices.getItemContent).toHaveBeenCalledWith(expect.stringContaining(`/_apis/testplan/Plans/${mockTestPlanId}/Suites/${mockSuiteId}/TestCase?witFields=Microsoft.VSTS.TCM.Steps,System.Rev`), mockToken);
562
+ });
563
+ });
564
+ describe('resolveSuiteTestCaseRevision', () => {
565
+ it('should resolve System.Rev from workItemFields', () => {
566
+ const revision = resultDataProvider.resolveSuiteTestCaseRevision({
567
+ workItem: {
568
+ workItemFields: [{ key: 'System.Rev', value: '12' }],
569
+ },
570
+ });
571
+ expect(revision).toBe(12);
572
+ });
573
+ it('should resolve System.Rev case-insensitively from workItem fields map', () => {
574
+ const revision = resultDataProvider.resolveSuiteTestCaseRevision({
575
+ workItem: {
576
+ fields: { 'system.rev': 14 },
577
+ },
578
+ });
579
+ expect(revision).toBe(14);
561
580
  });
562
581
  });
563
582
  describe('mapTestPointForCrossPlans', () => {
@@ -691,7 +710,7 @@ describe('ResultDataProvider', () => {
691
710
  lastResultDetails: { duration: 5, dateCompleted: '2023-01-01', runBy: { displayName: 'User' } },
692
711
  });
693
712
  const result = await resultDataProvider.fetchCrossTestPoints(mockProjectName, [1, 2]);
694
- expect(tfs_1.TFSServices.getItemContent).toHaveBeenCalledWith('https://example.com/points/2?witFields=Microsoft.VSTS.TCM.Steps&includePointDetails=true', mockToken);
713
+ expect(tfs_1.TFSServices.getItemContent).toHaveBeenCalledWith('https://example.com/points/2?witFields=Microsoft.VSTS.TCM.Steps,System.Rev&includePointDetails=true', mockToken);
695
714
  expect(result).toHaveLength(2);
696
715
  const tc1 = result.find((r) => r.testCaseId === 1);
697
716
  expect(tc1.lastResultDetails).toEqual(expect.objectContaining({
@@ -2490,7 +2509,7 @@ describe('ResultDataProvider', () => {
2490
2509
  'Test Case ID': 42,
2491
2510
  'Test Case Title': 'TC-0042',
2492
2511
  'Mentioned but Not Linked': 'Step 3: SR0027',
2493
- 'Linked but Not Mentioned': 'SR0817\nSR0818\nSR0859',
2512
+ 'Linked but Not Mentioned': 'SR0817; SR0818; SR0859',
2494
2513
  'Validation Status': 'Fail',
2495
2514
  }));
2496
2515
  expect(String(result.rows[0]['Mentioned but Not Linked'] || '')).not.toContain('VVRM');
@@ -3220,6 +3239,38 @@ describe('ResultDataProvider', () => {
3220
3239
  expect(calledUrls.some((url) => url.includes('?asOf='))).toBe(false);
3221
3240
  expect(res).toEqual(expect.objectContaining({ testCaseRevision: 9 }));
3222
3241
  });
3242
+ it('should resolve no-run revision from System.Rev in suite test-case fields', async () => {
3243
+ const point = {
3244
+ testCaseId: '321',
3245
+ testCaseName: 'TC 321',
3246
+ outcome: 'Not Run',
3247
+ suiteTestCase: {
3248
+ workItem: {
3249
+ id: 321,
3250
+ workItemFields: [
3251
+ { key: 'System.Rev', value: '13' },
3252
+ { key: 'Microsoft.VSTS.TCM.Steps', value: '<steps></steps>' },
3253
+ ],
3254
+ },
3255
+ },
3256
+ testSuite: { id: '1', name: 'Suite' },
3257
+ };
3258
+ tfs_1.TFSServices.getItemContent.mockResolvedValueOnce({
3259
+ id: 321,
3260
+ rev: 13,
3261
+ fields: {
3262
+ 'System.State': 'Design',
3263
+ 'System.CreatedDate': '2024-05-01T00:00:00',
3264
+ 'Microsoft.VSTS.TCM.Priority': 1,
3265
+ 'System.Title': 'Title 321',
3266
+ 'Microsoft.VSTS.TCM.Steps': '<steps></steps>',
3267
+ },
3268
+ relations: [],
3269
+ });
3270
+ const res = await resultDataProvider.fetchResultDataBasedOnWiBase(mockProjectName, '0', '0', true, [], false, point);
3271
+ expect(tfs_1.TFSServices.getItemContent).toHaveBeenCalledWith(expect.stringContaining('/_apis/wit/workItems/321/revisions/13?$expand=all'), mockToken);
3272
+ expect(res).toEqual(expect.objectContaining({ testCaseRevision: 13 }));
3273
+ });
3223
3274
  it('should append linked relations and filter testCaseWorkItemField when isTestReporter=true and isQueryMode=false', async () => {
3224
3275
  tfs_1.TFSServices.getItemContent.mockReset();
3225
3276
  const selectedFields = ['associatedBug@linked', 'System.Title@testCaseWorkItemField'];
@@ -4061,6 +4112,22 @@ describe('ResultDataProvider', () => {
4061
4112
  expect(fetchStrategy).not.toHaveBeenCalled();
4062
4113
  expect(result).toEqual([]);
4063
4114
  });
4115
+ it('should keep points without run/result IDs when test reporter mode is enabled', async () => {
4116
+ const testData = [
4117
+ {
4118
+ testSuiteId: 1,
4119
+ testPointsItems: [{ testCaseId: 10, lastRunId: 101, lastResultId: 201 }, { testCaseId: 11 }],
4120
+ },
4121
+ ];
4122
+ const fetchStrategy = jest
4123
+ .fn()
4124
+ .mockResolvedValueOnce({ testCaseId: 10 })
4125
+ .mockResolvedValueOnce({ testCaseId: 11 });
4126
+ const result = await resultDataProvider.fetchAllResultDataBase(testData, mockProjectName, true, fetchStrategy);
4127
+ expect(fetchStrategy).toHaveBeenCalledTimes(2);
4128
+ expect(fetchStrategy).toHaveBeenNthCalledWith(2, mockProjectName, 1, expect.objectContaining({ testCaseId: 11 }));
4129
+ expect(result).toEqual([{ testCaseId: 10 }, { testCaseId: 11 }]);
4130
+ });
4064
4131
  });
4065
4132
  describe('fetchResultDataBase', () => {
4066
4133
  it('should fetch result data for a point', async () => {
@@ -4078,6 +4145,17 @@ describe('ResultDataProvider', () => {
4078
4145
  expect(fetchResultMethod).toHaveBeenCalled();
4079
4146
  expect(result).toBeDefined();
4080
4147
  });
4148
+ it('should call fetch method with runId/resultId as 0 when point has no run history', async () => {
4149
+ const point = { testCaseId: 15, lastRunId: undefined, lastResultId: undefined };
4150
+ const fetchResultMethod = jest.fn().mockResolvedValue({
4151
+ testCase: { id: 15, name: 'TC 15' },
4152
+ testSuite: { name: 'S' },
4153
+ iterationDetails: [],
4154
+ });
4155
+ const createResponseObject = jest.fn().mockReturnValue({ id: 15 });
4156
+ await resultDataProvider.fetchResultDataBase(mockProjectName, 'suite-no-runs', point, fetchResultMethod, createResponseObject);
4157
+ expect(fetchResultMethod).toHaveBeenCalledWith(mockProjectName, '0', '0');
4158
+ });
4081
4159
  });
4082
4160
  describe('getCombinedResultsSummary', () => {
4083
4161
  it('should return combined results summary with expected content controls', async () => {
@@ -4373,6 +4451,73 @@ describe('ResultDataProvider', () => {
4373
4451
  stepStepIdentifier: '1',
4374
4452
  }));
4375
4453
  });
4454
+ it('should return test-level row with empty step fields when suite has no run history', async () => {
4455
+ jest.spyOn(resultDataProvider, 'fetchTestPlanName').mockResolvedValueOnce('Plan 12');
4456
+ jest.spyOn(resultDataProvider, 'fetchTestSuites').mockResolvedValueOnce([
4457
+ {
4458
+ testSuiteId: 300,
4459
+ suiteId: 300,
4460
+ suiteName: 'suite no runs',
4461
+ parentSuiteId: 100,
4462
+ parentSuiteName: 'Rel3',
4463
+ suitePath: 'Root/Rel3/suite no runs',
4464
+ testGroupName: 'suite no runs',
4465
+ },
4466
+ ]);
4467
+ jest.spyOn(resultDataProvider, 'fetchTestData').mockResolvedValueOnce([
4468
+ {
4469
+ testSuiteId: 300,
4470
+ suiteId: 300,
4471
+ suiteName: 'suite no runs',
4472
+ parentSuiteId: 100,
4473
+ parentSuiteName: 'Rel3',
4474
+ suitePath: 'Root/Rel3/suite no runs',
4475
+ testGroupName: 'suite no runs',
4476
+ testPointsItems: [
4477
+ {
4478
+ testCaseId: 55,
4479
+ testCaseName: 'TC 55',
4480
+ outcome: 'Not Run',
4481
+ testPointId: 9001,
4482
+ lastRunId: undefined,
4483
+ lastResultId: undefined,
4484
+ lastResultDetails: undefined,
4485
+ },
4486
+ ],
4487
+ testCasesItems: [
4488
+ {
4489
+ workItem: {
4490
+ id: 55,
4491
+ workItemFields: [{ key: 'System.Rev', value: 4 }],
4492
+ },
4493
+ },
4494
+ ],
4495
+ },
4496
+ ]);
4497
+ jest.spyOn(resultDataProvider, 'fetchAllResultDataTestReporter').mockResolvedValueOnce([
4498
+ {
4499
+ testCaseId: 55,
4500
+ testCase: { id: 55, name: 'TC 55' },
4501
+ testSuite: { name: 'suite no runs' },
4502
+ executionDate: '',
4503
+ testCaseResult: { resultMessage: 'Not Run', url: '' },
4504
+ customFields: {},
4505
+ runBy: '',
4506
+ iteration: undefined,
4507
+ lastRunId: undefined,
4508
+ lastResultId: undefined,
4509
+ },
4510
+ ]);
4511
+ const result = await resultDataProvider.getTestReporterFlatResults(mockTestPlanId, mockProjectName, undefined, [], false);
4512
+ expect(result.rows).toHaveLength(1);
4513
+ expect(result.rows[0]).toEqual(expect.objectContaining({
4514
+ testCaseId: 55,
4515
+ testRunId: undefined,
4516
+ testPointId: 9001,
4517
+ stepOutcome: undefined,
4518
+ stepStepIdentifier: '',
4519
+ }));
4520
+ });
4376
4521
  });
4377
4522
  describe('getCombinedResultsSummary - appendix branches', () => {
4378
4523
  it('should use mapAttachmentsUrl when stepAnalysis.generateRunAttachments is enabled and stepExecution.runAttachmentMode != planOnly', async () => {