Files
pedwfrontend/tests/phase22/select-query-types-field-families.test.cjs
T

406 lines
12 KiB
JavaScript

const fs = require("fs");
const path = require("path");
const vm = require("vm");
const assert = require("assert");
const rootDir = path.resolve(__dirname, "..", "..");
const loadSelectQueryTypesModule = (relayPath) => {
const filePath = path.join(rootDir, "actions", "selectQueryTypes.js");
let source = fs.readFileSync(filePath, "utf8");
source = source.replace(
/export const\s+getSelectQuery\s*=\s*/,
"const getSelectQuery = "
);
source += `
module.exports = {
getSelectQuery
};
`;
const context = {
module: { exports: {} },
exports: {},
require,
process: {
env: {
RELAYPATH: relayPath
}
}
};
vm.runInNewContext(source, context, { filename: filePath });
return context.module.exports;
};
const tests = [];
const test = (name, fn) => tests.push({ name, fn });
const splitFields = (query) => {
assert.ok(
query.startsWith("&$select="),
`Expected query to start with &$select= but received: ${query}`
);
return query
.replace(/^&\$select=/, "")
.split(",")
.map((field) => field.trim())
.filter(Boolean);
};
const getFieldSet = (appealTypeName, relayPath) =>
new Set(
splitFields(
loadSelectQueryTypesModule(relayPath).getSelectQuery(appealTypeName)
)
);
const assertHasFields = (fieldSet, expectedFields, label) => {
for (const field of expectedFields) {
assert.ok(fieldSet.has(field), `${label}: expected field \`${field}\``);
}
};
test("planning-style family preserves common base, location, decision, and status fields across representative bundles", () => {
const s78Dev = getFieldSet("pinswg_planningappeals78s", "dev-pedw-hc");
const rows = getFieldSet("pinswg_rows");
const householder = getFieldSet("pinswg_householderappealhases");
const planningBaseFamily = [
"modifiedon",
"_pinswg_appellant_value",
"pinswg_name",
"pinswg_dateeventrequested",
"statuscode"
];
for (const [label, fields] of [
["S78 dev", s78Dev],
["ROW", rows],
["Householder", householder]
]) {
assertHasFields(fields, planningBaseFamily, label);
}
assertHasFields(
s78Dev,
[
"pinswg_siteaddressline1",
"pinswg_siteaddressline2",
"pinswg_siteaddresspostcode",
"pinswg_siteaddresstown",
"pinswg_siteaddresscounty",
"pinswg_casedecisiondate",
"pinswg_dicision"
],
"S78 dev planning family"
);
assertHasFields(
rows,
[
"pinswg_siteaddressline1",
"pinswg_siteaddressline2",
"pinswg_siteaddresspostcode",
"pinswg_siteaddresstown",
"pinswg_casedecisiondate",
"pinswg_decision"
],
"ROW planning family"
);
assertHasFields(
householder,
[
"pinswg_siteaddressline1",
"pinswg_siteaddressline2",
"pinswg_siteaddresspostcode",
"pinswg_siteaddresstown",
"pinswg_casedecisiondate",
"pinswg_decision"
],
"Householder planning family"
);
});
test("representation-window family preserves current start and end date variants without normalization", () => {
const rows = getFieldSet("pinswg_rows");
const enforcementListed = getFieldSet(
"pinswg_enforcementlistedbuildingconservationaps"
);
const dns = getFieldSet("pinswg_dnses");
const callIns = getFieldSet("pinswg_callinss77s");
assertHasFields(
rows,
[
"pinswg_startdate",
"pinswg_statementduedate",
"pinswg_finalcommentsduedate"
],
"ROW representation-window family"
);
assertHasFields(
enforcementListed,
[
"pinswg_startdates",
"pinswg_statementduedate",
"pinswg_finalcommentsduedate"
],
"Enforcement listed representation-window family"
);
assertHasFields(
dns,
[
"pinswg_applicationacceptedasvalid",
"pinswg_endofrepresentationperiod"
],
"DNS representation-window family"
);
assertHasFields(
callIns,
[
"pinswg_startdate",
"pinswg_statementsduedate",
"pinswg_finalcommentsduedate"
],
"Call-ins representation-window family"
);
assert.ok(
!dns.has("pinswg_startdate") && !dns.has("pinswg_startdates"),
"DNS should preserve infrastructure-style start-date variant rather than planning-style start fields"
);
});
test("specialist-process family preserves intentional field-variant divergence across bundles", () => {
const rows = getFieldSet("pinswg_rows");
const adverts = getFieldSet("pinswg_advertses");
const hedges = getFieldSet(
"pinswg_hedgeshedgerowstreepreservationreplacems"
);
const householder = getFieldSet("pinswg_householderappealhases");
assert.ok(
rows.has("pinswg_specialistcaseprocess") &&
!rows.has("pinswg_speacialistcaseprocess"),
"ROW should preserve canonical-only specialist-process selection"
);
assert.ok(
adverts.has("pinswg_speacialistcaseprocess") &&
!adverts.has("pinswg_specialistcaseprocess"),
"Adverts should preserve misspelled-only specialist-process selection"
);
assert.ok(
hedges.has("pinswg_specialistcaseprocess") &&
!hedges.has("pinswg_speacialistcaseprocess"),
"Hedges should preserve canonical-only specialist-process selection"
);
assert.ok(
!householder.has("pinswg_specialistcaseprocess") &&
!householder.has("pinswg_speacialistcaseprocess"),
"Householder should preserve absence of specialist-process fields"
);
});
test("infrastructure-style family preserves project-oriented fields and schema variants across representative bundles", () => {
const dns = getFieldSet("pinswg_dnses");
const harbour = getFieldSet("pinswg_harbourrevisionorders");
const electricity = getFieldSet("pinswg_electricityacts");
const commonInfrastructureFields = [
"pinswg_eiarequired",
"pinswg_name",
"pinswg_addressline1",
"pinswg_addresstown",
"pinswg_postcode",
"pinswg_applicationacceptedasvalid",
"pinswg_endofrepresentationperiod",
"pinswg_projectlocation",
"pinswg_recommendation",
"pinswg_reportdueby",
"pinswg_validnoticeofintentiontosubmitanapplicati",
"pinswg_writtenacceptanceofnotification",
"pinswg_startdateofevent",
"pinswg_typeofevent",
"statuscode"
];
for (const [label, fields] of [
["DNS", dns],
["Harbour", harbour],
["Electricity", electricity]
]) {
assertHasFields(fields, commonInfrastructureFields, label);
}
assert.ok(
dns.has("pinswg_projectdescription") &&
!dns.has("pinswg_projectdiscription"),
"DNS should preserve canonical project description field"
);
assert.ok(
harbour.has("pinswg_projectdiscription") &&
!harbour.has("pinswg_projectdescription"),
"Harbour should preserve misspelled project description variant"
);
assert.ok(
dns.has("pinswg_suspensionstartdates") &&
!dns.has("pinswg_suspensionstartdate"),
"DNS should preserve plural suspension start field"
);
assert.ok(
harbour.has("pinswg_suspensionstartdate") &&
!harbour.has("pinswg_suspensionstartdates"),
"Harbour should preserve singular suspension start field variant"
);
assert.ok(
electricity.has("modifiedon") && !dns.has("modifiedon"),
"Electricity should preserve current modifiedon overlap while DNS preserves its current omission"
);
});
test("authority and LPA family preserves current field distinctions rather than collapsing them", () => {
const s78Dev = getFieldSet("pinswg_planningappeals78s", "dev-pedw-hc");
const rows = getFieldSet("pinswg_rows");
const dns = getFieldSet("pinswg_dnses");
assert.ok(
s78Dev.has("_pinswg_localplanningauthority_value") &&
!s78Dev.has("_pinswg_associatedlpa_value"),
"S78 should preserve local-planning-authority field variant"
);
assert.ok(
rows.has("_pinswg_associatedlpa_value") &&
rows.has("pinswg_relevantauthorityname"),
"ROW should preserve overlap of associated LPA and relevant authority fields"
);
assert.ok(
dns.has("_pinswg_associatedlpa_value") &&
!dns.has("pinswg_relevantauthorityname"),
"DNS should preserve associated LPA without planning-style relevant-authority field"
);
});
test("consultation family is currently specific to SIPS-style profiles", () => {
const sips = getFieldSet("pinswg_sipses");
const dns = getFieldSet("pinswg_dnses");
const rows = getFieldSet("pinswg_rows");
assertHasFields(
sips,
["pinswg_consultationopen", "pinswg_consultationclose"],
"SIPS consultation family"
);
assert.ok(
!dns.has("pinswg_consultationopen") &&
!dns.has("pinswg_consultationclose") &&
!rows.has("pinswg_consultationopen") &&
!rows.has("pinswg_consultationclose"),
"Consultation fields should preserve their current absence from non-SIPS representative bundles"
);
});
test("minimal-profile family preserves intentionally small bundles and divergence from larger families", () => {
const nonValidation = getFieldSet("pinswg_nonvalidations");
const ldp = getFieldSet("pinswg_ldps");
const rows = getFieldSet("pinswg_rows");
assert.deepStrictEqual([...ldp], ["modifiedon", "pinswg_name"]);
assertHasFields(
nonValidation,
[
"modifiedon",
"_pinswg_appellant_value",
"pinswg_name",
"pinswg_siteaddressline1",
"pinswg_siteaddresspostcode",
"_pinswg_associatedlpa_value",
"statuscode"
],
"Nonvalidation minimal family"
);
assert.ok(
!nonValidation.has("pinswg_questionnaireduedate") &&
!nonValidation.has("pinswg_startdate") &&
!nonValidation.has("pinswg_applicationacceptedasvalid"),
"Nonvalidation should preserve absence of representation-window and questionnaire family fields"
);
assert.ok(
rows.size > nonValidation.size && nonValidation.size > ldp.size,
"Minimal bundles should preserve their intentionally smaller profiles relative to larger planning bundles"
);
});
test("family overlaps and divergences are preserved across representative bundles", () => {
const rows = getFieldSet("pinswg_rows");
const dns = getFieldSet("pinswg_dnses");
const sips = getFieldSet("pinswg_sipses");
const nonValidation = getFieldSet("pinswg_nonvalidations");
assert.ok(
rows.has("pinswg_startdate") && rows.has("pinswg_finalcommentsduedate"),
"Planning + representation overlap should be preserved for ROW"
);
assert.ok(
dns.has("pinswg_applicationacceptedasvalid") &&
dns.has("pinswg_endofrepresentationperiod") &&
dns.has("pinswg_projectlocation"),
"Infrastructure + representation overlap should be preserved for DNS"
);
assert.ok(
sips.has("pinswg_consultationopen") &&
sips.has("pinswg_consultationclose") &&
!sips.has("pinswg_finalcommentsduedate"),
"SIPS + consultation overlap and planning-style divergence should be preserved"
);
assert.ok(
!nonValidation.has("pinswg_projectlocation") &&
!nonValidation.has("pinswg_consultationopen") &&
!nonValidation.has("pinswg_questionnaireduedate"),
"Minimal profiles should preserve divergence from infrastructure, consultation, and richer planning families"
);
});
const run = async () => {
let passed = 0;
for (const currentTest of tests) {
await currentTest.fn();
passed += 1;
}
console.log(
`Phase 22 select-query-types field family tests passed (${passed}/${tests.length}).`
);
};
module.exports = run;
if (require.main === module) {
run().catch((error) => {
console.error(error);
process.exit(1);
});
}