457 lines
14 KiB
JavaScript
457 lines
14 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 near-clones preserve a shared base cluster while retaining intentional representation-field differences", () => {
|
|
const planningConditions = getFieldSet("pinswg_planningconditionss73s79s");
|
|
const planningObligation = getFieldSet(
|
|
"pinswg_planningobligationappeals106s"
|
|
);
|
|
const enforcement = getFieldSet("pinswg_enforcementnoticeappeals174s");
|
|
|
|
const sharedPlanningCluster = [
|
|
"modifiedon",
|
|
"_pinswg_appellant_value",
|
|
"pinswg_name",
|
|
"pinswg_siteaddressline1",
|
|
"pinswg_siteaddressline2",
|
|
"pinswg_siteaddresspostcode",
|
|
"pinswg_siteaddresstown",
|
|
"_pinswg_associatedlpa_value",
|
|
"pinswg_casedecisiondate",
|
|
"pinswg_dateeventrequested",
|
|
"pinswg_finalcommentsduedate",
|
|
"pinswg_procedure",
|
|
"pinswg_questionnaireduedate",
|
|
"pinswg_startdate",
|
|
"pinswg_statementduedate",
|
|
"statuscode"
|
|
];
|
|
|
|
for (const [label, fields] of [
|
|
["Planning conditions", planningConditions],
|
|
["Planning obligation", planningObligation],
|
|
["Enforcement", enforcement]
|
|
]) {
|
|
assertHasFields(fields, sharedPlanningCluster, label);
|
|
}
|
|
|
|
assert.ok(
|
|
planningConditions.has("pinswg_otherpartiesstatement") &&
|
|
!planningConditions.has("pinswg_otherpartiesstatements"),
|
|
"Planning conditions should preserve singular other-parties field variant"
|
|
);
|
|
|
|
assert.ok(
|
|
planningObligation.has("pinswg_otherpartiesstatements") &&
|
|
!planningObligation.has("pinswg_otherpartiesstatement"),
|
|
"Planning obligation should preserve plural other-parties field variant"
|
|
);
|
|
|
|
assert.ok(
|
|
enforcement.has("pinswg_startdateoftheevent") &&
|
|
!enforcement.has("pinswg_startdateofevent"),
|
|
"Enforcement should preserve its current event-date field variant"
|
|
);
|
|
});
|
|
|
|
test("ROW and Hedges preserve a shared specialist/date/representation near-clone cluster", () => {
|
|
const rows = getFieldSet("pinswg_rows");
|
|
const hedges = getFieldSet(
|
|
"pinswg_hedgeshedgerowstreepreservationreplacems"
|
|
);
|
|
|
|
const sharedRowHedgesCluster = [
|
|
"pinswg_specialistcaseprocess",
|
|
"modifiedon",
|
|
"_pinswg_appellant_value",
|
|
"pinswg_name",
|
|
"_pinswg_associatedlpa_value",
|
|
"pinswg_casedecisiondate",
|
|
"pinswg_finalcommentsduedate",
|
|
"pinswg_otherpartiesstatement",
|
|
"pinswg_procedure",
|
|
"pinswg_proofsofevidencewrittenstatementsofeviden",
|
|
"pinswg_questionnaireduedate",
|
|
"pinswg_relevantauthorityname",
|
|
"pinswg_startdate",
|
|
"pinswg_startdateoftheevent",
|
|
"pinswg_typeofevent",
|
|
"pinswg_statementduedate",
|
|
"statuscode"
|
|
];
|
|
|
|
assertHasFields(rows, sharedRowHedgesCluster, "ROW near-clone cluster");
|
|
assertHasFields(
|
|
hedges,
|
|
sharedRowHedgesCluster,
|
|
"Hedges near-clone cluster"
|
|
);
|
|
|
|
assert.ok(
|
|
rows.has("pinswg_detailedeiascreeningrequired") &&
|
|
!rows.has("pinswg_detailedeiascreening"),
|
|
"ROW should preserve detailed EIA screening required variant"
|
|
);
|
|
|
|
assert.ok(
|
|
hedges.has("pinswg_detailedeiascreening") &&
|
|
!hedges.has("pinswg_detailedeiascreeningrequired"),
|
|
"Hedges should preserve detailed EIA screening variant without accidental normalization"
|
|
);
|
|
});
|
|
|
|
test("Advert specialist divergence is preserved against ROW canonical specialist-process selection", () => {
|
|
const adverts = getFieldSet("pinswg_advertses");
|
|
const rows = getFieldSet("pinswg_rows");
|
|
|
|
assert.ok(
|
|
adverts.has("pinswg_speacialistcaseprocess") &&
|
|
!adverts.has("pinswg_specialistcaseprocess"),
|
|
"Adverts should preserve misspelled specialist-process field only"
|
|
);
|
|
|
|
assert.ok(
|
|
rows.has("pinswg_specialistcaseprocess") &&
|
|
!rows.has("pinswg_speacialistcaseprocess"),
|
|
"ROW should preserve canonical specialist-process field only"
|
|
);
|
|
|
|
assertHasFields(
|
|
adverts,
|
|
[
|
|
"pinswg_finalcommentsduedate",
|
|
"pinswg_questionnaireduedate",
|
|
"pinswg_statementduedate",
|
|
"pinswg_startdate",
|
|
"pinswg_startdateoftheevent"
|
|
],
|
|
"Adverts specialist divergence support cluster"
|
|
);
|
|
|
|
assertHasFields(
|
|
rows,
|
|
[
|
|
"pinswg_finalcommentsduedate",
|
|
"pinswg_questionnaireduedate",
|
|
"pinswg_statementduedate",
|
|
"pinswg_startdate",
|
|
"pinswg_startdateoftheevent"
|
|
],
|
|
"ROW specialist divergence support cluster"
|
|
);
|
|
});
|
|
|
|
test("infrastructure near-clones preserve shared milestone concepts and schema-specific divergences", () => {
|
|
const dns = getFieldSet("pinswg_dnses");
|
|
const harbour = getFieldSet("pinswg_harbourrevisionorders");
|
|
const transport = getFieldSet("pinswg_transportandworkacts");
|
|
const electricity = getFieldSet("pinswg_electricityacts");
|
|
|
|
const sharedInfrastructureCluster = [
|
|
"pinswg_eiarequired",
|
|
"pinswg_name",
|
|
"pinswg_addressline1",
|
|
"pinswg_addressline2",
|
|
"pinswg_postcode",
|
|
"pinswg_addresstown",
|
|
"pinswg_applicationacceptedasvalid",
|
|
"pinswg_confirmrequesttovaryapplication",
|
|
"pinswg_dateeventrequested",
|
|
"pinswg_dateofsubmissionofapplication",
|
|
"pinswg_dateprojectpublishedonwebsite",
|
|
"pinswg_deadlineforsubmissionofapplication",
|
|
"pinswg_endofrepresentationperiod",
|
|
"pinswg_inspectorreportsubmittedtowelshgovernment",
|
|
"pinswg_projectlocation",
|
|
"pinswg_recommendation",
|
|
"pinswg_rejectrequesttovaryapplication",
|
|
"pinswg_reportdueby",
|
|
"pinswg_suspensiondates",
|
|
"pinswg_validnoticeofintentiontosubmitanapplicati",
|
|
"pinswg_webaddress",
|
|
"pinswg_withdrawndate",
|
|
"pinswg_writtenacceptanceofnotification",
|
|
"pinswg_startdateofevent",
|
|
"pinswg_typeofevent",
|
|
"statuscode"
|
|
];
|
|
|
|
for (const [label, fields] of [
|
|
["DNS", dns],
|
|
["Harbour", harbour],
|
|
["Transport", transport],
|
|
["Electricity", electricity]
|
|
]) {
|
|
assertHasFields(fields, sharedInfrastructureCluster, label);
|
|
}
|
|
|
|
assert.ok(
|
|
dns.has("pinswg_projectdescription") &&
|
|
!dns.has("pinswg_projectdiscription"),
|
|
"DNS should preserve canonical project description"
|
|
);
|
|
|
|
assert.ok(
|
|
harbour.has("pinswg_projectdiscription") &&
|
|
!harbour.has("pinswg_projectdescription"),
|
|
"Harbour should preserve misspelled project description variant"
|
|
);
|
|
|
|
assert.ok(
|
|
transport.has("pinswg_projectdescription") &&
|
|
!transport.has("pinswg_projectdiscription"),
|
|
"Transport should preserve canonical project description field"
|
|
);
|
|
|
|
assert.ok(
|
|
dns.has("pinswg_suspensionstartdates") &&
|
|
!dns.has("pinswg_suspensionstartdate"),
|
|
"DNS should preserve plural suspension start field"
|
|
);
|
|
|
|
for (const [label, fields] of [
|
|
["Harbour", harbour],
|
|
["Transport", transport]
|
|
]) {
|
|
assert.ok(
|
|
fields.has("pinswg_suspensionstartdate") &&
|
|
!fields.has("pinswg_suspensionstartdates"),
|
|
`${label} should preserve singular suspension start field variant`
|
|
);
|
|
}
|
|
|
|
assert.ok(
|
|
dns.has("pinswg_anticipatedgridreferenceeastingtext") &&
|
|
dns.has("pinswg_anticipatedgridreferencenorthingtext"),
|
|
"DNS should preserve grid reference fields"
|
|
);
|
|
|
|
assert.ok(
|
|
harbour.has("pinswg_anticipatedgridreferenceeastingtext") &&
|
|
harbour.has("pinswg_anticipatedgridreferencenorthingtext"),
|
|
"Harbour should preserve grid reference fields"
|
|
);
|
|
|
|
assert.ok(
|
|
!electricity.has("pinswg_anticipatedgridreferenceeastingtext") &&
|
|
!electricity.has("pinswg_anticipatedgridreferencenorthingtext"),
|
|
"Electricity should preserve current absence of grid reference fields"
|
|
);
|
|
});
|
|
|
|
test("representation-support cluster preserves questionnaire, statement, final-comments, and proof/other-parties variants", () => {
|
|
const rows = getFieldSet("pinswg_rows");
|
|
const planningObligation = getFieldSet(
|
|
"pinswg_planningobligationappeals106s"
|
|
);
|
|
const householder = getFieldSet("pinswg_householderappealhases");
|
|
const commonLand = getFieldSet("pinswg_commonlands");
|
|
|
|
assertHasFields(
|
|
rows,
|
|
[
|
|
"pinswg_questionnaireduedate",
|
|
"pinswg_statementduedate",
|
|
"pinswg_finalcommentsduedate",
|
|
"pinswg_proofsofevidencewrittenstatementsofeviden",
|
|
"pinswg_otherpartiesstatement"
|
|
],
|
|
"ROW representation-support cluster"
|
|
);
|
|
|
|
assertHasFields(
|
|
planningObligation,
|
|
[
|
|
"pinswg_questionnaireduedate",
|
|
"pinswg_statementduedate",
|
|
"pinswg_finalcommentsduedate",
|
|
"pinswg_otherpartiesstatements"
|
|
],
|
|
"Planning obligation representation-support cluster"
|
|
);
|
|
|
|
assertHasFields(
|
|
householder,
|
|
[
|
|
"pinswg_questionnaireduedate",
|
|
"pinswg_statementduedate",
|
|
"pinswg_finalcommentsduedate",
|
|
"pinswg_otherpartiesstmt"
|
|
],
|
|
"Householder representation-support cluster"
|
|
);
|
|
|
|
assertHasFields(
|
|
commonLand,
|
|
[
|
|
"pinswg_questionnaireduedate",
|
|
"pinswg_statementsduedate",
|
|
"pinswg_finalcommentsduedate",
|
|
"pinswg_proofsofevidencewrittenstatementsofeviden",
|
|
"pinswg_otherpartiesstatement"
|
|
],
|
|
"Common land representation-support cluster"
|
|
);
|
|
|
|
assert.ok(
|
|
commonLand.has("pinswg_statementsduedate") &&
|
|
!commonLand.has("pinswg_statementduedate"),
|
|
"Common land should preserve plural statement-due-date variant"
|
|
);
|
|
});
|
|
|
|
test("event-date cluster preserves coexistence of start-date/time variants across representative bundles", () => {
|
|
const callIns = getFieldSet("pinswg_callinss77s");
|
|
const adverts = getFieldSet("pinswg_advertses");
|
|
const planningS78Dev = getFieldSet(
|
|
"pinswg_planningappeals78s",
|
|
"dev-pedw-hc"
|
|
);
|
|
const listedBuilding = getFieldSet(
|
|
"pinswg_listedbuildingandconservationareaconsens"
|
|
);
|
|
const commonLand = getFieldSet("pinswg_commonlands");
|
|
|
|
assert.ok(
|
|
callIns.has("pinswg_startdateofevent") &&
|
|
!callIns.has("pinswg_startdateoftheevent"),
|
|
"Call-ins should preserve `pinswg_startdateofevent` variant"
|
|
);
|
|
|
|
assert.ok(
|
|
adverts.has("pinswg_startdateoftheevent") &&
|
|
!adverts.has("pinswg_startdateofevent"),
|
|
"Adverts should preserve `pinswg_startdateoftheevent` variant"
|
|
);
|
|
|
|
assert.ok(
|
|
planningS78Dev.has("pinswg_startdatetimeiftheevent"),
|
|
"S78 should preserve datetime event variant"
|
|
);
|
|
|
|
assert.ok(
|
|
listedBuilding.has("pinswg_starttimeofevent") &&
|
|
!listedBuilding.has("pinswg_starttimeoftheevent"),
|
|
"Listed building should preserve `pinswg_starttimeofevent` variant"
|
|
);
|
|
|
|
assert.ok(
|
|
commonLand.has("pinswg_starttimeoftheevent") &&
|
|
!commonLand.has("pinswg_starttimeofevent"),
|
|
"Common land should preserve `pinswg_starttimeoftheevent` variant"
|
|
);
|
|
});
|
|
|
|
test("authority and LPA cluster preserves current coexistence of local, associated, and relevant authority fields", () => {
|
|
const planningS78Dev = getFieldSet(
|
|
"pinswg_planningappeals78s",
|
|
"dev-pedw-hc"
|
|
);
|
|
const rows = getFieldSet("pinswg_rows");
|
|
const dns = getFieldSet("pinswg_dnses");
|
|
|
|
assert.ok(
|
|
planningS78Dev.has("_pinswg_localplanningauthority_value") &&
|
|
!planningS78Dev.has("_pinswg_associatedlpa_value") &&
|
|
!planningS78Dev.has("pinswg_relevantauthorityname"),
|
|
"S78 should preserve local-planning-authority-only behaviour"
|
|
);
|
|
|
|
assert.ok(
|
|
rows.has("_pinswg_associatedlpa_value") &&
|
|
rows.has("pinswg_relevantauthorityname") &&
|
|
!rows.has("_pinswg_localplanningauthority_value"),
|
|
"ROW should preserve overlap of associated LPA and relevant authority"
|
|
);
|
|
|
|
assert.ok(
|
|
dns.has("_pinswg_associatedlpa_value") &&
|
|
!dns.has("pinswg_relevantauthorityname") &&
|
|
!dns.has("_pinswg_localplanningauthority_value"),
|
|
"DNS should preserve associated-LPA-only authority behaviour"
|
|
);
|
|
});
|
|
|
|
const run = async () => {
|
|
let passed = 0;
|
|
for (const currentTest of tests) {
|
|
await currentTest.fn();
|
|
passed += 1;
|
|
}
|
|
|
|
console.log(
|
|
`Phase 22 select-query-types duplicated-cluster tests passed (${passed}/${tests.length}).`
|
|
);
|
|
};
|
|
|
|
module.exports = run;
|
|
|
|
if (require.main === module) {
|
|
run().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|
|
}
|