@elisra-devops/docgen-data-provider 1.78.0 → 1.79.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.
- package/bin/models/mewp-reporting.d.ts +1 -0
- package/bin/modules/ResultDataProvider.d.ts +0 -1
- package/bin/modules/ResultDataProvider.js +25 -50
- package/bin/modules/ResultDataProvider.js.map +1 -1
- package/bin/tests/modules/ResultDataProvider.test.js +6 -6
- package/bin/tests/modules/ResultDataProvider.test.js.map +1 -1
- package/package.json +1 -1
- package/src/models/mewp-reporting.ts +1 -0
- package/src/modules/ResultDataProvider.ts +26 -44
- package/src/tests/modules/ResultDataProvider.test.ts +6 -7
|
@@ -999,12 +999,16 @@ export default class ResultDataProvider {
|
|
|
999
999
|
}
|
|
1000
1000
|
|
|
1001
1001
|
private createMewpCoverageRow(
|
|
1002
|
-
requirement: Pick<
|
|
1002
|
+
requirement: Pick<
|
|
1003
|
+
MewpL2RequirementFamily,
|
|
1004
|
+
'workItemId' | 'requirementId' | 'title' | 'subSystem' | 'responsibility'
|
|
1005
|
+
>,
|
|
1003
1006
|
runStatus: MewpRunStatus,
|
|
1004
1007
|
bug: MewpCoverageBugCell,
|
|
1005
1008
|
linkedL3L4: MewpCoverageL3L4Cell
|
|
1006
1009
|
): MewpCoverageRow {
|
|
1007
|
-
const
|
|
1010
|
+
const l2ReqIdNumeric = Number(requirement?.workItemId || 0);
|
|
1011
|
+
const l2ReqId = l2ReqIdNumeric > 0 ? String(l2ReqIdNumeric) : '';
|
|
1008
1012
|
const l2ReqTitle = this.toMewpComparableText(requirement.title);
|
|
1009
1013
|
const l2SubSystem = this.toMewpComparableText(requirement.subSystem);
|
|
1010
1014
|
|
|
@@ -1050,15 +1054,6 @@ export default class ResultDataProvider {
|
|
|
1050
1054
|
return rows;
|
|
1051
1055
|
}
|
|
1052
1056
|
|
|
1053
|
-
private formatMewpCustomerId(rawValue: string): string {
|
|
1054
|
-
const normalized = this.normalizeMewpRequirementCode(this.toMewpComparableText(rawValue));
|
|
1055
|
-
if (normalized) return normalized;
|
|
1056
|
-
|
|
1057
|
-
const onlyDigits = String(rawValue || '').replace(/\D/g, '');
|
|
1058
|
-
if (onlyDigits) return `SR${onlyDigits}`;
|
|
1059
|
-
return '';
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
1057
|
private buildMewpCoverageRows(
|
|
1063
1058
|
requirements: MewpL2RequirementFamily[],
|
|
1064
1059
|
requirementIndex: MewpRequirementIndex,
|
|
@@ -1790,7 +1785,7 @@ export default class ResultDataProvider {
|
|
|
1790
1785
|
const workItems = await this.fetchWorkItemsByIds(projectName, requirementIds, true);
|
|
1791
1786
|
const requirements = workItems.map((wi: any) => {
|
|
1792
1787
|
const fields = wi?.fields || {};
|
|
1793
|
-
const requirementId = this.extractMewpRequirementIdentifier(fields
|
|
1788
|
+
const requirementId = this.extractMewpRequirementIdentifier(fields);
|
|
1794
1789
|
const areaPath = this.toMewpComparableText(fields?.['System.AreaPath']);
|
|
1795
1790
|
return {
|
|
1796
1791
|
workItemId: Number(wi?.id || 0),
|
|
@@ -1878,6 +1873,7 @@ export default class ResultDataProvider {
|
|
|
1878
1873
|
|
|
1879
1874
|
return [...families.entries()]
|
|
1880
1875
|
.map(([baseKey, family]) => ({
|
|
1876
|
+
workItemId: Number(family?.representative?.workItemId || 0),
|
|
1881
1877
|
requirementId: String(family?.representative?.requirementId || baseKey),
|
|
1882
1878
|
baseKey,
|
|
1883
1879
|
title: String(family?.representative?.title || ''),
|
|
@@ -2153,47 +2149,33 @@ export default class ResultDataProvider {
|
|
|
2153
2149
|
return [...out].sort((a, b) => a - b);
|
|
2154
2150
|
}
|
|
2155
2151
|
|
|
2156
|
-
private extractMewpRequirementIdentifier(fields: Record<string, any
|
|
2152
|
+
private extractMewpRequirementIdentifier(fields: Record<string, any>): string {
|
|
2157
2153
|
const entries = Object.entries(fields || {});
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2154
|
+
const normalizeFieldKey = (value: string): string =>
|
|
2155
|
+
String(value || '')
|
|
2156
|
+
.toLowerCase()
|
|
2157
|
+
.replace(/[^a-z0-9]/g, '');
|
|
2158
|
+
|
|
2159
|
+
// Strict MEWP mode: only explicit MEWP customer-id fields are accepted.
|
|
2160
|
+
// API display name: "Customer ID"
|
|
2161
|
+
// API reference name: "Custom.CustomerID"
|
|
2162
|
+
const customerIdFieldKeys = new Set<string>([
|
|
2161
2163
|
'customerid',
|
|
2162
|
-
'
|
|
2163
|
-
|
|
2164
|
-
'requirementid',
|
|
2165
|
-
'externalid',
|
|
2166
|
-
'srid',
|
|
2167
|
-
'sapwbsid',
|
|
2168
|
-
];
|
|
2169
|
-
for (const [key, value] of entries) {
|
|
2170
|
-
const normalizedKey = String(key || '').toLowerCase();
|
|
2171
|
-
if (!strictHints.some((hint) => normalizedKey.includes(hint))) continue;
|
|
2172
|
-
|
|
2173
|
-
const valueAsString = this.toMewpComparableText(value);
|
|
2174
|
-
if (!valueAsString) continue;
|
|
2175
|
-
const normalized = this.normalizeMewpRequirementCodeWithSuffix(valueAsString);
|
|
2176
|
-
if (normalized) return normalized;
|
|
2177
|
-
}
|
|
2164
|
+
'customcustomerid',
|
|
2165
|
+
]);
|
|
2178
2166
|
|
|
2179
|
-
// Second pass: weaker hints, but still key-based only.
|
|
2180
|
-
const looseHints = ['customer', 'requirement', 'external', 'sapwbs', 'sr'];
|
|
2181
2167
|
for (const [key, value] of entries) {
|
|
2182
|
-
const normalizedKey =
|
|
2183
|
-
if (!
|
|
2168
|
+
const normalizedKey = normalizeFieldKey(key);
|
|
2169
|
+
if (!customerIdFieldKeys.has(normalizedKey)) continue;
|
|
2184
2170
|
|
|
2185
2171
|
const valueAsString = this.toMewpComparableText(value);
|
|
2186
2172
|
if (!valueAsString) continue;
|
|
2187
|
-
const normalized = this.normalizeMewpRequirementCodeWithSuffix(valueAsString);
|
|
2188
|
-
if (normalized) return normalized;
|
|
2189
|
-
}
|
|
2190
2173
|
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
if (titleCode) return titleCode;
|
|
2174
|
+
const normalizedRequirementId = this.normalizeMewpRequirementCodeWithSuffix(valueAsString);
|
|
2175
|
+
if (normalizedRequirementId) return normalizedRequirementId;
|
|
2176
|
+
}
|
|
2195
2177
|
|
|
2196
|
-
return
|
|
2178
|
+
return '';
|
|
2197
2179
|
}
|
|
2198
2180
|
|
|
2199
2181
|
private deriveMewpResponsibility(fields: Record<string, any>): string {
|
|
@@ -1178,9 +1178,9 @@ describe('ResultDataProvider', () => {
|
|
|
1178
1178
|
})
|
|
1179
1179
|
);
|
|
1180
1180
|
|
|
1181
|
-
const covered = result.rows.find((row: any) => row['L2 REQ ID'] === '
|
|
1182
|
-
const inferredByStepText = result.rows.find((row: any) => row['L2 REQ ID'] === '
|
|
1183
|
-
const uncovered = result.rows.find((row: any) => row['L2 REQ ID'] === '
|
|
1181
|
+
const covered = result.rows.find((row: any) => row['L2 REQ ID'] === '5001');
|
|
1182
|
+
const inferredByStepText = result.rows.find((row: any) => row['L2 REQ ID'] === '5002');
|
|
1183
|
+
const uncovered = result.rows.find((row: any) => row['L2 REQ ID'] === '5003');
|
|
1184
1184
|
|
|
1185
1185
|
expect(covered).toEqual(
|
|
1186
1186
|
expect.objectContaining({
|
|
@@ -1297,7 +1297,7 @@ describe('ResultDataProvider', () => {
|
|
|
1297
1297
|
[1]
|
|
1298
1298
|
);
|
|
1299
1299
|
|
|
1300
|
-
const row = result.rows.find((item: any) => item['L2 REQ ID'] === '
|
|
1300
|
+
const row = result.rows.find((item: any) => item['L2 REQ ID'] === '7001');
|
|
1301
1301
|
expect(parseSpy).not.toHaveBeenCalled();
|
|
1302
1302
|
expect(row).toEqual(
|
|
1303
1303
|
expect.objectContaining({
|
|
@@ -1312,11 +1312,10 @@ describe('ResultDataProvider', () => {
|
|
|
1312
1312
|
'System.Description': 'random text with SR9999 that is unrelated',
|
|
1313
1313
|
'Custom.CustomerId': 'customer id unknown',
|
|
1314
1314
|
'System.Title': 'Requirement without explicit SR code',
|
|
1315
|
-
}
|
|
1316
|
-
4321
|
|
1315
|
+
}
|
|
1317
1316
|
);
|
|
1318
1317
|
|
|
1319
|
-
expect(requirementId).toBe('
|
|
1318
|
+
expect(requirementId).toBe('');
|
|
1320
1319
|
});
|
|
1321
1320
|
|
|
1322
1321
|
it('should derive responsibility from Custom.SAPWBS when present', () => {
|