const fs = require("fs"); const path = require("path"); const vm = require("vm"); const assert = require("assert"); const rootDir = path.resolve(__dirname, "..", ".."); const loadModule = (relativePath, injected = {}) => { const filePath = path.join(rootDir, relativePath); let source = fs.readFileSync(filePath, "utf8"); source = source.replace(/import[\s\S]*?from\s+"[^"]+";\n?/g, ""); source = source.replace( /export default async function\s+(\w+)\s*\(/g, "async function $1(" ); source = source.replace(/export const\s+/g, "const "); source = source.replace( /export default\s+(\w+);/g, "module.exports.default = $1;" ); source += '\nif (typeof ApiProxy !== "undefined" && !module.exports.default) module.exports.default = ApiProxy;\n'; const context = { module: { exports: {} }, exports: {}, require, process, CryptoJS: { HmacSHA256: () => ({ toString: () => "hashed" }), enc: { Hex: { parse: () => "" } } }, console: { log: () => {}, info: () => {}, warn: () => {}, error: () => {} }, ...injected }; vm.runInNewContext(source, context, { filename: filePath }); return context.module.exports; }; const createRes = () => { const state = { statusCode: null, jsonBody: undefined }; return { state, status(code) { state.statusCode = code; return this; }, json(payload) { state.jsonBody = payload; return payload; } }; }; const tests = []; const test = (name, fn) => tests.push({ name, fn }); test("getbasicdnssearch_api still returns 200 and preserves nextLink transform", async () => { const mod = loadModule("pages/api/endpoint/getbasicdnssearch_api.js", { axios: { get: async () => ({ data: { value: [{ id: 1 }], "@odata.nextLink": "https://example.test/v9.2/incidents?$skiptoken=dns" } }) }, getToken: async () => ({ access_token: "token" }), azureHeadersPaged: () => ({}), _: { has: (obj, key) => Object.prototype.hasOwnProperty.call(obj, key) } }); const req = { query: {} }; const res = createRes(); await mod.default(req, res); assert.strictEqual(res.state.statusCode, 200); assert.strictEqual( res.state.jsonBody["@odata.nextLink"], 'incidents?$skiptoken=dns"' ); }); test("getbasicdnsurlsearch_api rejects missing searchString with 400", async () => { const mod = loadModule("pages/api/endpoint/getbasicdnsurlsearch_api.js", { axios: { get: async () => ({ data: { value: [] } }) }, getToken: async () => ({ access_token: "token" }), azureHeadersPaged: () => ({}), _: { has: () => false, isEmpty: () => true } }); const req = { query: {} }; const res = createRes(); await mod.default(req, res); assert.strictEqual(res.state.statusCode, 400); }); test("getbasicdnsurlsearch_api valid searchString still returns 200", async () => { const mod = loadModule("pages/api/endpoint/getbasicdnsurlsearch_api.js", { axios: { get: async () => ({ data: { value: [{ id: 1 }], "@odata.nextLink": "https://example.test/v9.2/incidents?$skiptoken=url" } }) }, getToken: async () => ({ access_token: "token" }), azureHeadersPaged: () => ({}), _: { has: (obj, key) => Object.prototype.hasOwnProperty.call(obj, key), isEmpty: () => false } }); const req = { query: { searchString: "farm" } }; const res = createRes(); await mod.default(req, res); assert.strictEqual(res.state.statusCode, 200); assert.strictEqual( res.state.jsonBody["@odata.nextLink"], 'incidents?$skiptoken=url"' ); }); test("getbasicsearchdetailspaged_api rejects missing required params with 400", async () => { const mod = loadModule( "pages/api/endpoint/getbasicsearchdetailspaged_api.js", { axios: { get: async () => ({ data: { value: [] } }) }, getToken: async () => ({ access_token: "token" }), azureHeadersPaged: () => ({}), getSelectQuery: () => "", getNavigationPropertyByPrimaryAttribute: () => ({ NavigationProperty: "incident" }), _: { has: () => false } } ); const req = { query: { appealTypeName: "", primaryIdAttribute: "pinswg_case", incidentID: "" } }; const res = createRes(); await mod.default(req, res); assert.strictEqual(res.state.statusCode, 400); }); test("getbasicsearchdetailspaged_api valid params still return 200", async () => { const mod = loadModule( "pages/api/endpoint/getbasicsearchdetailspaged_api.js", { axios: { get: async () => ({ data: { value: [{ incident: { ticketnumber: "CAS-1" } }] } }) }, getToken: async () => ({ access_token: "token" }), azureHeadersPaged: () => ({}), getSelectQuery: () => "", getNavigationPropertyByPrimaryAttribute: () => ({ NavigationProperty: "incident" }), _: { has: () => false } } ); const req = { query: { appealTypeName: "pinswg_cases", primaryIdAttribute: "pinswg_case", incidentID: "incidentid eq guid'1'" } }; const res = createRes(); await mod.default(req, res); assert.strictEqual(res.state.statusCode, 200); assert.strictEqual(res.state.jsonBody.value[0].ticketnumber, "CAS-1"); }); const run = async () => { let passed = 0; for (const currentTest of tests) { await currentTest.fn(); passed += 1; } console.log( `Phase 20 behavioural tests passed (${passed}/${tests.length}).` ); }; run().catch((error) => { console.error(error); process.exit(1); });