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 assertIncludesAll = (fields, requiredFields, message) => { for (const field of requiredFields) { assert.ok( fields.includes(field), `${message}: expected field \`${field}\` to be included` ); } }; test("Planning S78 bundle preserves base, typo, S78-specific, and relaypath-dependent fields", () => { const devMod = loadSelectQueryTypesModule("dev-pedw-hc"); const nonDevMod = loadSelectQueryTypesModule("prod-like"); const devFields = splitFields( devMod.getSelectQuery("pinswg_planningappeals78s") ); const nonDevFields = splitFields( nonDevMod.getSelectQuery("pinswg_planningappeals78s") ); assertIncludesAll( devFields, [ "pinswg_eiarequired", "modifiedon", "_pinswg_appellant_value", "pinswg_name", "pinswg_siteaddressline1", "pinswg_siteaddresspostcode", "pinswg_siteaddresscounty", "_pinswg_localplanningauthority_value", "pinswg_casedecisiondate", "pinswg_dicision", "pinswg_questionnaireduedate", "pinswg_startdate", "pinswg_statementduedate", "pinswg_startdatetimeiftheevent", "pinswg_representation_period_end_date", "pinswg_extend_representation_date", "pinswg_typeofevent", "statuscode" ], "S78 dev bundle" ); assert.ok( !devFields.includes("pinswg_developmentdescription"), "S78 dev bundle should preserve current omission of extended appeal-form fields" ); assertIncludesAll( nonDevFields, [ "pinswg_eiarequired", "modifiedon", "_pinswg_appellant_value", "pinswg_name", "pinswg_dicision", "pinswg_startdatetimeiftheevent", "pinswg_developmentdescription", "pinswg_whyisinspectorneededonsite", "pinswg_outlinehealthandsafetyissuesonsite", "pinswg_additionalappealsmadedetails", "pinswg_chosenprocedureexplanation", "pinswg_dateofapplication", "pinswg_lpaapplicationreference", "pinswg_caseworkreason", "pinswg_dateoflpadecision", "pinswg_areaofsiteinhectaresdec", "pinswg_floorspaceinsquaremeters", "pinswg_ownershipcertificate", "pinswg_siteviewablefromroad", "pinswg_costappliedforindicator", "pinswg_s106unilateralsubmitted" ], "S78 non-dev bundle" ); assert.ok( !nonDevFields.includes("pinswg_representation_period_end_date"), "S78 non-dev bundle should preserve current omission of dev-only representation-period fields" ); }); test("DNS bundle preserves project, representation-window, and process fields", () => { const { getSelectQuery } = loadSelectQueryTypesModule(); const fields = splitFields(getSelectQuery("pinswg_dnses")); assertIncludesAll( fields, [ "pinswg_eiarequired", "pinswg_anticipatedgridreferenceeastingtext", "pinswg_anticipatedgridreferencenorthingtext", "pinswg_name", "pinswg_addressline1", "pinswg_addresscounty", "pinswg_applicationacceptedasvalid", "pinswg_choiceofprocedure", "pinswg_dateofdecision", "pinswg_deadlineforsubmissionofapplication", "pinswg_endofrepresentationperiod", "pinswg_procedureconfirmed", "pinswg_projectdescription", "pinswg_projectlocation", "pinswg_recommendation", "pinswg_reportdueby", "pinswg_suspensiondates", "pinswg_suspensionenddates", "pinswg_suspensionstartdates", "pinswg_webaddress", "pinswg_writtenacceptanceofnotification", "_pinswg_dnsids_value", "pinswg_startdateofevent", "pinswg_typeofevent", "statuscode" ], "DNS bundle" ); }); test("SIPS bundle preserves consultation and milestone fields", () => { const { getSelectQuery } = loadSelectQueryTypesModule(); const fields = splitFields(getSelectQuery("pinswg_sipses")); assertIncludesAll( fields, [ "pinswg_casedeadline", "_pinswg_projecttype_value", "pinswg_eiarequired", "pinswg_anticipatedgridrefeasting", "pinswg_anticipatedgridrefnorthing", "_pinswg_appellant_value", "pinswg_name", "_pinswg_associatedlpa_value", "pinswg_choiceofprocedure", "pinswg_projectdescription", "pinswg_projectlocation", "_pinswg_sipscase_value", "pinswg_validnoticeofintentiontosubmit", "pinswg_deadlineforsubmissionofapplication", "pinswg_screeningstartdate", "pinswg_eiatargetdate", "pinswg_scopingstartdate", "pinswg_scopingtargetdate", "pinswg_scopingoutcomeissueddate", "pinswg_consultationopen", "pinswg_consultationclose", "pinswg_reportissuedtowelshministers", "pinswg_decisionissuedtoapplicant", "pinswg_redeterminationconsultationdeadline" ], "SIPS bundle" ); }); test("ROW bundle preserves canonical specialist-process field and date/representation fields", () => { const { getSelectQuery } = loadSelectQueryTypesModule(); const fields = splitFields(getSelectQuery("pinswg_rows")); assertIncludesAll( fields, [ "pinswg_detailedeiascreeningrequired", "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" ], "ROW bundle" ); assert.ok( !fields.includes("pinswg_speacialistcaseprocess"), "ROW bundle should preserve current absence of misspelled specialist-process field" ); }); test("Adverts bundle preserves misspelled specialist-process field and representation fields", () => { const { getSelectQuery } = loadSelectQueryTypesModule(); const fields = splitFields(getSelectQuery("pinswg_advertses")); assertIncludesAll( fields, [ "pinswg_detailedeiascreeningrequired", "pinswg_speacialistcaseprocess", "modifiedon", "_pinswg_appellant_value", "pinswg_name", "_pinswg_associatedlpa_value", "pinswg_casedecisiondate", "pinswg_dateeventrequested", "pinswg_procedure", "pinswg_questionnaireduedate", "pinswg_startdateoftheevent", "pinswg_startdate", "pinswg_otherpartiesstatement", "pinswg_finalcommentsduedate", "pinswg_proofsofevidencewrittenstatementsofeviden", "pinswg_statementduedate", "statuscode" ], "Adverts bundle" ); assert.ok( !fields.includes("pinswg_specialistcaseprocess"), "Adverts bundle should preserve current absence of canonical specialist-process field" ); }); test("Householder bundle preserves reduced field set and other-parties variant", () => { const { getSelectQuery } = loadSelectQueryTypesModule(); const fields = splitFields(getSelectQuery("pinswg_householderappealhases")); assertIncludesAll( fields, [ "pinswg_eiarequired", "modifiedon", "_pinswg_appellant_value", "pinswg_name", "pinswg_siteaddressline1", "pinswg_siteaddresspostcode", "_pinswg_associatedlpa_value", "pinswg_casedecisiondate", "pinswg_dateeventrequested", "pinswg_decision", "pinswg_finalcommentsduedate", "pinswg_otherpartiesstmt", "pinswg_procedure", "pinswg_questionnaireduedate", "pinswg_startdate", "pinswg_statementduedate", "statuscode" ], "Householder bundle" ); assert.ok( !fields.includes("pinswg_startdateoftheevent") && !fields.includes("pinswg_startdateofevent"), "Householder bundle should preserve current omission of event-start fields" ); }); test("Infrastructure-style harbour bundle preserves project/date fields and schema variants", () => { const { getSelectQuery } = loadSelectQueryTypesModule(); const fields = splitFields(getSelectQuery("pinswg_harbourrevisionorders")); assertIncludesAll( fields, [ "pinswg_eiarequired", "pinswg_anticipatedgridreferenceeastingtext", "pinswg_anticipatedgridreferencenorthingtext", "pinswg_name", "pinswg_addressline1", "pinswg_addresscounty", "pinswg_applicationacceptedasvalid", "pinswg_choiceofprocedure", "pinswg_dateofdecision", "pinswg_endofrepresentationperiod", "pinswg_projectdiscription", "pinswg_projectlocation", "pinswg_suspensionstartdate", "pinswg_suspensionenddates", "pinswg_validnoticeofintentiontosubmitanapplicati", "pinswg_writtenacceptanceofnotification", "pinswg_startdateofevent", "pinswg_typeofevent", "statuscode" ], "Harbour bundle" ); }); test("Minimal bundles preserve current nonvalidation and LDP behaviour", () => { const { getSelectQuery } = loadSelectQueryTypesModule(); const nonValidationFields = splitFields( getSelectQuery("pinswg_nonvalidations") ); assertIncludesAll( nonValidationFields, [ "modifiedon", "_pinswg_appellant_value", "pinswg_name", "pinswg_siteaddressline1", "pinswg_siteaddressline2", "pinswg_siteaddresspostcode", "pinswg_siteaddresstown", "_pinswg_associatedlpa_value", "statuscode" ], "Nonvalidation bundle" ); assert.strictEqual( nonValidationFields.includes("pinswg_casedecisiondate"), false, "Nonvalidation bundle should preserve current omission of decision-date fields" ); const ldpFields = splitFields(getSelectQuery("pinswg_ldps")); assert.deepStrictEqual(ldpFields, ["modifiedon", "pinswg_name"]); }); const run = async () => { let passed = 0; for (const currentTest of tests) { await currentTest.fn(); passed += 1; } console.log( `Phase 22 select-query-types field bundle tests passed (${passed}/${tests.length}).` ); }; module.exports = run; if (require.main === module) { run().catch((error) => { console.error(error); process.exit(1); }); }