const fs = require("fs"); const path = require("path"); const vm = require("vm"); const assert = require("assert"); const rootDir = path.resolve(__dirname, "..", ".."); const loadMapAppealTypeModule = () => { const filePath = path.join( rootDir, "lib", "domain", "case-lifecycle", "mapAppealType.js" ); let source = fs.readFileSync(filePath, "utf8"); source = source.replace(/export const\s+/g, "const "); source = source.replace( /export function\s+mapAppealType/, "function mapAppealType" ); source += ` module.exports = { caseTypeAliases, caseTypeKeyByAppealTypeId, normaliseCaseType, mapAppealType }; `; const context = { module: { exports: {} }, exports: {}, require }; vm.runInNewContext(source, context, { filename: filePath }); return context.module.exports; }; const loadGetAppealTypeFamily = () => { const filePath = path.join( rootDir, "lib", "domain", "appeal-type-policy", "getAppealTypeFamily.js" ); let source = fs.readFileSync(filePath, "utf8"); source = source.replace( /import\s+\{\s*mapAppealType\s*\}\s+from\s+"\.\.\/case-lifecycle\/mapAppealType";?/, "" ); source = source.replace( /export function\s+getAppealTypeFamily/, "function getAppealTypeFamily" ); source += "\nmodule.exports = { getAppealTypeFamily };\n"; const context = { module: { exports: {} }, exports: {}, require, mapAppealType: mapAppealTypeModule.mapAppealType }; vm.runInNewContext(source, context, { filename: filePath }); return context.module.exports; }; const tests = []; const test = (name, fn) => tests.push({ name, fn }); const mapAppealTypeModule = loadMapAppealTypeModule(); const { getAppealTypeFamily } = loadGetAppealTypeFamily(); test("known mappings are preserved for representative appeal types", () => { assert.strictEqual(getAppealTypeFamily(846040000), "PLANNING_S78"); assert.strictEqual(getAppealTypeFamily(846040009), "PLANNING_S78"); assert.strictEqual(getAppealTypeFamily(846040020), "PLANNING_S78"); assert.strictEqual(getAppealTypeFamily(846040011), "DNS"); assert.strictEqual(getAppealTypeFamily(846040002), "SIP"); assert.strictEqual( getAppealTypeFamily(846040015), "RIGHTS_OF_WAY_SCHEDULE_14" ); }); test("alias mappings are preserved exactly", () => { assert.strictEqual(getAppealTypeFamily("S78"), "PLANNING_S78"); assert.strictEqual(getAppealTypeFamily("PLANNING_78"), "PLANNING_S78"); assert.strictEqual(getAppealTypeFamily("CALL_IN"), "CALL_INS"); assert.strictEqual(getAppealTypeFamily("DNS"), "DNS"); }); test("numeric and numeric-string inputs preserve current behaviour", () => { assert.strictEqual(getAppealTypeFamily(846040004), "HAS"); assert.strictEqual(getAppealTypeFamily("846040004"), "HAS"); assert.strictEqual(getAppealTypeFamily("846040011"), "DNS"); }); test("unknown inputs preserve current fallback behaviour", () => { assert.strictEqual(getAppealTypeFamily(999999999), "999999999"); assert.strictEqual( getAppealTypeFamily("UNKNOWN_CASE_TYPE"), "UNKNOWN_CASE_TYPE" ); }); test("null and undefined preserve current behaviour", () => { assert.strictEqual(getAppealTypeFamily(null), undefined); assert.strictEqual(getAppealTypeFamily(undefined), undefined); }); test("existing normalization fallback behaviour is preserved for raw string labels", () => { assert.strictEqual(getAppealTypeFamily("planning s78"), "PLANNING_S78"); assert.strictEqual( getAppealTypeFamily("Rights of Way Schedule 14"), "RIGHTS_OF_WAY_SCHEDULE_14" ); }); test("new helper preserves parity with existing source-of-truth behaviour", () => { const scenarios = [ 846040000, 846040009, 846040020, 846040011, 846040002, 846040015, 846040004, 846040010, "S78", "CALL_IN", "UNKNOWN_CASE_TYPE", 999999999, null, undefined ]; for (const scenario of scenarios) { assert.strictEqual( getAppealTypeFamily(scenario), mapAppealTypeModule.mapAppealType(scenario) ); } }); const run = async () => { let passed = 0; for (const currentTest of tests) { await currentTest.fn(); passed += 1; } console.log( `Phase 22 appeal-type-family tests passed (${passed}/${tests.length}).` ); }; module.exports = run; if (require.main === module) { run().catch((error) => { console.error(error); process.exit(1); }); }