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); }); }