@elisra-devops/docgen-data-provider 1.74.0 → 1.75.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.
@@ -65,7 +65,7 @@ export default class ResultDataProvider {
65
65
  * Builds MEWP L2 requirement coverage rows for audit reporting.
66
66
  * Rows are one Requirement-TestCase pair; uncovered requirements are emitted with empty test-case columns.
67
67
  */
68
- getMewpL2CoverageFlatResults(testPlanId: string, projectName: string, selectedSuiteIds: number[] | undefined, linkedQueryRequest?: any): Promise<{
68
+ getMewpL2CoverageFlatResults(testPlanId: string, projectName: string, selectedSuiteIds: number[] | undefined): Promise<{
69
69
  sheetName: string;
70
70
  columnOrder: string[];
71
71
  rows: any[];
@@ -77,6 +77,7 @@ export default class ResultDataProvider {
77
77
  mapAttachmentsUrl(runResults: any[], project: string): any[];
78
78
  private buildMewpCoverageSheetName;
79
79
  private createMewpCoverageRow;
80
+ private formatMewpCustomerId;
80
81
  private buildMewpCoverageRows;
81
82
  private buildMewpTestCaseTitleMap;
82
83
  private extractMewpTestCaseId;
@@ -88,13 +89,6 @@ export default class ResultDataProvider {
88
89
  private normalizeRequirementStepText;
89
90
  private toRequirementKey;
90
91
  private fetchMewpL2Requirements;
91
- private extractMewpQueryHref;
92
- private fetchMewpL2RequirementsFromQuery;
93
- private upsertMewpRequirement;
94
- private hydrateMewpRequirementsFromWorkItems;
95
- private getMewpWorkItemType;
96
- private isMewpRequirementType;
97
- private isMewpTestCaseType;
98
92
  private fetchMewpRequirementTypeNames;
99
93
  private fetchWorkItemsByIds;
100
94
  private extractLinkedTestCaseIdsFromRequirement;
@@ -283,7 +283,7 @@ class ResultDataProvider {
283
283
  * Builds MEWP L2 requirement coverage rows for audit reporting.
284
284
  * Rows are one Requirement-TestCase pair; uncovered requirements are emitted with empty test-case columns.
285
285
  */
286
- async getMewpL2CoverageFlatResults(testPlanId, projectName, selectedSuiteIds, linkedQueryRequest) {
286
+ async getMewpL2CoverageFlatResults(testPlanId, projectName, selectedSuiteIds) {
287
287
  var _a, _b;
288
288
  const defaultPayload = {
289
289
  sheetName: `MEWP L2 Coverage - Plan ${testPlanId}`,
@@ -294,7 +294,7 @@ class ResultDataProvider {
294
294
  const planName = await this.fetchTestPlanName(testPlanId, projectName);
295
295
  const suites = await this.fetchTestSuites(testPlanId, projectName, selectedSuiteIds, true);
296
296
  const testData = await this.fetchTestData(suites, projectName, testPlanId, false);
297
- const requirements = await this.fetchMewpL2Requirements(projectName, linkedQueryRequest);
297
+ const requirements = await this.fetchMewpL2Requirements(projectName);
298
298
  if (requirements.length === 0) {
299
299
  return Object.assign(Object.assign({}, defaultPayload), { sheetName: this.buildMewpCoverageSheetName(planName, testPlanId) });
300
300
  }
@@ -395,9 +395,9 @@ class ResultDataProvider {
395
395
  return `MEWP L2 Coverage - ${suffix}`;
396
396
  }
397
397
  createMewpCoverageRow(requirement, testCaseId, testCaseTitle, stepSummary) {
398
- const customerId = String(requirement.requirementId || '').trim();
399
- const customerTitle = String(requirement.title || '').trim();
400
- const responsibility = String(requirement.responsibility || '').trim();
398
+ const customerId = this.formatMewpCustomerId(requirement.requirementId);
399
+ const customerTitle = this.toMewpComparableText(requirement.title);
400
+ const responsibility = this.toMewpComparableText(requirement.responsibility);
401
401
  const safeTestCaseId = Number.isFinite(testCaseId) && Number(testCaseId) > 0 ? Number(testCaseId) : '';
402
402
  return {
403
403
  'Customer ID': customerId,
@@ -410,6 +410,15 @@ class ResultDataProvider {
410
410
  'Number of not run tests': Number.isFinite(stepSummary === null || stepSummary === void 0 ? void 0 : stepSummary.notRun) ? stepSummary.notRun : 0,
411
411
  };
412
412
  }
413
+ formatMewpCustomerId(rawValue) {
414
+ const normalized = this.normalizeMewpRequirementCode(this.toMewpComparableText(rawValue));
415
+ if (normalized)
416
+ return normalized;
417
+ const onlyDigits = String(rawValue || '').replace(/\D/g, '');
418
+ if (onlyDigits)
419
+ return `SR${onlyDigits}`;
420
+ return '';
421
+ }
413
422
  buildMewpCoverageRows(requirements, requirementIndex, observedTestCaseIdsByRequirement, testCaseTitleMap) {
414
423
  var _a;
415
424
  const rows = [];
@@ -603,12 +612,8 @@ class ResultDataProvider {
603
612
  return '';
604
613
  return `SR${digits}`;
605
614
  }
606
- async fetchMewpL2Requirements(projectName, linkedQueryRequest) {
615
+ async fetchMewpL2Requirements(projectName) {
607
616
  var _a;
608
- const queryHref = this.extractMewpQueryHref(linkedQueryRequest);
609
- if (queryHref) {
610
- return this.fetchMewpL2RequirementsFromQuery(projectName, queryHref);
611
- }
612
617
  const workItemTypeNames = await this.fetchMewpRequirementTypeNames(projectName);
613
618
  if (workItemTypeNames.length === 0) {
614
619
  return [];
@@ -636,165 +641,13 @@ ORDER BY [System.Id]`;
636
641
  return {
637
642
  workItemId: Number((wi === null || wi === void 0 ? void 0 : wi.id) || 0),
638
643
  requirementId: this.extractMewpRequirementIdentifier(fields, Number((wi === null || wi === void 0 ? void 0 : wi.id) || 0)),
639
- title: String(fields['System.Title'] || ''),
644
+ title: this.toMewpComparableText((fields === null || fields === void 0 ? void 0 : fields['System.Title']) || (wi === null || wi === void 0 ? void 0 : wi.title)),
640
645
  responsibility: this.deriveMewpResponsibility(fields),
641
646
  linkedTestCaseIds: this.extractLinkedTestCaseIdsFromRequirement((wi === null || wi === void 0 ? void 0 : wi.relations) || []),
642
647
  };
643
648
  });
644
649
  return requirements.sort((a, b) => String(a.requirementId).localeCompare(String(b.requirementId)));
645
650
  }
646
- extractMewpQueryHref(linkedQueryRequest) {
647
- var _a, _b;
648
- const mode = String((linkedQueryRequest === null || linkedQueryRequest === void 0 ? void 0 : linkedQueryRequest.linkedQueryMode) || '')
649
- .trim()
650
- .toLowerCase();
651
- if (mode !== 'query')
652
- return '';
653
- return String(((_b = (_a = linkedQueryRequest === null || linkedQueryRequest === void 0 ? void 0 : linkedQueryRequest.testAssociatedQuery) === null || _a === void 0 ? void 0 : _a.wiql) === null || _b === void 0 ? void 0 : _b.href) || '').trim();
654
- }
655
- async fetchMewpL2RequirementsFromQuery(projectName, queryHref) {
656
- try {
657
- const ticketsDataProvider = new TicketsDataProvider_1.default(this.orgUrl, this.token);
658
- const queryResult = await ticketsDataProvider.GetQueryResultsFromWiql(queryHref, true, new Map());
659
- const requirementTypeNames = await this.fetchMewpRequirementTypeNames(projectName);
660
- const requirementTypeSet = new Set(requirementTypeNames.map((name) => String(name || '').trim().toLowerCase()));
661
- const requirementsById = new Map();
662
- const upsertRequirement = (workItem) => {
663
- this.upsertMewpRequirement(requirementsById, workItem, requirementTypeSet);
664
- };
665
- const linkRequirementToTestCase = (requirementWorkItem, testCaseWorkItem) => {
666
- const requirementId = Number((requirementWorkItem === null || requirementWorkItem === void 0 ? void 0 : requirementWorkItem.id) || 0);
667
- const testCaseId = Number((testCaseWorkItem === null || testCaseWorkItem === void 0 ? void 0 : testCaseWorkItem.id) || 0);
668
- if (!Number.isFinite(requirementId) || requirementId <= 0)
669
- return;
670
- if (!Number.isFinite(testCaseId) || testCaseId <= 0)
671
- return;
672
- upsertRequirement(requirementWorkItem);
673
- const requirement = requirementsById.get(requirementId);
674
- if (!requirement)
675
- return;
676
- requirement.linkedTestCaseIds.add(testCaseId);
677
- };
678
- if (Array.isArray(queryResult === null || queryResult === void 0 ? void 0 : queryResult.fetchedWorkItems)) {
679
- for (const workItem of queryResult.fetchedWorkItems) {
680
- upsertRequirement(workItem);
681
- }
682
- }
683
- if ((queryResult === null || queryResult === void 0 ? void 0 : queryResult.sourceTargetsMap) && typeof queryResult.sourceTargetsMap.entries === 'function') {
684
- for (const [sourceItem, targets] of queryResult.sourceTargetsMap.entries()) {
685
- const sourceType = this.getMewpWorkItemType(sourceItem);
686
- const sourceIsRequirement = this.isMewpRequirementType(sourceType, requirementTypeSet);
687
- const sourceIsTestCase = this.isMewpTestCaseType(sourceType);
688
- if (sourceIsRequirement) {
689
- upsertRequirement(sourceItem);
690
- }
691
- const relatedItems = Array.isArray(targets) ? targets : [];
692
- for (const targetItem of relatedItems) {
693
- const targetType = this.getMewpWorkItemType(targetItem);
694
- const targetIsRequirement = this.isMewpRequirementType(targetType, requirementTypeSet);
695
- const targetIsTestCase = this.isMewpTestCaseType(targetType);
696
- if (targetIsRequirement) {
697
- upsertRequirement(targetItem);
698
- }
699
- if (sourceIsRequirement && targetIsTestCase) {
700
- linkRequirementToTestCase(sourceItem, targetItem);
701
- }
702
- else if (sourceIsTestCase && targetIsRequirement) {
703
- linkRequirementToTestCase(targetItem, sourceItem);
704
- }
705
- }
706
- }
707
- }
708
- await this.hydrateMewpRequirementsFromWorkItems(projectName, requirementsById);
709
- return [...requirementsById.values()]
710
- .map((requirement) => ({
711
- workItemId: requirement.workItemId,
712
- requirementId: requirement.requirementId,
713
- title: requirement.title,
714
- responsibility: requirement.responsibility,
715
- linkedTestCaseIds: [...requirement.linkedTestCaseIds].sort((a, b) => a - b),
716
- }))
717
- .sort((a, b) => String(a.requirementId).localeCompare(String(b.requirementId)));
718
- }
719
- catch (error) {
720
- logger_1.default.error(`Could not fetch MEWP requirements from query: ${(error === null || error === void 0 ? void 0 : error.message) || error}`);
721
- return [];
722
- }
723
- }
724
- upsertMewpRequirement(requirementsById, workItem, requirementTypeSet) {
725
- const workItemId = Number((workItem === null || workItem === void 0 ? void 0 : workItem.id) || 0);
726
- if (!Number.isFinite(workItemId) || workItemId <= 0)
727
- return;
728
- const fields = (workItem === null || workItem === void 0 ? void 0 : workItem.fields) || {};
729
- const workItemType = this.getMewpWorkItemType(workItem);
730
- if (!this.isMewpRequirementType(workItemType, requirementTypeSet))
731
- return;
732
- const existing = requirementsById.get(workItemId) || {
733
- workItemId,
734
- requirementId: String(workItemId),
735
- title: '',
736
- responsibility: '',
737
- linkedTestCaseIds: new Set(),
738
- };
739
- const extractedRequirementId = this.extractMewpRequirementIdentifier(fields, workItemId);
740
- const extractedTitle = this.toMewpComparableText(fields === null || fields === void 0 ? void 0 : fields['System.Title']);
741
- const extractedResponsibility = this.deriveMewpResponsibility(fields);
742
- existing.requirementId = extractedRequirementId || existing.requirementId || String(workItemId);
743
- if (extractedTitle) {
744
- existing.title = extractedTitle;
745
- }
746
- if (extractedResponsibility) {
747
- existing.responsibility = extractedResponsibility;
748
- }
749
- requirementsById.set(workItemId, existing);
750
- }
751
- async hydrateMewpRequirementsFromWorkItems(projectName, requirementsById) {
752
- const requirementIds = [...requirementsById.keys()];
753
- if (requirementIds.length === 0)
754
- return;
755
- const fetchedRequirements = await this.fetchWorkItemsByIds(projectName, requirementIds, true);
756
- for (const requirementWorkItem of fetchedRequirements) {
757
- const workItemId = Number((requirementWorkItem === null || requirementWorkItem === void 0 ? void 0 : requirementWorkItem.id) || 0);
758
- if (!Number.isFinite(workItemId) || workItemId <= 0)
759
- continue;
760
- const current = requirementsById.get(workItemId);
761
- if (!current)
762
- continue;
763
- const fields = (requirementWorkItem === null || requirementWorkItem === void 0 ? void 0 : requirementWorkItem.fields) || {};
764
- const requirementId = this.extractMewpRequirementIdentifier(fields, workItemId);
765
- const title = this.toMewpComparableText(fields === null || fields === void 0 ? void 0 : fields['System.Title']);
766
- const responsibility = this.deriveMewpResponsibility(fields);
767
- const linkedTestCaseIds = this.extractLinkedTestCaseIdsFromRequirement((requirementWorkItem === null || requirementWorkItem === void 0 ? void 0 : requirementWorkItem.relations) || []);
768
- current.requirementId = requirementId || current.requirementId || String(workItemId);
769
- if (title) {
770
- current.title = title;
771
- }
772
- if (responsibility) {
773
- current.responsibility = responsibility;
774
- }
775
- linkedTestCaseIds.forEach((testCaseId) => current.linkedTestCaseIds.add(testCaseId));
776
- }
777
- }
778
- getMewpWorkItemType(workItem) {
779
- var _a;
780
- return this.toMewpComparableText((_a = workItem === null || workItem === void 0 ? void 0 : workItem.fields) === null || _a === void 0 ? void 0 : _a['System.WorkItemType']);
781
- }
782
- isMewpRequirementType(workItemType, requirementTypeSet) {
783
- const normalized = String(workItemType || '')
784
- .trim()
785
- .toLowerCase();
786
- if (!normalized)
787
- return false;
788
- if (requirementTypeSet.has(normalized))
789
- return true;
790
- return normalized.includes('requirement') || normalized === 'epic';
791
- }
792
- isMewpTestCaseType(workItemType) {
793
- const normalized = String(workItemType || '')
794
- .trim()
795
- .toLowerCase();
796
- return normalized === 'test case' || normalized === 'testcase';
797
- }
798
651
  async fetchMewpRequirementTypeNames(projectName) {
799
652
  try {
800
653
  const url = `${this.orgUrl}${projectName}/_apis/wit/workitemtypes?api-version=7.1-preview.2`;
@@ -890,9 +743,21 @@ ORDER BY [System.Id]`;
890
743
  const titleCode = this.normalizeMewpRequirementCode(title);
891
744
  if (titleCode)
892
745
  return titleCode;
893
- return String(fallbackWorkItemId || '');
746
+ return fallbackWorkItemId ? `SR${fallbackWorkItemId}` : '';
894
747
  }
895
748
  deriveMewpResponsibility(fields) {
749
+ const explicitSapWbs = this.toMewpComparableText(fields === null || fields === void 0 ? void 0 : fields['Custom.SAPWBS']);
750
+ const fromExplicitSapWbs = this.resolveMewpResponsibility(explicitSapWbs);
751
+ if (fromExplicitSapWbs)
752
+ return fromExplicitSapWbs;
753
+ if (explicitSapWbs)
754
+ return explicitSapWbs;
755
+ const explicitSapWbsByLabel = this.toMewpComparableText(fields === null || fields === void 0 ? void 0 : fields['SAPWBS']);
756
+ const fromExplicitLabel = this.resolveMewpResponsibility(explicitSapWbsByLabel);
757
+ if (fromExplicitLabel)
758
+ return fromExplicitLabel;
759
+ if (explicitSapWbsByLabel)
760
+ return explicitSapWbsByLabel;
896
761
  const areaPath = this.toMewpComparableText(fields === null || fields === void 0 ? void 0 : fields['System.AreaPath']);
897
762
  const fromAreaPath = this.resolveMewpResponsibility(areaPath);
898
763
  if (fromAreaPath)
@@ -945,6 +810,9 @@ ORDER BY [System.Id]`;
945
810
  const uniqueName = value.uniqueName;
946
811
  if (uniqueName)
947
812
  return String(uniqueName).trim();
813
+ const objectValue = value.value;
814
+ if (objectValue !== undefined && objectValue !== null)
815
+ return String(objectValue).trim();
948
816
  }
949
817
  return String(value).trim();
950
818
  }