Add all vendor project keys and update docs for issue type dropdown

Expand VENDOR_PROJECT_KEYS to include all vendor projects: AA_ADTRAN,
AA_ADVA, AA_CASA, AA_CISCO, AACOMMSCOP, AA_COMMSCOP, AA_HARMONI,
AA_JUNIPER, AA_VECIMA, AA_VIAVI. Both AACOMMSCOP and AA_COMMSCOP
variants are included for safety.

Update property tests to exercise the full vendor key list instead of
only AA_VECIMA. Update full-reference-manual.md with vendor-specific
issue type dropdown documentation.
This commit is contained in:
Jordan Ramos
2026-05-27 15:17:43 -06:00
parent 04eb21a7d3
commit 9f7703c76f
4 changed files with 88 additions and 61 deletions

View File

@@ -15,7 +15,18 @@ const fc = require('fast-check');
// Replicate the pure functions from JiraPage.js for testing
// ---------------------------------------------------------------------------
const VENDOR_PROJECT_KEYS = ['AA_VECIMA'];
const VENDOR_PROJECT_KEYS = [
'AA_ADTRAN',
'AA_ADVA',
'AA_CASA',
'AA_CISCO',
'AACOMMSCOP',
'AA_COMMSCOP',
'AA_HARMONI',
'AA_JUNIPER',
'AA_VECIMA',
'AA_VIAVI',
];
const VENDOR_ISSUE_TYPES = [
'Epic',
@@ -58,22 +69,33 @@ function simulateProjectKeyChange(oldKey, newKey, currentIssueType, vendorKeys)
return (wasVendor !== isNowVendor) ? '' : currentIssueType;
}
// Helper: generate a vendor key with random casing and optional whitespace
const arbVendorKey = fc.constantFrom(...VENDOR_PROJECT_KEYS).chain(key =>
fc.oneof(
fc.constant(key),
fc.constant(key.toLowerCase()),
fc.constant(` ${key} `),
)
);
// Helper: generate a string that does NOT match any vendor key after normalization
const arbNonVendorKey = fc.string({ minLength: 0, maxLength: 50 }).filter(s => {
const normalized = s.trim().toUpperCase();
return !VENDOR_PROJECT_KEYS.includes(normalized);
});
const arbNonVendorKeyNonEmpty = fc.string({ minLength: 1, maxLength: 30 }).filter(s => {
const normalized = s.trim().toUpperCase();
return !VENDOR_PROJECT_KEYS.includes(normalized) && normalized.length > 0;
});
// ---------------------------------------------------------------------------
// Property 1: Issue type list determination
// ---------------------------------------------------------------------------
describe('Feature: vendor-issue-type-dropdown, Property 1: Issue type list determination', () => {
it('returns VENDOR_ISSUE_TYPES when project key matches a vendor key (case-insensitive, trimmed)', () => {
// Generate variations of the vendor key with different casing and whitespace
const vendorKeyVariants = fc.oneof(
fc.constant('AA_VECIMA'),
fc.constant('aa_vecima'),
fc.constant('Aa_Vecima'),
fc.constant(' AA_VECIMA '),
fc.constant('aa_VECIMA'),
);
fc.assert(
fc.property(vendorKeyVariants, (key) => {
fc.property(arbVendorKey, (key) => {
const result = getIssueTypesForProject(key, VENDOR_PROJECT_KEYS, VENDOR_ISSUE_TYPES, STEAM_ISSUE_TYPES);
expect(result).toBe(VENDOR_ISSUE_TYPES);
}),
@@ -82,14 +104,8 @@ describe('Feature: vendor-issue-type-dropdown, Property 1: Issue type list deter
});
it('returns STEAM_ISSUE_TYPES for any string that does not match a vendor key after normalization', () => {
// Generate arbitrary strings that are NOT 'AA_VECIMA' after trim+uppercase
const nonVendorKey = fc.string({ minLength: 0, maxLength: 50 }).filter(s => {
const normalized = s.trim().toUpperCase();
return normalized !== 'AA_VECIMA';
});
fc.assert(
fc.property(nonVendorKey, (key) => {
fc.property(arbNonVendorKey, (key) => {
const result = getIssueTypesForProject(key, VENDOR_PROJECT_KEYS, VENDOR_ISSUE_TYPES, STEAM_ISSUE_TYPES);
expect(result).toBe(STEAM_ISSUE_TYPES);
}),
@@ -120,20 +136,10 @@ describe('Feature: vendor-issue-type-dropdown, Property 1: Issue type list deter
// ---------------------------------------------------------------------------
describe('Feature: vendor-issue-type-dropdown, Property 2: Context switch resets issue type', () => {
it('resets issue_type to empty when switching from vendor to non-vendor context', () => {
// Generate a vendor key variant and a non-vendor key
const vendorKey = fc.oneof(
fc.constant('AA_VECIMA'),
fc.constant('aa_vecima'),
fc.constant(' AA_VECIMA '),
);
const nonVendorKey = fc.string({ minLength: 1, maxLength: 30 }).filter(s => {
const normalized = s.trim().toUpperCase();
return normalized !== 'AA_VECIMA' && normalized.length > 0;
});
const anyIssueType = fc.string({ minLength: 1, maxLength: 50 });
fc.assert(
fc.property(vendorKey, nonVendorKey, anyIssueType, (oldKey, newKey, issueType) => {
fc.property(arbVendorKey, arbNonVendorKeyNonEmpty, anyIssueType, (oldKey, newKey, issueType) => {
const result = simulateProjectKeyChange(oldKey, newKey, issueType, VENDOR_PROJECT_KEYS);
expect(result).toBe('');
}),
@@ -142,18 +148,10 @@ describe('Feature: vendor-issue-type-dropdown, Property 2: Context switch resets
});
it('resets issue_type to empty when switching from non-vendor to vendor context', () => {
const nonVendorKey = fc.string({ minLength: 1, maxLength: 30 }).filter(s => {
const normalized = s.trim().toUpperCase();
return normalized !== 'AA_VECIMA' && normalized.length > 0;
});
const vendorKey = fc.oneof(
fc.constant('AA_VECIMA'),
fc.constant('aa_vecima'),
);
const anyIssueType = fc.string({ minLength: 1, maxLength: 50 });
fc.assert(
fc.property(nonVendorKey, vendorKey, anyIssueType, (oldKey, newKey, issueType) => {
fc.property(arbNonVendorKeyNonEmpty, arbVendorKey, anyIssueType, (oldKey, newKey, issueType) => {
const result = simulateProjectKeyChange(oldKey, newKey, issueType, VENDOR_PROJECT_KEYS);
expect(result).toBe('');
}),
@@ -167,18 +165,10 @@ describe('Feature: vendor-issue-type-dropdown, Property 2: Context switch resets
// ---------------------------------------------------------------------------
describe('Feature: vendor-issue-type-dropdown, Property 3: Same context preserves issue type', () => {
it('preserves issue_type when both old and new keys resolve to STEAM context', () => {
const nonVendorKey1 = fc.string({ minLength: 0, maxLength: 30 }).filter(s => {
const normalized = s.trim().toUpperCase();
return normalized !== 'AA_VECIMA';
});
const nonVendorKey2 = fc.string({ minLength: 0, maxLength: 30 }).filter(s => {
const normalized = s.trim().toUpperCase();
return normalized !== 'AA_VECIMA';
});
const anyIssueType = fc.string({ minLength: 0, maxLength: 50 });
fc.assert(
fc.property(nonVendorKey1, nonVendorKey2, anyIssueType, (oldKey, newKey, issueType) => {
fc.property(arbNonVendorKey, arbNonVendorKey, anyIssueType, (oldKey, newKey, issueType) => {
const result = simulateProjectKeyChange(oldKey, newKey, issueType, VENDOR_PROJECT_KEYS);
expect(result).toBe(issueType);
}),
@@ -187,21 +177,10 @@ describe('Feature: vendor-issue-type-dropdown, Property 3: Same context preserve
});
it('preserves issue_type when both old and new keys resolve to vendor context', () => {
// With only one vendor key, both must be variants of AA_VECIMA
const vendorKey1 = fc.oneof(
fc.constant('AA_VECIMA'),
fc.constant('aa_vecima'),
fc.constant(' AA_VECIMA '),
);
const vendorKey2 = fc.oneof(
fc.constant('AA_VECIMA'),
fc.constant('Aa_Vecima'),
fc.constant('aa_VECIMA'),
);
const anyIssueType = fc.string({ minLength: 0, maxLength: 50 });
fc.assert(
fc.property(vendorKey1, vendorKey2, anyIssueType, (oldKey, newKey, issueType) => {
fc.property(arbVendorKey, arbVendorKey, anyIssueType, (oldKey, newKey, issueType) => {
const result = simulateProjectKeyChange(oldKey, newKey, issueType, VENDOR_PROJECT_KEYS);
expect(result).toBe(issueType);
}),