5502 lines
181 KiB
JavaScript
5502 lines
181 KiB
JavaScript
const assert = require("assert");
|
|
const {
|
|
loadModule,
|
|
createRes,
|
|
respondSuccessMock,
|
|
respondErrorMock
|
|
} = require("./_shared.cjs");
|
|
|
|
const tests = [];
|
|
const test = (name, fn) => tests.push({ name, fn });
|
|
|
|
test("getCrmPersonalAccount returns the CRM response unchanged", async () => {
|
|
const contactId = "726158c6-708d-ec11-aad8-00224800be9c";
|
|
const crmResponse = {
|
|
contactid: contactId,
|
|
firstname: "Test",
|
|
lastname: "User",
|
|
emailaddress1: "test@example.com"
|
|
};
|
|
|
|
let capturedQueryUrl;
|
|
|
|
const mod = loadModule("lib/server/getCrmPersonalAccount.js", {
|
|
relayGetData: async ({ queryUrl }) => {
|
|
capturedQueryUrl = queryUrl;
|
|
return { data: crmResponse };
|
|
}
|
|
});
|
|
|
|
const result = await mod.getCrmPersonalAccount(contactId);
|
|
|
|
assert.deepStrictEqual(result, crmResponse);
|
|
assert.strictEqual(
|
|
capturedQueryUrl,
|
|
"contacts(" +
|
|
contactId +
|
|
")?$select=firstname, lastname, emailaddress1, telephone1, pinswg_companyname, address1_line1,address1_line2,address1_city, address1_county,address1_postalcode,pinswg_typeofinvolvement,pinswg_contact_associatedlpa,pinswg_preferredlanguage&$count=true"
|
|
);
|
|
});
|
|
|
|
test("getCrmPersonalAccount preserves the CRM lookup relay policy", async () => {
|
|
let capturedRelayPolicy;
|
|
|
|
const mod = loadModule("lib/server/getCrmPersonalAccount.js", {
|
|
relayGetData: async ({ relayPolicy }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return { data: {} };
|
|
}
|
|
});
|
|
|
|
await mod.getCrmPersonalAccount("726158c6-708d-ec11-aad8-00224800be9c");
|
|
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 6000,
|
|
maxRetries: 1,
|
|
retryBaseDelayMs: 100,
|
|
retryMaxDelayMs: 500
|
|
});
|
|
});
|
|
|
|
test("getCrmPersonalAccount propagates CRM relay failures", async () => {
|
|
const relayError = new Error("CRM relay unavailable");
|
|
|
|
const mod = loadModule("lib/server/getCrmPersonalAccount.js", {
|
|
relayGetData: async () => {
|
|
throw relayError;
|
|
}
|
|
});
|
|
|
|
await assert.rejects(
|
|
() => mod.getCrmPersonalAccount("726158c6-708d-ec11-aad8-00224800be9c"),
|
|
(error) => error === relayError
|
|
);
|
|
});
|
|
|
|
test("getaccounts returns EMAIL_ADDRESS_REQUIRED when emailAddress missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getaccounts_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "EMAIL_ADDRESS_REQUIRED");
|
|
});
|
|
|
|
test("getaccounts catch path returns ACCOUNTS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getaccounts_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "ACCOUNTS_FETCH_FAILED");
|
|
});
|
|
|
|
test("getaccounts passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getaccounts_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
}
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 6000,
|
|
maxRetries: 1,
|
|
retryBaseDelayMs: 100,
|
|
retryMaxDelayMs: 500
|
|
});
|
|
});
|
|
|
|
test("getemailaccountcheck returns EMAIL_ADDRESS_REQUIRED when emailAddress missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getemailaccountcheck_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "EMAIL_ADDRESS_REQUIRED");
|
|
});
|
|
|
|
test("getemailaccountcheck catch path returns EMAIL_ACCOUNT_CHECK_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getemailaccountcheck_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"EMAIL_ACCOUNT_CHECK_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getpreferredlanguage returns EMAIL_ADDRESS_REQUIRED when emailAddress missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getpreferredlanguage_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
sanitizeString: () => "",
|
|
isNonEmptyString: () => false,
|
|
escapeODataString: (value) => value,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "EMAIL_ADDRESS_REQUIRED");
|
|
});
|
|
|
|
test("getpreferredlanguage catch path returns PREFERRED_LANGUAGE_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getpreferredlanguage_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
sanitizeString: (value) => value,
|
|
isNonEmptyString: () => true,
|
|
escapeODataString: (value) => value,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"PREFERRED_LANGUAGE_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getpreferredlanguage success returns existing data payload contract", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getpreferredlanguage_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res }) =>
|
|
respondSuccessMock(res, {
|
|
value: [
|
|
{
|
|
contactid: "c1",
|
|
pinswg_preferredlanguage: 807570001
|
|
}
|
|
]
|
|
}),
|
|
sanitizeString: (value) => value,
|
|
isNonEmptyString: () => true,
|
|
escapeODataString: (value) => value,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => ({
|
|
data: {
|
|
value: [
|
|
{
|
|
contactid: "c1",
|
|
pinswg_preferredlanguage: 807570001
|
|
}
|
|
]
|
|
}
|
|
})
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
|
|
value: [
|
|
{
|
|
contactid: "c1",
|
|
pinswg_preferredlanguage: 807570001
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
test("getportallogin returns HASH_REQUIRED when hash missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getportallogin_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
hashAPIPath: (input) =>
|
|
input && input.startsWith("/api/endpoint/getportallogin_api")
|
|
? "&hash=expected"
|
|
: "&hash=relay",
|
|
azureHeadersPaged: () => ({})
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "HASH_REQUIRED");
|
|
});
|
|
|
|
test("getportallogin returns INVALID_HASH when hash mismatch", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getportallogin_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
hashAPIPath: (input) =>
|
|
input && input.startsWith("/api/endpoint/getportallogin_api")
|
|
? "&hash=expected"
|
|
: "&hash=relay",
|
|
azureHeadersPaged: () => ({})
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local", hash: "wrong" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INVALID_HASH");
|
|
});
|
|
|
|
test("getportallogin catch path returns PORTAL_LOGIN_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getportallogin_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
hashAPIPath: (input) =>
|
|
input && input.startsWith("/api/endpoint/getportallogin_api")
|
|
? "&hash=expected"
|
|
: "&hash=relay",
|
|
azureHeadersPaged: () => ({})
|
|
});
|
|
|
|
const req = {
|
|
query: { emailAddress: "user@test.local", hash: "expected" }
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"PORTAL_LOGIN_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getportallogin passes strict relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getportallogin_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
},
|
|
hashAPIPath: (input) =>
|
|
input && input.startsWith("/api/endpoint/getportallogin_api")
|
|
? "&hash=expected"
|
|
: "&hash=relay",
|
|
azureHeadersPaged: () => ({})
|
|
});
|
|
|
|
const req = {
|
|
query: { emailAddress: "user@test.local", hash: "expected" }
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 5000,
|
|
maxRetries: 0,
|
|
retryBaseDelayMs: 0,
|
|
retryMaxDelayMs: 0
|
|
});
|
|
});
|
|
|
|
test("getportallogin accepts encoded email hash variant", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getportallogin_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res }) =>
|
|
respondSuccessMock(res, { value: [{ contactid: "c1" }] }),
|
|
hashAPIPath: (input) =>
|
|
input && input.includes("emailAddress=user%2Btest%40local")
|
|
? "&hash=expected"
|
|
: "&hash=other",
|
|
azureHeadersPaged: () => ({})
|
|
});
|
|
|
|
const req = {
|
|
query: { emailAddress: "user+test@local", hash: "expected" }
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
|
|
value: [{ contactid: "c1" }]
|
|
});
|
|
});
|
|
|
|
test("getnewappeals catch path returns ADMIN_NEW_APPEALS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/admin/getnewappeals_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPagedCustom: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("admin new appeals failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"ADMIN_NEW_APPEALS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getlatestdocuments catch path returns ADMIN_LATEST_DOCS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/admin/getlatestdocuments_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPagedCustom: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("latest docs failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
process: { env: { HASHKEY: "abc" } },
|
|
CryptoJS: {
|
|
HmacSHA256: () => ({ toString: () => "hash" }),
|
|
enc: { Hex: { parse: () => "parsed" } }
|
|
},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"ADMIN_LATEST_DOCS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getportalloginproxy catch path returns PORTAL_LOGIN_PROXY_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getportalloginproxy_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"PORTAL_LOGIN_PROXY_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getportalloginproxy passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getportalloginproxy_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
},
|
|
azureHeadersPaged: () => ({})
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 6000,
|
|
maxRetries: 1,
|
|
retryBaseDelayMs: 100,
|
|
retryMaxDelayMs: 500
|
|
});
|
|
});
|
|
|
|
test("getpersonalaccount returns CONTACT_ID_REQUIRED when contactid missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getpersonalaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { contactid: "c1" } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "CONTACT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getpersonalaccount catch path returns PERSONAL_ACCOUNT_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getpersonalaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { contactid: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"PERSONAL_ACCOUNT_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getaccounts success returns existing data payload contract", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getaccounts_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res }) =>
|
|
respondSuccessMock(res, { value: [{ contactid: "c1" }] }),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => ({ data: { value: [{ contactid: "c1" }] } })
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
|
|
value: [{ contactid: "c1" }]
|
|
});
|
|
});
|
|
|
|
test("getemailaccountcheck success returns existing data payload contract", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getemailaccountcheck_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res }) =>
|
|
respondSuccessMock(res, {
|
|
value: [{ emailaddress1: "u@test" }]
|
|
}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => ({
|
|
data: { value: [{ emailaddress1: "u@test" }] }
|
|
})
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { emailAddress: "user@test.local" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
|
|
value: [{ emailaddress1: "u@test" }]
|
|
});
|
|
});
|
|
|
|
test("getwatchedcasesproxy returns LOGGED_IN_USER_ID_REQUIRED when loggedInUserId missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getwatchedcasesproxy_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"LOGGED_IN_USER_ID_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getwatchedcasesproxy catch path returns WATCHED_CASES_PROXY_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getwatchedcasesproxy_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"WATCHED_CASES_PROXY_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getmyrepresentationsproxy returns LOGGED_IN_USER_ID_REQUIRED when loggedInUserId missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getmyrepresentationsproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"LOGGED_IN_USER_ID_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getmyrepresentationsproxy catch path returns MY_REPRESENTATIONS_PROXY_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getmyrepresentationsproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"MY_REPRESENTATIONS_PROXY_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getrepresentationsproxy returns INCIDENT_ID_REQUIRED when incidentID missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getrepresentationsproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getrepresentationsproxy catch path returns REPRESENTATIONS_PROXY_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getrepresentationsproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { incidentID: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"REPRESENTATIONS_PROXY_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getawaitingsubmissionproxy returns LOGGED_IN_USER_ID_REQUIRED when loggedInUserId missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getawaitingsubmissionproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"LOGGED_IN_USER_ID_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getawaitingsubmissionproxy catch path returns AWAITING_SUBMISSION_PROXY_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getawaitingsubmissionproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"AWAITING_SUBMISSION_PROXY_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("createaccount returns ACCOUNT_PAYLOAD_REQUIRED when body missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/createaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => ({ data: { contactid: "c1" } }),
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {}, body: undefined };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"ACCOUNT_PAYLOAD_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("createaccount catch path returns ACCOUNT_CREATE_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/createaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => {
|
|
throw new Error("relay failed");
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {}, body: { firstname: "A" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "ACCOUNT_CREATE_FAILED");
|
|
});
|
|
|
|
test("updateaccount returns INVALID_CONTACT_ID when contactId missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/updateaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
updateCrmContact: async () => ({ contactid: "c1" }),
|
|
consoleLogger: () => {},
|
|
getServerSession: async () => ({
|
|
user: { email: "owner@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => ({
|
|
access_token: "test-token"
|
|
}),
|
|
escapeODataString: (value) => value,
|
|
azureHeaders: (token) => ({
|
|
headers: { Authorization: `Bearer ${token}` }
|
|
}),
|
|
relayGetData: async () => ({
|
|
data: {
|
|
value: [
|
|
{
|
|
contactid: "00000000-0000-0000-0000-000000000001"
|
|
}
|
|
]
|
|
}
|
|
})
|
|
});
|
|
|
|
const req = { method: "POST", query: {}, body: { firstname: "A" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INVALID_CONTACT_ID");
|
|
});
|
|
|
|
test("updateaccount returns ACCOUNT_UPDATE_PAYLOAD_REQUIRED when body missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/updateaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
updateCrmContact: async () => ({ contactid: "c1" }),
|
|
consoleLogger: () => {},
|
|
getServerSession: async () => ({
|
|
user: { email: "owner@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => ({
|
|
access_token: "test-token"
|
|
}),
|
|
escapeODataString: (value) => value,
|
|
azureHeaders: (token) => ({
|
|
headers: { Authorization: `Bearer ${token}` }
|
|
}),
|
|
relayGetData: async () => ({
|
|
data: {
|
|
value: [
|
|
{
|
|
contactid: "00000000-0000-0000-0000-000000000001"
|
|
}
|
|
]
|
|
}
|
|
})
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
query: { contactId: "00000000-0000-0000-0000-000000000001" },
|
|
body: undefined
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"ACCOUNT_UPDATE_PAYLOAD_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("updateaccount catch path returns ACCOUNT_UPDATE_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/updateaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
updateCrmContact: async () => {
|
|
throw new Error("relay failed");
|
|
},
|
|
consoleLogger: () => {},
|
|
getServerSession: async () => ({
|
|
user: { email: "owner@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => ({
|
|
access_token: "test-token"
|
|
}),
|
|
escapeODataString: (value) => value,
|
|
azureHeaders: (token) => ({
|
|
headers: { Authorization: `Bearer ${token}` }
|
|
}),
|
|
relayGetData: async () => ({
|
|
data: {
|
|
value: [
|
|
{
|
|
contactid: "00000000-0000-0000-0000-000000000001"
|
|
}
|
|
]
|
|
}
|
|
})
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
query: { contactId: "00000000-0000-0000-0000-000000000001" },
|
|
body: { firstname: "A" }
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "ACCOUNT_UPDATE_FAILED");
|
|
});
|
|
|
|
test("updateaccount rejects a different CRM contact before updating", async () => {
|
|
let updateCalls = 0;
|
|
|
|
const mod = loadModule("pages/api/endpoint/updateaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
consoleLogger: () => {},
|
|
|
|
getServerSession: async () => ({
|
|
user: { email: "owner@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
|
|
getToken: async () => ({
|
|
access_token: "test-token"
|
|
}),
|
|
escapeODataString: (value) => value,
|
|
azureHeaders: (token) => ({
|
|
headers: { Authorization: `Bearer ${token}` }
|
|
}),
|
|
|
|
relayGetData: async () => ({
|
|
data: {
|
|
value: [
|
|
{
|
|
contactid: "00000000-0000-0000-0000-000000000001"
|
|
}
|
|
]
|
|
}
|
|
}),
|
|
|
|
updateCrmContact: async () => {
|
|
updateCalls++;
|
|
return {};
|
|
}
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
query: {
|
|
contactId: "00000000-0000-0000-0000-000000000002"
|
|
},
|
|
body: {
|
|
firstname: "Unauthorised Update"
|
|
}
|
|
};
|
|
|
|
const res = createRes();
|
|
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 403);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CONTACT_OWNERSHIP_MISMATCH"
|
|
);
|
|
assert.strictEqual(updateCalls, 0);
|
|
});
|
|
|
|
test("updateaccount rejects unresolved CRM identity before updating", async () => {
|
|
let updateCalls = 0;
|
|
|
|
const mod = loadModule("pages/api/endpoint/updateaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
consoleLogger: () => {},
|
|
|
|
getServerSession: async () => ({
|
|
user: { email: "owner@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
|
|
getToken: async () => ({
|
|
access_token: "test-token"
|
|
}),
|
|
escapeODataString: (value) => value,
|
|
azureHeaders: (token) => ({
|
|
headers: { Authorization: `Bearer ${token}` }
|
|
}),
|
|
|
|
relayGetData: async () => ({
|
|
data: {
|
|
value: []
|
|
}
|
|
}),
|
|
|
|
updateCrmContact: async () => {
|
|
updateCalls++;
|
|
return {};
|
|
}
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
query: {
|
|
contactId: "00000000-0000-0000-0000-000000000001"
|
|
},
|
|
body: {
|
|
firstname: "Unauthorised Update"
|
|
}
|
|
};
|
|
|
|
const res = createRes();
|
|
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 403);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CONTACT_IDENTITY_NOT_RESOLVED"
|
|
);
|
|
assert.strictEqual(updateCalls, 0);
|
|
});
|
|
|
|
test("updateaccount strips prohibited CRM fields before updating", async () => {
|
|
const contactId = "00000000-0000-0000-0000-000000000001";
|
|
let capturedContactId;
|
|
let capturedPayload;
|
|
let updateCalls = 0;
|
|
|
|
const mod = loadModule("pages/api/endpoint/updateaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
consoleLogger: () => {},
|
|
|
|
getServerSession: async () => ({
|
|
user: { email: "owner@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
|
|
getToken: async () => ({
|
|
access_token: "test-token"
|
|
}),
|
|
escapeODataString: (value) => value,
|
|
azureHeaders: (token) => ({
|
|
headers: { Authorization: `Bearer ${token}` }
|
|
}),
|
|
|
|
relayGetData: async () => ({
|
|
data: {
|
|
value: [{ contactid: contactId }]
|
|
}
|
|
}),
|
|
|
|
updateCrmContact: async (id, payload) => {
|
|
updateCalls++;
|
|
capturedContactId = id;
|
|
capturedPayload = payload;
|
|
return { contactid: id };
|
|
}
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
query: { contactId },
|
|
body: {
|
|
firstname: "Robert",
|
|
telephone1: "01234567890",
|
|
emailaddress1: "attacker@example.com",
|
|
statuscode: 2,
|
|
contactid: "00000000-0000-0000-0000-000000000002"
|
|
}
|
|
};
|
|
|
|
const res = createRes();
|
|
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(updateCalls, 1);
|
|
assert.strictEqual(capturedContactId, contactId);
|
|
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedPayload)), {
|
|
firstname: "Robert",
|
|
telephone1: "01234567890"
|
|
});
|
|
});
|
|
|
|
test("updateaccount rejects payload containing only prohibited fields", async () => {
|
|
const contactId = "00000000-0000-0000-0000-000000000001";
|
|
let updateCalls = 0;
|
|
|
|
const mod = loadModule("pages/api/endpoint/updateaccount_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
consoleLogger: () => {},
|
|
|
|
getServerSession: async () => ({
|
|
user: { email: "owner@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
|
|
getToken: async () => ({
|
|
access_token: "test-token"
|
|
}),
|
|
escapeODataString: (value) => value,
|
|
azureHeaders: (token) => ({
|
|
headers: { Authorization: `Bearer ${token}` }
|
|
}),
|
|
|
|
relayGetData: async () => ({
|
|
data: {
|
|
value: [{ contactid: contactId }]
|
|
}
|
|
}),
|
|
|
|
updateCrmContact: async () => {
|
|
updateCalls++;
|
|
return {};
|
|
}
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
query: { contactId },
|
|
body: {
|
|
emailaddress1: "attacker@example.com",
|
|
statuscode: 2,
|
|
contactid: "00000000-0000-0000-0000-000000000002"
|
|
}
|
|
};
|
|
|
|
const res = createRes();
|
|
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"NO_ALLOWED_ACCOUNT_FIELDS"
|
|
);
|
|
assert.strictEqual(updateCalls, 0);
|
|
});
|
|
|
|
test("getbasicsearch returns SEARCH_STRING_REQUIRED when searchString missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicsearch_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "SEARCH_STRING_REQUIRED");
|
|
});
|
|
|
|
test("getbasicsearch catch path returns BASIC_SEARCH_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicsearch_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { searchString: "CAS" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_SEARCH_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getcasemessage returns CASE_ID_REQUIRED when id missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getcasemessage_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "CASE_ID_REQUIRED");
|
|
});
|
|
|
|
test("getcasemessage catch path returns CASE_MESSAGE_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getcasemessage_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { id: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CASE_MESSAGE_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getadvancedsearch returns SEARCH_STRING_REQUIRED when searchstring missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getadvancedsearch_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "SEARCH_STRING_REQUIRED");
|
|
});
|
|
|
|
test("getadvancedsearch returns INVALID_SEARCH_STRING when searchstring invalid JSON", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getadvancedsearch_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { searchstring: "not-json" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INVALID_SEARCH_STRING");
|
|
});
|
|
|
|
test("getadvancedsearch catch path returns ADVANCED_SEARCH_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getadvancedsearch_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
relayGetData: async () => ({
|
|
data: { value: [] },
|
|
accessToken: "token"
|
|
}),
|
|
azureHeadersPaged: () => ({}),
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
searchstring: encodeURI(
|
|
JSON.stringify({ q: "cas", lpa: "l1", apt: "1" })
|
|
)
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"ADVANCED_SEARCH_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getadvancedsearchpaged returns SEARCH_STRING_REQUIRED when searchstring missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getadvancedsearchpaged_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
azureHeadersPagedCustom: () => ({}),
|
|
hasOwn: (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
orderby: "createdon",
|
|
fieldSort: "asc",
|
|
showNumberOfRecords: "10"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "SEARCH_STRING_REQUIRED");
|
|
});
|
|
|
|
test("getadvancedsearchpaged returns ORDER_BY_REQUIRED when orderby missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getadvancedsearchpaged_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
azureHeadersPagedCustom: () => ({}),
|
|
hasOwn: (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
searchstring: encodeURI(JSON.stringify({ q: "cas" })),
|
|
fieldSort: "asc",
|
|
showNumberOfRecords: "10"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "ORDER_BY_REQUIRED");
|
|
});
|
|
|
|
test("getadvancedsearchpaged catch path returns ADVANCED_SEARCH_PAGED_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getadvancedsearchpaged_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
azureHeadersPagedCustom: () => ({}),
|
|
hasOwn: (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
searchstring: encodeURI(JSON.stringify({ q: "cas" })),
|
|
orderby: "createdon",
|
|
fieldSort: "asc",
|
|
showNumberOfRecords: "10"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"ADVANCED_SEARCH_PAGED_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getsearchdocumenthistory returns DOCUMENT_ID_REQUIRED when documentid missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getsearchdocumenthistory_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "DOCUMENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getsearchdocumenthistory catch path returns SEARCH_DOCUMENT_HISTORY_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getsearchdocumenthistory_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { documentid: "d1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"SEARCH_DOCUMENT_HISTORY_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getsearchdocumenthistory success returns existing data payload contract", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getsearchdocumenthistory_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res }) =>
|
|
respondSuccessMock(res, {
|
|
value: [{ _pinswg_documentid_value: "d1" }]
|
|
}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => ({
|
|
data: { value: [{ _pinswg_documentid_value: "d1" }] }
|
|
})
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { documentid: "d1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
|
|
value: [{ _pinswg_documentid_value: "d1" }]
|
|
});
|
|
});
|
|
|
|
test("getsearchdocumenthistorypaged returns DOCUMENT_ID_REQUIRED when documentid missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getsearchdocumenthistorypaged_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "DOCUMENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getsearchdocumenthistorypaged catch path returns SEARCH_DOCUMENT_HISTORY_PAGED_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getsearchdocumenthistorypaged_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { documentid: "d1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"SEARCH_DOCUMENT_HISTORY_PAGED_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getsearchdocumentdetails returns INCIDENT_ID_REQUIRED when incidentid missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getsearchdocumentdetails_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {},
|
|
CryptoJS: {
|
|
HmacSHA256: () => ({ toString: () => "hash" }),
|
|
enc: { Hex: { parse: () => "parsed", stringify: () => "hex" } }
|
|
},
|
|
_: { has: () => false }
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getsearchdocumentdetails catch path returns SEARCH_DOCUMENT_DETAILS_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getsearchdocumentdetails_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
CryptoJS: {
|
|
HmacSHA256: () => ({ toString: () => "hash" }),
|
|
enc: { Hex: { parse: () => "parsed", stringify: () => "hex" } }
|
|
},
|
|
_: { has: () => false }
|
|
}
|
|
);
|
|
|
|
const req = { query: { incidentid: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"SEARCH_DOCUMENT_DETAILS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getsearchdocumentdetailspaged returns INCIDENT_ID_REQUIRED when incidentid missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getsearchdocumentdetailspaged_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPagedCustom: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {},
|
|
CryptoJS: {
|
|
HmacSHA256: () => ({ toString: () => "hash" }),
|
|
enc: { Hex: { parse: () => "parsed", stringify: () => "hex" } }
|
|
},
|
|
_: { has: () => false }
|
|
}
|
|
);
|
|
|
|
const req = {
|
|
query: {
|
|
orderby: "createdon",
|
|
fieldSort: "asc",
|
|
showNumberOfRecords: "10"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getsearchdocumentdetailspaged catch path returns SEARCH_DOCUMENT_DETAILS_PAGED_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getsearchdocumentdetailspaged_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPagedCustom: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
CryptoJS: {
|
|
HmacSHA256: () => ({ toString: () => "hash" }),
|
|
enc: { Hex: { parse: () => "parsed", stringify: () => "hex" } }
|
|
},
|
|
_: { has: () => false }
|
|
}
|
|
);
|
|
|
|
const req = {
|
|
query: {
|
|
incidentid: "i1",
|
|
orderby: "createdon",
|
|
fieldSort: "asc",
|
|
showNumberOfRecords: "10"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"SEARCH_DOCUMENT_DETAILS_PAGED_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getsearchdocumentTypes returns INCIDENT_ID_REQUIRED when incidentid missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getsearchdocumentTypes_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getsearchdocumentTypes catch path returns SEARCH_DOCUMENT_TYPES_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getsearchdocumentTypes_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { incidentid: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"SEARCH_DOCUMENT_TYPES_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getsearchdocumentTypes success returns grouped data payload contract", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getsearchdocumentTypes_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res }) =>
|
|
respondSuccessMock(res, [
|
|
{
|
|
pinswg_isharedocumentlocations: 1,
|
|
pinswg_isharedocumentlocationsLabel: "Plans",
|
|
count: 2
|
|
},
|
|
{
|
|
pinswg_isharedocumentlocations: 2,
|
|
pinswg_isharedocumentlocationsLabel: "Letters",
|
|
count: 1
|
|
}
|
|
]),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => ({
|
|
data: {
|
|
value: [
|
|
{
|
|
pinswg_isharedocumentlocations: 1,
|
|
"pinswg_isharedocumentlocations@OData.Community.Display.V1.FormattedValue":
|
|
"Plans"
|
|
},
|
|
{
|
|
pinswg_isharedocumentlocations: 1,
|
|
"pinswg_isharedocumentlocations@OData.Community.Display.V1.FormattedValue":
|
|
"Plans"
|
|
},
|
|
{
|
|
pinswg_isharedocumentlocations: 2,
|
|
"pinswg_isharedocumentlocations@OData.Community.Display.V1.FormattedValue":
|
|
"Letters"
|
|
}
|
|
]
|
|
}
|
|
})
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { incidentid: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), [
|
|
{
|
|
pinswg_isharedocumentlocations: 1,
|
|
pinswg_isharedocumentlocationsLabel: "Plans",
|
|
count: 2
|
|
},
|
|
{
|
|
pinswg_isharedocumentlocations: 2,
|
|
pinswg_isharedocumentlocationsLabel: "Letters",
|
|
count: 1
|
|
}
|
|
]);
|
|
});
|
|
|
|
test("getmycases returns LOGGED_IN_USER_ID_REQUIRED when loggedInUserId missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getmycases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"LOGGED_IN_USER_ID_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getmycases catch path returns MY_CASES_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getmycases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "MY_CASES_FETCH_FAILED");
|
|
});
|
|
|
|
test("getmycases passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getmycases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
}
|
|
});
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 8000,
|
|
maxRetries: 2,
|
|
retryBaseDelayMs: 150,
|
|
retryMaxDelayMs: 800
|
|
});
|
|
});
|
|
|
|
test("getmyrepresentations returns LOGGED_IN_USER_ID_REQUIRED when loggedInUserId missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getmyrepresentations_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"LOGGED_IN_USER_ID_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getmyrepresentations catch path returns MY_REPRESENTATIONS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getmyrepresentations_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"MY_REPRESENTATIONS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getmyrepresentations passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getmyrepresentations_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
}
|
|
});
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 8000,
|
|
maxRetries: 2,
|
|
retryBaseDelayMs: 150,
|
|
retryMaxDelayMs: 800
|
|
});
|
|
});
|
|
|
|
test("getwatchedcases returns LOGGED_IN_USER_ID_REQUIRED when loggedInUserId missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"LOGGED_IN_USER_ID_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getwatchedcases catch path returns WATCHED_CASES_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"WATCHED_CASES_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getwatchedcases passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
}
|
|
});
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 8000,
|
|
maxRetries: 2,
|
|
retryBaseDelayMs: 150,
|
|
retryMaxDelayMs: 800
|
|
});
|
|
});
|
|
|
|
test("getawaitingsubmission returns LOGGED_IN_USER_ID_REQUIRED when loggedInUserId missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getawaitingsubmission_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"LOGGED_IN_USER_ID_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getawaitingsubmission catch path returns AWAITING_SUBMISSION_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getawaitingsubmission_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"AWAITING_SUBMISSION_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getawaitingsubmission passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getawaitingsubmission_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
}
|
|
});
|
|
|
|
const req = { query: { loggedInUserId: "c1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 8000,
|
|
maxRetries: 2,
|
|
retryBaseDelayMs: 150,
|
|
retryMaxDelayMs: 800
|
|
});
|
|
});
|
|
|
|
test("getbasicsearchdetails returns APPEAL_TYPE_NAME_REQUIRED when appealTypeName missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicsearchdetails_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=title",
|
|
getNavigationPropertyByPrimaryAttribute: () => ({
|
|
NavigationProperty: "pinswg_TestNav"
|
|
}),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
primaryIdAttribute: "pinswg_planningappeals78id",
|
|
incidentID: "i1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"APPEAL_TYPE_NAME_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getbasicsearchdetails catch path returns BASIC_SEARCH_DETAILS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicsearchdetails_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=title",
|
|
getNavigationPropertyByPrimaryAttribute: () => ({
|
|
NavigationProperty: "pinswg_TestNav"
|
|
}),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
appealTypeName: "pinswg_planningappeals78s",
|
|
primaryIdAttribute: "pinswg_planningappeals78id",
|
|
incidentID: "i1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_SEARCH_DETAILS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicsearchdetailspaged returns APPEAL_TYPE_NAME_REQUIRED when appealTypeName missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicsearchdetailspaged_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=title",
|
|
getNavigationPropertyByPrimaryAttribute: () => ({
|
|
NavigationProperty: "pinswg_TestNav"
|
|
}),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
}
|
|
);
|
|
|
|
const req = {
|
|
query: {
|
|
primaryIdAttribute: "pinswg_planningappeals78id",
|
|
incidentID: "i1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"APPEAL_TYPE_NAME_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getbasicsearchdetailspaged catch path returns BASIC_SEARCH_DETAILS_PAGED_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicsearchdetailspaged_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=title",
|
|
getNavigationPropertyByPrimaryAttribute: () => ({
|
|
NavigationProperty: "pinswg_TestNav"
|
|
}),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
}
|
|
);
|
|
|
|
const req = {
|
|
query: {
|
|
appealTypeName: "pinswg_planningappeals78s",
|
|
primaryIdAttribute: "pinswg_planningappeals78id",
|
|
incidentID: "i1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_SEARCH_DETAILS_PAGED_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicsearchpaged returns ORDER_BY_REQUIRED when orderby missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicsearchpaged_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPagedCustom: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
searchString: "cas",
|
|
fieldSort: "asc",
|
|
showNumberOfRecords: "10"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "ORDER_BY_REQUIRED");
|
|
});
|
|
|
|
test("getbasicsearchpaged catch path returns BASIC_SEARCH_PAGED_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicsearchpaged_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPagedCustom: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
searchString: "cas",
|
|
orderby: "createdon",
|
|
fieldSort: "asc",
|
|
showNumberOfRecords: "10"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_SEARCH_PAGED_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicsearchpaged passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getbasicsearchpaged_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
},
|
|
azureHeadersPagedCustom: () => ({}),
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
searchString: "cas",
|
|
orderby: "createdon",
|
|
fieldSort: "asc",
|
|
showNumberOfRecords: "10"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 9000,
|
|
maxRetries: 2,
|
|
retryBaseDelayMs: 150,
|
|
retryMaxDelayMs: 1000
|
|
});
|
|
});
|
|
|
|
test("getbasicsearch_by_lparref returns LPA_REF_REQUIRED when lpaRef missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicsearch_by_lparref_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "LPA_REF_REQUIRED");
|
|
});
|
|
|
|
test("getbasicsearch_by_lparref catch path returns BASIC_SEARCH_LPA_REF_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicsearch_by_lparref_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGetData: async () => {
|
|
throw new Error("relay failed");
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { lpaRef: "abc" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_SEARCH_LPA_REF_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicsearch_by_address success returns existing payload contract", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicsearch_by_address_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
relayGetData: async () => ({ data: { value: [] } }),
|
|
consoleLogger: () => {},
|
|
jsonpath: () => []
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
|
|
"@odata.count": 0,
|
|
value: []
|
|
});
|
|
});
|
|
|
|
test("getbasicsearch_by_address catch path returns BASIC_SEARCH_BY_ADDRESS_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicsearch_by_address_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => {
|
|
throw new Error("token failed");
|
|
},
|
|
relayGetData: async () => {
|
|
throw new Error("relay failed");
|
|
},
|
|
consoleLogger: () => {},
|
|
jsonpath: () => []
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 500);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_SEARCH_BY_ADDRESS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicdnssearch catch path returns BASIC_DNS_SEARCH_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicdnssearch_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_DNS_SEARCH_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicdnssearchpaged returns ORDER_BY_REQUIRED when orderby missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicdnssearchpaged_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
azureHeadersPagedCustom: () => ({}),
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: { fieldSort: "asc", showNumberOfRecords: "10" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "ORDER_BY_REQUIRED");
|
|
});
|
|
|
|
test("getbasicdnssearchpaged catch path returns BASIC_DNS_SEARCH_PAGED_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicdnssearchpaged_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
azureHeadersPagedCustom: () => ({}),
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
orderby: "createdon",
|
|
fieldSort: "asc",
|
|
showNumberOfRecords: "10"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_DNS_SEARCH_PAGED_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicdnssearchdetails returns CASE_REFERENCE_REQUIRED when caseReference missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicdnssearchdetails_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=pinswg_name",
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CASE_REFERENCE_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getbasicdnssearchdetails catch path returns BASIC_DNS_SEARCH_DETAILS_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicdnssearchdetails_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=pinswg_name",
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { caseReference: "DNS-001" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_DNS_SEARCH_DETAILS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicdnssearchdetailspaged returns CASE_REFERENCE_REQUIRED when caseReference missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicdnssearchdetailspaged_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=pinswg_name",
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CASE_REFERENCE_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getbasicdnssearchdetailspaged catch path returns BASIC_DNS_SEARCH_DETAILS_PAGED_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicdnssearchdetailspaged_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=pinswg_name",
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
}
|
|
);
|
|
|
|
const req = { query: { caseReference: "DNS-001" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_DNS_SEARCH_DETAILS_PAGED_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getportalmoduledetails returns APPEAL_TYPE_REQUIRED when appealType missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getportalmoduledetails_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=pinswg_name",
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { caseReference: "CAS-1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "APPEAL_TYPE_REQUIRED");
|
|
});
|
|
|
|
test("getportalmoduledetails catch path returns PORTAL_MODULE_DETAILS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getportalmoduledetails_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=pinswg_name",
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
appealType: "pinswg_planningappeals78s",
|
|
caseReference: "CAS-1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"PORTAL_MODULE_DETAILS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getportalmoduledetails passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getportalmoduledetails_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
},
|
|
getSelectQuery: () => "&$select=pinswg_name"
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
appealType: "pinswg_planningappeals78s",
|
|
caseReference: "CAS-1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 8000,
|
|
maxRetries: 2,
|
|
retryBaseDelayMs: 150,
|
|
retryMaxDelayMs: 800
|
|
});
|
|
});
|
|
|
|
test("getportalmoduledetailsproxy returns APPEAL_TYPE_REQUIRED when appealType missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getportalmoduledetailsproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=pinswg_name",
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { caseReference: "CAS-1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "APPEAL_TYPE_REQUIRED");
|
|
});
|
|
|
|
test("getportalmoduledetailsproxy catch path returns PORTAL_MODULE_DETAILS_PROXY_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getportalmoduledetailsproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
getSelectQuery: () => "&$select=pinswg_name",
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = {
|
|
query: {
|
|
appealType: "pinswg_planningappeals78s",
|
|
caseReference: "CAS-1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"PORTAL_MODULE_DETAILS_PROXY_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getportalmoduledetailsproxy passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getportalmoduledetailsproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
},
|
|
getSelectQuery: () => "&$select=pinswg_name"
|
|
}
|
|
);
|
|
|
|
const req = {
|
|
query: {
|
|
appealType: "pinswg_planningappeals78s",
|
|
caseReference: "CAS-1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 8000,
|
|
maxRetries: 2,
|
|
retryBaseDelayMs: 150,
|
|
retryMaxDelayMs: 800
|
|
});
|
|
});
|
|
|
|
test("getmylpacases returns LPA_ID_REQUIRED when lpaid missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getmylpacases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getLPA: async () => [{ name: "Test LPA", accountid: "acc1" }],
|
|
jsonpath: () => [{ accountid: "acc1" }],
|
|
azureHeaders: () => ({})
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "LPA_ID_REQUIRED");
|
|
});
|
|
|
|
test("getmylpacases returns LPA_NOT_FOUND when lpaid lookup misses", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getmylpacases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getLPA: async () => [{ name: "Another LPA", accountid: "acc1" }],
|
|
jsonpath: () => [],
|
|
azureHeaders: () => ({})
|
|
});
|
|
|
|
const req = { query: { lpaid: "Missing LPA" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 404);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "LPA_NOT_FOUND");
|
|
});
|
|
|
|
test("getmylpacases catch path returns MY_LPA_CASES_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getmylpacases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getLPA: async () => [{ name: "Test LPA", accountid: "acc1" }],
|
|
jsonpath: () => [{ accountid: "acc1" }],
|
|
azureHeaders: () => ({})
|
|
});
|
|
|
|
const req = { query: { lpaid: "Test LPA" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"MY_LPA_CASES_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getcase returns INCIDENT_ID_REQUIRED when incidentID missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getcase_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { ticketnumber: "CAS-1" } }) },
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getcase catch path returns CASE_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getcase_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: { incidentID: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "CASE_FETCH_FAILED");
|
|
});
|
|
|
|
test("getcasebyid returns INCIDENT_ID_REQUIRED when incidentID missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getcasebyid_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { ticketnumber: "CAS-1" } }) },
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getcasebyid catch path returns CASE_BY_ID_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getcasebyid_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: { incidentID: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CASE_BY_ID_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getincidentbyid returns SEARCH_STRING_REQUIRED when searchString missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getincidentbyid_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "SEARCH_STRING_REQUIRED");
|
|
});
|
|
|
|
test("getincidentbyid catch path returns INCIDENT_BY_ID_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getincidentbyid_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { searchString: "incident-guid" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"INCIDENT_BY_ID_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("createwatchedcases returns WATCHED_CASE_BINDINGS_REQUIRED when bindings missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => ({ data: {} }),
|
|
consoleLogger: () => {},
|
|
getServerSession: async () => ({
|
|
user: {
|
|
email: "test@example.com"
|
|
}
|
|
}),
|
|
authOptions: () => ({})
|
|
});
|
|
|
|
const req = { method: "POST", body: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"WATCHED_CASE_BINDINGS_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("createwatchedcases returns INVALID_BINDING_FORMAT when bindings invalid", async () => {
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => ({ data: {} }),
|
|
consoleLogger: () => {},
|
|
getServerSession: async () => ({
|
|
user: {
|
|
email: "test@example.com"
|
|
}
|
|
}),
|
|
authOptions: () => ({})
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
body: {
|
|
"pinswg_WatchedCase@odata.bind": "/incidents",
|
|
"pinswg_Contact@odata.bind": "/contacts"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INVALID_BINDING_FORMAT");
|
|
});
|
|
|
|
test("createwatchedcases catch path returns WATCHED_CASE_UPSERT_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => {
|
|
throw new Error("token failed");
|
|
},
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => ({ data: {} }),
|
|
consoleLogger: () => {},
|
|
getServerSession: async () => ({
|
|
user: {
|
|
email: "test@example.com"
|
|
}
|
|
}),
|
|
authOptions: () => ({})
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
body: {
|
|
"pinswg_WatchedCase@odata.bind":
|
|
"/incidents(11111111-1111-1111-1111-111111111111)",
|
|
"pinswg_Contact@odata.bind":
|
|
"/contacts(22222222-2222-2222-2222-222222222222)"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"WATCHED_CASE_UPSERT_FAILED"
|
|
);
|
|
});
|
|
|
|
test("createwatchedcases rejects unauthenticated requests before CRM access", async () => {
|
|
let tokenCalls = 0;
|
|
let relayCalls = 0;
|
|
let writeCalls = 0;
|
|
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getServerSession: async () => null,
|
|
authOptions: () => ({}),
|
|
getToken: async () => {
|
|
tokenCalls += 1;
|
|
return { access_token: "token" };
|
|
},
|
|
relayGetData: async () => {
|
|
relayCalls += 1;
|
|
return { data: { value: [] } };
|
|
},
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => {
|
|
writeCalls += 1;
|
|
return { data: {} };
|
|
},
|
|
consoleLogger: () => {},
|
|
authOptions: () => ({})
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
body: {
|
|
"pinswg_WatchedCase@odata.bind":
|
|
"/incidents(11111111-1111-1111-1111-111111111111)",
|
|
"pinswg_Contact@odata.bind":
|
|
"/contacts(22222222-2222-2222-2222-222222222222)"
|
|
}
|
|
};
|
|
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 401);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "UNAUTHENTICATED");
|
|
assert.strictEqual(tokenCalls, 0);
|
|
assert.strictEqual(relayCalls, 0);
|
|
assert.strictEqual(writeCalls, 0);
|
|
});
|
|
|
|
test("createwatchedcases rejects another contact before CRM write", async () => {
|
|
let writeCalls = 0;
|
|
|
|
const ownContactID = "22222222-2222-2222-2222-222222222222";
|
|
const otherContactID = "33333333-3333-3333-3333-333333333333";
|
|
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getServerSession: async () => ({
|
|
user: { email: "test@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
azureHeaders: () => ({
|
|
headers: { Authorization: "Bearer token" }
|
|
}),
|
|
escapeODataString: (value) => value.replace(/'/g, "''"),
|
|
relayGetData: async ({ queryUrl }) => {
|
|
if (queryUrl.startsWith("contacts?")) {
|
|
return {
|
|
data: {
|
|
value: [{ contactid: ownContactID }]
|
|
}
|
|
};
|
|
}
|
|
|
|
return { data: { value: [] } };
|
|
},
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => {
|
|
writeCalls += 1;
|
|
return { data: {} };
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
body: {
|
|
"pinswg_WatchedCase@odata.bind":
|
|
"/incidents(11111111-1111-1111-1111-111111111111)",
|
|
"pinswg_Contact@odata.bind": `/contacts(${otherContactID})`
|
|
}
|
|
};
|
|
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 403);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CONTACT_OWNERSHIP_MISMATCH"
|
|
);
|
|
assert.strictEqual(writeCalls, 0);
|
|
});
|
|
|
|
test("createwatchedcases rejects malformed GUID bindings before CRM access", async () => {
|
|
let tokenCalls = 0;
|
|
let relayCalls = 0;
|
|
let writeCalls = 0;
|
|
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getServerSession: async () => ({
|
|
user: { email: "test@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => {
|
|
tokenCalls += 1;
|
|
return { access_token: "token" };
|
|
},
|
|
relayGetData: async () => {
|
|
relayCalls += 1;
|
|
return { data: { value: [] } };
|
|
},
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => {
|
|
writeCalls += 1;
|
|
return { data: {} };
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
body: {
|
|
"pinswg_WatchedCase@odata.bind": "/incidents(not-a-valid-guid)",
|
|
"pinswg_Contact@odata.bind":
|
|
"/contacts(22222222-2222-2222-2222-222222222222)"
|
|
}
|
|
};
|
|
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INVALID_BINDING_FORMAT");
|
|
assert.strictEqual(tokenCalls, 0);
|
|
assert.strictEqual(relayCalls, 0);
|
|
assert.strictEqual(writeCalls, 0);
|
|
});
|
|
|
|
test("createwatchedcases rejects existing watchlist with mismatched ownership", async () => {
|
|
let writeCalls = 0;
|
|
|
|
const ownContactID = "22222222-2222-2222-2222-222222222222";
|
|
const otherContactID = "33333333-3333-3333-3333-333333333333";
|
|
const caseID = "11111111-1111-1111-1111-111111111111";
|
|
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getServerSession: async () => ({
|
|
user: { email: "test@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
azureHeaders: () => ({
|
|
headers: { Authorization: "Bearer token" }
|
|
}),
|
|
escapeODataString: (value) => value.replace(/'/g, "''"),
|
|
relayGetData: async ({ queryUrl }) => {
|
|
if (queryUrl.startsWith("contacts?")) {
|
|
return {
|
|
data: { value: [{ contactid: ownContactID }] }
|
|
};
|
|
}
|
|
|
|
if (queryUrl.startsWith("pinswg_watchlists?")) {
|
|
return {
|
|
data: {
|
|
value: [
|
|
{
|
|
pinswg_watchlistid:
|
|
"44444444-4444-4444-4444-444444444444",
|
|
_pinswg_contact_value: otherContactID,
|
|
_pinswg_watchedcase_value: caseID
|
|
}
|
|
]
|
|
}
|
|
};
|
|
}
|
|
|
|
throw new Error("Unexpected CRM query");
|
|
},
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => {
|
|
writeCalls += 1;
|
|
return { data: {} };
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
body: {
|
|
"pinswg_WatchedCase@odata.bind": `/incidents(${caseID})`,
|
|
"pinswg_Contact@odata.bind": `/contacts(${ownContactID})`
|
|
}
|
|
};
|
|
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 403);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"WATCHLIST_OWNERSHIP_MISMATCH"
|
|
);
|
|
assert.strictEqual(writeCalls, 0);
|
|
});
|
|
|
|
test("createwatchedcases allows multiple existing watchlists for the same contact and case", async () => {
|
|
const writes = [];
|
|
|
|
const contactID = "22222222-2222-2222-2222-222222222222";
|
|
const caseID = "11111111-1111-1111-1111-111111111111";
|
|
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getServerSession: async () => ({
|
|
user: { email: "test@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
azureHeaders: () => ({
|
|
headers: { Authorization: "Bearer token" }
|
|
}),
|
|
escapeODataString: (value) => value.replace(/'/g, "''"),
|
|
relayGetData: async ({ queryUrl }) => {
|
|
if (queryUrl.startsWith("contacts?")) {
|
|
return {
|
|
data: { value: [{ contactid: contactID }] }
|
|
};
|
|
}
|
|
|
|
if (queryUrl.startsWith("pinswg_watchlists?")) {
|
|
return {
|
|
data: {
|
|
value: [
|
|
{
|
|
pinswg_watchlistid:
|
|
"44444444-4444-4444-4444-444444444444",
|
|
_pinswg_contact_value: contactID,
|
|
_pinswg_watchedcase_value: caseID
|
|
},
|
|
{
|
|
pinswg_watchlistid:
|
|
"55555555-5555-5555-5555-555555555555",
|
|
_pinswg_contact_value: contactID,
|
|
_pinswg_watchedcase_value: caseID
|
|
}
|
|
]
|
|
}
|
|
};
|
|
}
|
|
|
|
throw new Error("Unexpected CRM query");
|
|
},
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async (config) => {
|
|
writes.push(config);
|
|
return { data: {} };
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
method: "POST",
|
|
body: {
|
|
"pinswg_WatchedCase@odata.bind": `/incidents(${caseID})`,
|
|
"pinswg_Contact@odata.bind": `/contacts(${contactID})`
|
|
}
|
|
};
|
|
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(writes.length, 1);
|
|
assert.strictEqual(writes[0].method, "patch");
|
|
|
|
assert.ok(
|
|
writes[0].url.includes(
|
|
"pinswg_watchlists(44444444-4444-4444-4444-444444444444)"
|
|
)
|
|
);
|
|
});
|
|
|
|
test("createwatchedcases creates a watched case for the authenticated contact", async () => {
|
|
const contactID = "22222222-2222-2222-2222-222222222222";
|
|
const caseID = "11111111-1111-1111-1111-111111111111";
|
|
const writes = [];
|
|
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getServerSession: async () => ({
|
|
user: { email: "test@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
azureHeaders: () => ({
|
|
headers: { Authorization: "Bearer token" }
|
|
}),
|
|
escapeODataString: (value) => value.replace(/'/g, "''"),
|
|
relayGetData: async ({ queryUrl }) => {
|
|
if (queryUrl.startsWith("contacts?")) {
|
|
return {
|
|
data: { value: [{ contactid: contactID }] }
|
|
};
|
|
}
|
|
|
|
if (queryUrl.startsWith("pinswg_watchlists?")) {
|
|
return { data: { value: [] } };
|
|
}
|
|
|
|
throw new Error("Unexpected CRM query");
|
|
},
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async (config) => {
|
|
writes.push(config);
|
|
return { data: { created: true } };
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const body = {
|
|
"pinswg_WatchedCase@odata.bind": `/incidents(${caseID})`,
|
|
"pinswg_Contact@odata.bind": `/contacts(${contactID})`,
|
|
pinswg_emailnotifications: true
|
|
};
|
|
|
|
const res = createRes();
|
|
|
|
await mod.default(
|
|
{
|
|
method: "POST",
|
|
body
|
|
},
|
|
res
|
|
);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(writes.length, 1);
|
|
assert.strictEqual(writes[0].method, "post");
|
|
assert.ok(writes[0].url.includes("pinswg_watchlists"));
|
|
|
|
const writtenData = JSON.parse(writes[0].data);
|
|
|
|
assert.strictEqual(
|
|
writtenData["pinswg_Contact@odata.bind"],
|
|
`/contacts(${contactID})`
|
|
);
|
|
assert.strictEqual(
|
|
writtenData["pinswg_WatchedCase@odata.bind"],
|
|
`/incidents(${caseID})`
|
|
);
|
|
assert.strictEqual(writtenData.pinswg_emailnotifications, true);
|
|
});
|
|
|
|
test("createwatchedcases updates a verified watchlist preserving representation fields", async () => {
|
|
const contactID = "22222222-2222-2222-2222-222222222222";
|
|
const caseID = "11111111-1111-1111-1111-111111111111";
|
|
const watchlistID = "44444444-4444-4444-4444-444444444444";
|
|
const writes = [];
|
|
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getServerSession: async () => ({
|
|
user: { email: "test@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
azureHeaders: () => ({
|
|
headers: { Authorization: "Bearer token" }
|
|
}),
|
|
escapeODataString: (value) => value.replace(/'/g, "''"),
|
|
relayGetData: async ({ queryUrl }) => {
|
|
if (queryUrl.startsWith("contacts?")) {
|
|
return {
|
|
data: { value: [{ contactid: contactID }] }
|
|
};
|
|
}
|
|
|
|
if (queryUrl.startsWith("pinswg_watchlists?")) {
|
|
return {
|
|
data: {
|
|
value: [
|
|
{
|
|
pinswg_watchlistid: watchlistID,
|
|
_pinswg_contact_value: contactID,
|
|
_pinswg_watchedcase_value: caseID
|
|
}
|
|
]
|
|
}
|
|
};
|
|
}
|
|
|
|
throw new Error("Unexpected CRM query");
|
|
},
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async (config) => {
|
|
writes.push(config);
|
|
return { data: { updated: true } };
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const body = {
|
|
"pinswg_WatchedCase@odata.bind": `/incidents(${caseID})`,
|
|
"pinswg_Contact@odata.bind": `/contacts(${contactID})`,
|
|
pinswg_emailnotifications: true,
|
|
pinswg_representationsubmitted: true,
|
|
pinswg_representationtype: 1
|
|
};
|
|
|
|
const res = createRes();
|
|
|
|
await mod.default({ method: "POST", body }, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(writes.length, 1);
|
|
assert.strictEqual(writes[0].method, "patch");
|
|
assert.ok(writes[0].url.includes(`pinswg_watchlists(${watchlistID})`));
|
|
|
|
const writtenData = JSON.parse(writes[0].data);
|
|
|
|
assert.strictEqual(writtenData.pinswg_emailnotifications, true);
|
|
assert.strictEqual(writtenData.pinswg_representationsubmitted, true);
|
|
assert.strictEqual(writtenData.pinswg_representationtype, 1);
|
|
assert.strictEqual(
|
|
writtenData["pinswg_Contact@odata.bind"],
|
|
`/contacts(${contactID})`
|
|
);
|
|
});
|
|
|
|
test("createwatchedcases preserves previous representations when submitting another", async () => {
|
|
const contactID = "22222222-2222-2222-2222-222222222222";
|
|
const caseID = "11111111-1111-1111-1111-111111111111";
|
|
const writes = [];
|
|
|
|
const existingRecords = [
|
|
{
|
|
pinswg_watchlistid: "44444444-4444-4444-4444-444444444444",
|
|
_pinswg_contact_value: contactID,
|
|
_pinswg_watchedcase_value: caseID,
|
|
pinswg_representationsubmitted: "2025-01-07T10:00:00Z",
|
|
pinswg_representationtype: 1
|
|
},
|
|
{
|
|
pinswg_watchlistid: "55555555-5555-5555-5555-555555555555",
|
|
_pinswg_contact_value: contactID,
|
|
_pinswg_watchedcase_value: caseID,
|
|
pinswg_representationsubmitted: "2025-01-09T14:00:00Z",
|
|
pinswg_representationtype: 2
|
|
}
|
|
];
|
|
|
|
const mod = loadModule("pages/api/endpoint/createwatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getServerSession: async () => ({
|
|
user: { email: "test@example.com" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
azureHeaders: () => ({
|
|
headers: { Authorization: "Bearer token" }
|
|
}),
|
|
escapeODataString: (value) => value.replace(/'/g, "''"),
|
|
relayGetData: async ({ queryUrl }) => {
|
|
if (queryUrl.startsWith("contacts?")) {
|
|
return {
|
|
data: { value: [{ contactid: contactID }] }
|
|
};
|
|
}
|
|
|
|
if (queryUrl.startsWith("pinswg_watchlists?")) {
|
|
assert.ok(queryUrl.includes("pinswg_representationsubmitted"));
|
|
|
|
return {
|
|
data: { value: existingRecords }
|
|
};
|
|
}
|
|
|
|
throw new Error("Unexpected CRM query");
|
|
},
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async (config) => {
|
|
writes.push(config);
|
|
return { data: { created: true } };
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const submissionDate = "2025-01-14T09:30:00Z";
|
|
|
|
const body = {
|
|
"pinswg_WatchedCase@odata.bind": `/incidents(${caseID})`,
|
|
"pinswg_Contact@odata.bind": `/contacts(${contactID})`,
|
|
pinswg_representationsubmitted: submissionDate,
|
|
pinswg_representationtype: 3
|
|
};
|
|
|
|
const res = createRes();
|
|
|
|
await mod.default({ method: "POST", body }, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(writes.length, 1);
|
|
|
|
// A new submission must not PATCH a historical representation.
|
|
assert.strictEqual(writes[0].method, "post");
|
|
assert.ok(writes[0].url.includes("pinswg_watchlists"));
|
|
assert.ok(
|
|
!writes[0].url.includes(
|
|
"pinswg_watchlists(44444444-4444-4444-4444-444444444444)"
|
|
)
|
|
);
|
|
|
|
const writtenData = JSON.parse(writes[0].data);
|
|
|
|
assert.strictEqual(
|
|
writtenData.pinswg_representationsubmitted,
|
|
submissionDate
|
|
);
|
|
assert.strictEqual(writtenData.pinswg_representationtype, 3);
|
|
assert.strictEqual(
|
|
writtenData["pinswg_Contact@odata.bind"],
|
|
`/contacts(${contactID})`
|
|
);
|
|
|
|
// Neither historical submission was modified.
|
|
assert.strictEqual(
|
|
existingRecords[0].pinswg_representationsubmitted,
|
|
"2025-01-07T10:00:00Z"
|
|
);
|
|
assert.strictEqual(
|
|
existingRecords[1].pinswg_representationsubmitted,
|
|
"2025-01-09T14:00:00Z"
|
|
);
|
|
});
|
|
|
|
const WATCHED_CASE_ID = "11111111-1111-1111-1111-111111111111";
|
|
const CONTACT_ID = "22222222-2222-2222-2222-222222222222";
|
|
const OTHER_CONTACT_ID = "33333333-3333-3333-3333-333333333333";
|
|
|
|
const createDeleteWatchedCasesFixture = (overrides = {}) => {
|
|
const calls = {
|
|
session: [],
|
|
token: 0,
|
|
relay: [],
|
|
delete: []
|
|
};
|
|
const session = Object.prototype.hasOwnProperty.call(overrides, "session")
|
|
? overrides.session
|
|
: { user: { email: "user.o'neill@test.local" } };
|
|
const contacts = Object.prototype.hasOwnProperty.call(overrides, "contacts")
|
|
? overrides.contacts
|
|
: [{ contactid: CONTACT_ID }];
|
|
const watchlist = Object.prototype.hasOwnProperty.call(
|
|
overrides,
|
|
"watchlist"
|
|
)
|
|
? overrides.watchlist
|
|
: {
|
|
pinswg_watchlistid: WATCHED_CASE_ID,
|
|
_pinswg_contact_value: CONTACT_ID
|
|
};
|
|
|
|
const mod = loadModule("pages/api/endpoint/deletewatchedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getServerSession: async (...args) => {
|
|
calls.session.push(args);
|
|
return session;
|
|
},
|
|
authOptions: (req, res) => ({ req, res }),
|
|
getToken: async () => {
|
|
calls.token += 1;
|
|
return { access_token: "token" };
|
|
},
|
|
relayGetData: async (options) => {
|
|
calls.relay.push(options);
|
|
|
|
if (options.queryUrl.startsWith("contacts?")) {
|
|
if (overrides.contactLookupError) {
|
|
throw overrides.contactLookupError;
|
|
}
|
|
return { data: { value: contacts } };
|
|
}
|
|
|
|
if (overrides.watchlistLookupError) {
|
|
throw overrides.watchlistLookupError;
|
|
}
|
|
return { data: watchlist };
|
|
},
|
|
escapeODataString: (value) => value.trim().replace(/'/g, "''"),
|
|
azureHeaders: (accessToken) => ({
|
|
headers: { Authorization: `Bearer ${accessToken}` }
|
|
}),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async (config) => {
|
|
calls.delete.push(config);
|
|
if (overrides.deleteError) throw overrides.deleteError;
|
|
return { data: { removed: true } };
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
return { mod, calls };
|
|
};
|
|
|
|
const invokeDeleteWatchedCase = async (fixture, request = {}) => {
|
|
const req = {
|
|
method: "DELETE",
|
|
query: { watchedCaseID: WATCHED_CASE_ID },
|
|
...request
|
|
};
|
|
const res = createRes();
|
|
await fixture.mod.default(req, res);
|
|
return { req, res };
|
|
};
|
|
|
|
test("deletewatchedcases rejects missing watchedCaseID without CRM access", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture();
|
|
const { res } = await invokeDeleteWatchedCase(fixture, { query: {} });
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"INVALID_WATCHED_CASE_ID"
|
|
);
|
|
assert.strictEqual(fixture.calls.session.length, 0);
|
|
assert.strictEqual(fixture.calls.token, 0);
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases rejects malformed and array watchedCaseID values", async () => {
|
|
for (const watchedCaseID of [
|
|
"not-a-guid",
|
|
` ${WATCHED_CASE_ID} `,
|
|
[WATCHED_CASE_ID]
|
|
]) {
|
|
const fixture = createDeleteWatchedCasesFixture();
|
|
const { res } = await invokeDeleteWatchedCase(fixture, {
|
|
query: { watchedCaseID }
|
|
});
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"INVALID_WATCHED_CASE_ID"
|
|
);
|
|
assert.strictEqual(fixture.calls.token, 0);
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
}
|
|
});
|
|
|
|
test("deletewatchedcases rejects non-DELETE methods without CRM access", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture();
|
|
const { res } = await invokeDeleteWatchedCase(fixture, { method: "GET" });
|
|
|
|
assert.strictEqual(res.state.statusCode, 405);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "METHOD_NOT_ALLOWED");
|
|
assert.strictEqual(fixture.calls.session.length, 0);
|
|
assert.strictEqual(fixture.calls.token, 0);
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases rejects missing session without CRM access", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture({ session: null });
|
|
const { req, res } = await invokeDeleteWatchedCase(fixture);
|
|
|
|
assert.strictEqual(res.state.statusCode, 401);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "UNAUTHENTICATED");
|
|
assert.strictEqual(fixture.calls.session[0][0], req);
|
|
assert.strictEqual(fixture.calls.session[0][1], res);
|
|
assert.strictEqual(fixture.calls.token, 0);
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases rejects session without email", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture({
|
|
session: { user: { id: "application-user" } }
|
|
});
|
|
const { res } = await invokeDeleteWatchedCase(fixture);
|
|
|
|
assert.strictEqual(res.state.statusCode, 401);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "UNAUTHENTICATED");
|
|
assert.strictEqual(fixture.calls.token, 0);
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases denies zero active CRM contacts", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture({ contacts: [] });
|
|
const { res } = await invokeDeleteWatchedCase(fixture);
|
|
|
|
assert.strictEqual(res.state.statusCode, 403);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CONTACT_IDENTITY_NOT_RESOLVED"
|
|
);
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases denies multiple active CRM contacts", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture({
|
|
contacts: [{ contactid: CONTACT_ID }, { contactid: OTHER_CONTACT_ID }]
|
|
});
|
|
const { res } = await invokeDeleteWatchedCase(fixture);
|
|
|
|
assert.strictEqual(res.state.statusCode, 403);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CONTACT_IDENTITY_NOT_RESOLVED"
|
|
);
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases fails closed when CRM contact lookup fails", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture({
|
|
contactLookupError: new Error("CRM unavailable")
|
|
});
|
|
const { res } = await invokeDeleteWatchedCase(fixture);
|
|
|
|
assert.strictEqual(res.state.statusCode, 500);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"WATCHED_CASE_DELETE_FAILED"
|
|
);
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases returns 404 for unknown watchlist", async () => {
|
|
const lookupError = new Error("not found");
|
|
lookupError.response = { status: 404 };
|
|
const fixture = createDeleteWatchedCasesFixture({
|
|
watchlistLookupError: lookupError
|
|
});
|
|
const { res } = await invokeDeleteWatchedCase(fixture);
|
|
|
|
assert.strictEqual(res.state.statusCode, 404);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "WATCHED_CASE_NOT_FOUND");
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases returns 404 for non-owned watchlist", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture({
|
|
watchlist: {
|
|
pinswg_watchlistid: WATCHED_CASE_ID,
|
|
_pinswg_contact_value: OTHER_CONTACT_ID
|
|
}
|
|
});
|
|
const { res } = await invokeDeleteWatchedCase(fixture);
|
|
|
|
assert.strictEqual(res.state.statusCode, 404);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "WATCHED_CASE_NOT_FOUND");
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases deletes exactly once for the authenticated CRM contact", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture();
|
|
const { req, res } = await invokeDeleteWatchedCase(fixture);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
|
|
removed: true
|
|
});
|
|
assert.strictEqual(fixture.calls.relay.length, 2);
|
|
assert.strictEqual(
|
|
fixture.calls.relay[0].queryUrl,
|
|
"contacts?$filter=emailaddress1 eq 'user.o''neill@test.local' and statuscode eq 1&$select=contactid"
|
|
);
|
|
assert.strictEqual(
|
|
fixture.calls.relay[1].queryUrl,
|
|
`pinswg_watchlists(${WATCHED_CASE_ID})?$select=pinswg_watchlistid,_pinswg_contact_value`
|
|
);
|
|
assert.strictEqual(fixture.calls.delete.length, 1);
|
|
assert.strictEqual(fixture.calls.delete[0].method, "delete");
|
|
assert.match(
|
|
fixture.calls.delete[0].url,
|
|
new RegExp(`pinswg_watchlists\\(${WATCHED_CASE_ID}\\)&hash=expected$`)
|
|
);
|
|
assert.strictEqual(fixture.calls.session[0][0], req);
|
|
});
|
|
|
|
test("deletewatchedcases ignores client-supplied contact and email identity", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture({
|
|
watchlist: {
|
|
pinswg_watchlistid: WATCHED_CASE_ID,
|
|
_pinswg_contact_value: OTHER_CONTACT_ID
|
|
}
|
|
});
|
|
const { res } = await invokeDeleteWatchedCase(fixture, {
|
|
query: {
|
|
watchedCaseID: WATCHED_CASE_ID,
|
|
contactid: OTHER_CONTACT_ID,
|
|
email: "other@test.local"
|
|
},
|
|
body: { contactid: OTHER_CONTACT_ID, email: "other@test.local" }
|
|
});
|
|
|
|
assert.strictEqual(res.state.statusCode, 404);
|
|
assert.match(fixture.calls.relay[0].queryUrl, /user\.o''neill@test\.local/);
|
|
assert.doesNotMatch(fixture.calls.relay[0].queryUrl, /other@test\.local/);
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcases does not let a valid HMAC override ownership", async () => {
|
|
const fixture = createDeleteWatchedCasesFixture({
|
|
watchlist: {
|
|
pinswg_watchlistid: WATCHED_CASE_ID,
|
|
_pinswg_contact_value: OTHER_CONTACT_ID
|
|
}
|
|
});
|
|
const { res } = await invokeDeleteWatchedCase(fixture, {
|
|
query: { watchedCaseID: WATCHED_CASE_ID, hash: "valid-signature" }
|
|
});
|
|
|
|
assert.strictEqual(res.state.statusCode, 404);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "WATCHED_CASE_NOT_FOUND");
|
|
assert.strictEqual(fixture.calls.delete.length, 0);
|
|
});
|
|
|
|
test("deletewatchedcasesproxy returns WATCHED_CASE_ID_REQUIRED when watchedCaseID missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/deletewatchedcasesproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: {} }) },
|
|
consoleLogger: () => {},
|
|
process: { env: {} }
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"WATCHED_CASE_ID_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("deletewatchedcasesproxy catch path returns WATCHED_CASE_PROXY_DELETE_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/deletewatchedcasesproxy_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
forwardGetData: async () => {
|
|
throw new Error("proxy delete failed");
|
|
},
|
|
azureHeaders: () => ({}),
|
|
consoleLogger: () => {},
|
|
process: { env: {} }
|
|
}
|
|
);
|
|
|
|
const req = { query: { watchedCaseID: "w1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"WATCHED_CASE_PROXY_DELETE_FAILED"
|
|
);
|
|
});
|
|
|
|
test("deleteawaitingsubmissions returns INCIDENT_ID_REQUIRED when incidentID missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/deleteawaitingsubmissions_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => ({ data: {} }),
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("deleteawaitingsubmissions catch path returns AWAITING_SUBMISSION_DELETE_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/deleteawaitingsubmissions_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => {
|
|
throw new Error("delete failed");
|
|
},
|
|
consoleLogger: () => {}
|
|
}
|
|
);
|
|
|
|
const req = { query: { incidentID: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"AWAITING_SUBMISSION_DELETE_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getlpa catch path returns LPA_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getlpa_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "LPA_FETCH_FAILED");
|
|
});
|
|
|
|
test("getappealid returns CASE_REFERENCE_REQUIRED when caseReference missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getappealid_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
azureHeaders: () => ({})
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
updateFormCollection: "pinswg_planningappeals78s",
|
|
primaryAttribute: "pinswg_planningappeals78id"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CASE_REFERENCE_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getappealid catch path returns APPEAL_ID_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getappealid_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
azureHeaders: () => ({})
|
|
});
|
|
|
|
const req = {
|
|
query: {
|
|
caseReference: "CAS-1",
|
|
updateFormCollection: "pinswg_planningappeals78s",
|
|
primaryAttribute: "pinswg_planningappeals78id"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "APPEAL_ID_FETCH_FAILED");
|
|
});
|
|
|
|
test("getprojecttypes catch path returns PROJECT_TYPES_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getprojecttypes_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"PROJECT_TYPES_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getappealtypes catch path returns APPEAL_TYPES_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getappealtypes_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
process: { env: {} }
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"APPEAL_TYPES_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getlinkedcases returns PARENT_INCIDENT_ID_REQUIRED when parentincidentid missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getlinkedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"PARENT_INCIDENT_ID_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getlinkedcases catch path returns LINKED_CASES_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getlinkedcases_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { parentincidentid: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"LINKED_CASES_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getformdata returns WHICH_FORM_REQUIRED when whichForm missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getformdata_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "WHICH_FORM_REQUIRED");
|
|
});
|
|
|
|
test("getformdata catch path returns FORM_DATA_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getformdata_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { whichForm: "planningappeals78" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "FORM_DATA_FETCH_FAILED");
|
|
});
|
|
|
|
test("getispublishedbyid returns SEARCH_STRING_REQUIRED when searchString missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getispublishedbyid_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "SEARCH_STRING_REQUIRED");
|
|
});
|
|
|
|
test("getispublishedbyid catch path returns IS_PUBLISHED_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getispublishedbyid_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { searchString: "incident-guid" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"IS_PUBLISHED_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getdnslist catch path returns DNS_LIST_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getdnslist_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
azureHeaders: () => ({}),
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "DNS_LIST_FETCH_FAILED");
|
|
});
|
|
|
|
test("getsipsevents returns CASE_ID_REQUIRED when caseid missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getsipsevents_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "CASE_ID_REQUIRED");
|
|
});
|
|
|
|
test("getsipsevents catch path returns SIPS_EVENTS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getsipsevents_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { caseid: "case-guid" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"SIPS_EVENTS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicpartsaveddetails returns APPEAL_TYPE_NAME_REQUIRED when appealTypeName missing", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicpartsaveddetails_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
azureHeadersNoOdata: () => ({})
|
|
}
|
|
);
|
|
|
|
const req = {
|
|
query: {
|
|
primaryIdAttribute: "pinswg_planningappeals78id",
|
|
incidentID: "i1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"APPEAL_TYPE_NAME_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("getbasicpartsaveddetails catch path returns BASIC_PART_SAVED_DETAILS_FETCH_FAILED", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getbasicpartsaveddetails_api.js",
|
|
{
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
azureHeadersNoOdata: () => ({})
|
|
}
|
|
);
|
|
|
|
const req = {
|
|
query: {
|
|
appealTypeName: "pinswg_planningappeals78s",
|
|
primaryIdAttribute: "pinswg_planningappeals78id",
|
|
incidentID: "i1"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_PART_SAVED_DETAILS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getbasicdnsurlsearch returns SEARCH_STRING_REQUIRED when searchString missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicdnsurlsearch_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "SEARCH_STRING_REQUIRED");
|
|
});
|
|
|
|
test("getbasicdnsurlsearch catch path returns BASIC_DNS_URL_SEARCH_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getbasicdnsurlsearch_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: { searchString: "farm" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"BASIC_DNS_URL_SEARCH_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getpartsavedappeal returns SEARCH_STRING_REQUIRED when searchString missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getpartsavedappeal_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "SEARCH_STRING_REQUIRED");
|
|
});
|
|
|
|
test("getpartsavedappeal catch path returns PART_SAVED_APPEAL_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getpartsavedappeal_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeadersPaged: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {},
|
|
_: { has: () => false }
|
|
});
|
|
|
|
const req = { query: { searchString: "CAS" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"PART_SAVED_APPEAL_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getrepresentations returns INCIDENT_ID_REQUIRED when incidentID missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getrepresentations_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getrepresentations catch path returns REPRESENTATIONS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getrepresentations_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { incidentID: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"REPRESENTATIONS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getrepresentations passes relayPolicy overrides to relayGet", async () => {
|
|
let capturedRelayPolicy = null;
|
|
|
|
const mod = loadModule("pages/api/endpoint/getrepresentations_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ relayPolicy, res }) => {
|
|
capturedRelayPolicy = relayPolicy;
|
|
return respondSuccessMock(res, { value: [] });
|
|
}
|
|
});
|
|
|
|
const req = { query: { incidentID: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(capturedRelayPolicy)), {
|
|
method: "GET",
|
|
timeoutMs: 8000,
|
|
maxRetries: 2,
|
|
retryBaseDelayMs: 150,
|
|
retryMaxDelayMs: 800
|
|
});
|
|
});
|
|
|
|
test("getdnscoords catch path returns DNS_COORDS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getdnscoords_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGetData: async () => {
|
|
throw new Error("relay failed");
|
|
},
|
|
consoleLogger: () => {},
|
|
OSPoint: function () {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"DNS_COORDS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("getappealpdfdocuments returns INCIDENT_ID_REQUIRED when incidentid missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getappealpdfdocuments_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async () => ({}),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: { get: async () => ({ data: { value: [] } }) },
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("getappealpdfdocuments catch path returns APPEAL_PDF_DOCUMENTS_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getappealpdfdocuments_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
relayGet: async ({ res, errorResponse }) =>
|
|
respondErrorMock(res, errorResponse),
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
azureHeaders: () => ({}),
|
|
axios: {
|
|
get: async () => {
|
|
throw new Error("relay failed");
|
|
}
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { incidentid: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"APPEAL_PDF_DOCUMENTS_FETCH_FAILED"
|
|
);
|
|
});
|
|
|
|
test("updatecase returns CASE_UPDATE_PAYLOAD_REQUIRED when body missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/updatecase_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => ({ data: {} }),
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
query: { appealObj: "a1", updateFormCollection: "pinswg_x" },
|
|
body: undefined
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.error.code,
|
|
"CASE_UPDATE_PAYLOAD_REQUIRED"
|
|
);
|
|
});
|
|
|
|
test("updatecase catch path returns CASE_UPDATE_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/updatecase_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => {
|
|
throw new Error("update failed");
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = {
|
|
query: { appealObj: "a1", updateFormCollection: "pinswg_x" },
|
|
body: { title: "updated" }
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "CASE_UPDATE_FAILED");
|
|
});
|
|
|
|
test("patchcase returns INCIDENT_ID_REQUIRED when incidentid missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/patchcase_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => ({ data: {} }),
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INCIDENT_ID_REQUIRED");
|
|
});
|
|
|
|
test("patchcase catch path returns CASE_PATCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/patchcase_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
getToken: async () => ({ access_token: "token" }),
|
|
hashAPIPath: () => "&hash=expected",
|
|
axios: async () => {
|
|
throw new Error("patch failed");
|
|
},
|
|
consoleLogger: () => {}
|
|
});
|
|
|
|
const req = { query: { incidentid: "i1" } };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "CASE_PATCH_FAILED");
|
|
});
|
|
|
|
const trustedContactOrigin = "https://portal.example.test";
|
|
const trustedWelshContactOrigin = "https://porth.example.test";
|
|
|
|
const contactSubjects = {
|
|
plq: {
|
|
en: "Questions about Planning legislation or policy",
|
|
cy: "Ymholiad deddfwriaeth gynllunio"
|
|
},
|
|
ipq: {
|
|
en: "Questions or comments about applications for major infrastructure projects",
|
|
cy: "Ymholiad gweithdrefn seilwaith"
|
|
},
|
|
pcpq: {
|
|
en: "Questions or comments about planning and environmental appeals",
|
|
cy: "Ymholiad gweithdrefn gwaith achos cynllunio"
|
|
},
|
|
pi: { en: "Query about using the Casework Portal", cy: "Materion Porth" },
|
|
appadvice: { en: "Advice How to submit an appeal", cy: "Cyngor cyflwyno apêl" },
|
|
repadvice: {
|
|
en: "Advice How to comment on an appeal or application",
|
|
cy: "Cyngor cyflwyno sylwadau"
|
|
},
|
|
ceq: {
|
|
en: "Queries about forthcoming Hearing or Inquiry event",
|
|
cy: "Ymholiad Digwyddiadau Gwaith Achos"
|
|
},
|
|
other: { en: "Other enquiry for PEDW", cy: "Unrhyw Ymholiadau Eraill" },
|
|
postdec: {
|
|
en: "Issues or questions about a case after the decision is issued",
|
|
cy: "Ar ôl Penderfyniad"
|
|
},
|
|
comp: {
|
|
en: "General Complaints of Compliments",
|
|
cy: "Cwynion/Canmoliaethau"
|
|
}
|
|
};
|
|
|
|
const contactTeamIds = {
|
|
plq: "ec48450c-7e26-ec11-a97f-00224800e98c",
|
|
ipq: "7fb9e598-7d26-ec11-a97f-00224800e98c",
|
|
pcpq: "8ffabad9-7c26-ec11-a97f-00224800e98c",
|
|
pi: "5554882f-4606-ec11-a97f-00224800d374",
|
|
appadvice: "cc3d987e-7c26-ec11-a97f-00224800e98c",
|
|
repadvice: "cc3d987e-7c26-ec11-a97f-00224800e98c",
|
|
ceq: "4fddd7e8-7d26-ec11-a97f-00224800e98c",
|
|
other: "8ffabad9-7c26-ec11-a97f-00224800e98c",
|
|
postdec: "1357e457-7e26-ec11-a97f-00224800e98c",
|
|
comp: "1357e457-7e26-ec11-a97f-00224800e98c"
|
|
};
|
|
|
|
const validContactTaskRequest = (overrides = {}) => ({
|
|
method: "POST",
|
|
headers: {
|
|
origin: trustedContactOrigin,
|
|
"content-type": "application/json; charset=utf-8"
|
|
},
|
|
body: {
|
|
contactEmail: "user@example.com",
|
|
contactSubject: contactSubjects.plq.en,
|
|
contactbody: "Please help with my enquiry.",
|
|
typeOfContact: "plq"
|
|
},
|
|
...overrides
|
|
});
|
|
|
|
const loadContactTaskEndpoint = (overrides = {}) => {
|
|
let tokenCalls = 0;
|
|
const relayCalls = [];
|
|
const axios =
|
|
overrides.axios ||
|
|
(async (config) => {
|
|
relayCalls.push(config);
|
|
return { data: { taskId: "crm-1" } };
|
|
});
|
|
|
|
const mod = loadModule("pages/api/endpoint/createcrmtask_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
isNonEmptyString: (value) =>
|
|
typeof value === "string" && value.trim().length > 0,
|
|
sanitizeString: (value) =>
|
|
typeof value === "string" ? value.trim() : "",
|
|
getToken: async () => {
|
|
tokenCalls += 1;
|
|
return { access_token: "token" };
|
|
},
|
|
hashAPIPath: () => "?hash=expected",
|
|
axios,
|
|
consoleLogger: () => {},
|
|
process: {
|
|
env: {
|
|
NEXTAUTH_URL: trustedContactOrigin,
|
|
CY_API_ROOT: trustedWelshContactOrigin,
|
|
RELAY_ROOT: "https://relay.example/"
|
|
}
|
|
},
|
|
...overrides
|
|
});
|
|
|
|
return {
|
|
mod,
|
|
getTokenCalls: () => tokenCalls,
|
|
getRelayCalls: () => relayCalls
|
|
};
|
|
};
|
|
|
|
const assertContactTaskRejectedBeforeRelay = async ({ req, status, code }) => {
|
|
const loaded = loadContactTaskEndpoint();
|
|
const res = createRes();
|
|
|
|
await loaded.mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, status);
|
|
assert.strictEqual(res.state.jsonBody.error.code, code);
|
|
assert.strictEqual(loaded.getTokenCalls(), 0);
|
|
assert.strictEqual(loaded.getRelayCalls().length, 0);
|
|
};
|
|
|
|
test("createcrmtask accepts a valid anonymous public Contact Us POST", async () => {
|
|
const loaded = loadContactTaskEndpoint();
|
|
const res = createRes();
|
|
|
|
await loaded.mod.default(validContactTaskRequest(), res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(loaded.getTokenCalls(), 1);
|
|
assert.strictEqual(loaded.getRelayCalls().length, 1);
|
|
});
|
|
|
|
test("createcrmtask accepts a valid portal Contact Us payload", async () => {
|
|
const loaded = loadContactTaskEndpoint();
|
|
const req = validContactTaskRequest({
|
|
headers: {
|
|
origin: trustedWelshContactOrigin,
|
|
"content-type": "application/json"
|
|
},
|
|
body: {
|
|
contactEmail: "portal.user@example.com",
|
|
contactSubject: contactSubjects.repadvice.cy,
|
|
contactbody: "Mae angen cymorth arnaf.",
|
|
typeOfContact: "repadvice"
|
|
}
|
|
});
|
|
const res = createRes();
|
|
|
|
await loaded.mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(loaded.getTokenCalls(), 1);
|
|
assert.strictEqual(loaded.getRelayCalls().length, 1);
|
|
});
|
|
|
|
test("createcrmtask preserves all category-to-team assignments", async () => {
|
|
for (const [typeOfContact, teamId] of Object.entries(contactTeamIds)) {
|
|
const loaded = loadContactTaskEndpoint();
|
|
const req = validContactTaskRequest({
|
|
body: {
|
|
contactEmail: "user@example.com",
|
|
contactSubject: contactSubjects[typeOfContact].en,
|
|
contactbody: "Please help with my enquiry.",
|
|
typeOfContact
|
|
}
|
|
});
|
|
const res = createRes();
|
|
|
|
await loaded.mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
const payload = JSON.parse(loaded.getRelayCalls()[0].data);
|
|
assert.strictEqual(payload["ownerid@odata.bind"], `/teams(${teamId})`);
|
|
}
|
|
});
|
|
|
|
for (const method of ["GET", "PUT", "DELETE"]) {
|
|
test(`createcrmtask rejects ${method} before CRM processing`, async () => {
|
|
const req = validContactTaskRequest({ method });
|
|
const loaded = loadContactTaskEndpoint();
|
|
const res = createRes();
|
|
|
|
await loaded.mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 405);
|
|
assert.strictEqual(res.state.headers.allow, "POST");
|
|
assert.strictEqual(res.state.jsonBody.error.code, "METHOD_NOT_ALLOWED");
|
|
assert.strictEqual(loaded.getTokenCalls(), 0);
|
|
assert.strictEqual(loaded.getRelayCalls().length, 0);
|
|
});
|
|
}
|
|
|
|
for (const contentType of [
|
|
"application/x-www-form-urlencoded",
|
|
"text/plain",
|
|
"multipart/form-data; boundary=test"
|
|
]) {
|
|
test(`createcrmtask rejects ${contentType} before CRM processing`, async () => {
|
|
const req = validContactTaskRequest({
|
|
headers: { origin: trustedContactOrigin, "content-type": contentType }
|
|
});
|
|
await assertContactTaskRejectedBeforeRelay({
|
|
req,
|
|
status: 415,
|
|
code: "UNSUPPORTED_MEDIA_TYPE"
|
|
});
|
|
});
|
|
}
|
|
|
|
test("createcrmtask rejects an untrusted Origin before CRM processing", async () => {
|
|
const req = validContactTaskRequest({
|
|
headers: {
|
|
origin: "https://attacker.example",
|
|
"content-type": "application/json"
|
|
}
|
|
});
|
|
await assertContactTaskRejectedBeforeRelay({ req, status: 403, code: "FORBIDDEN" });
|
|
});
|
|
|
|
test("createcrmtask accepts each configured trusted Origin", async () => {
|
|
for (const origin of [trustedContactOrigin, trustedWelshContactOrigin]) {
|
|
const loaded = loadContactTaskEndpoint();
|
|
const req = validContactTaskRequest({
|
|
headers: { origin, "content-type": "application/json" }
|
|
});
|
|
const res = createRes();
|
|
|
|
await loaded.mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(loaded.getTokenCalls(), 1);
|
|
}
|
|
});
|
|
|
|
test("createcrmtask conservatively rejects a missing Origin", async () => {
|
|
const req = validContactTaskRequest({ headers: { "content-type": "application/json" } });
|
|
await assertContactTaskRejectedBeforeRelay({ req, status: 403, code: "FORBIDDEN" });
|
|
});
|
|
|
|
for (const body of [null, [], "not-an-object"]) {
|
|
test(`createcrmtask rejects malformed body ${JSON.stringify(body)}`, async () => {
|
|
const req = validContactTaskRequest({ body });
|
|
await assertContactTaskRejectedBeforeRelay({
|
|
req,
|
|
status: 400,
|
|
code: "INVALID_REQUEST_BODY"
|
|
});
|
|
});
|
|
}
|
|
|
|
for (const contactEmail of [undefined, "invalid", `${"a".repeat(190)}@example.com`]) {
|
|
test(`createcrmtask rejects invalid email ${String(contactEmail).slice(0, 30)}`, async () => {
|
|
const req = validContactTaskRequest({
|
|
body: {
|
|
contactEmail,
|
|
contactSubject: contactSubjects.plq.en,
|
|
contactbody: "Details",
|
|
typeOfContact: "plq"
|
|
}
|
|
});
|
|
await assertContactTaskRejectedBeforeRelay({
|
|
req,
|
|
status: 400,
|
|
code: "INVALID_CONTACT_EMAIL"
|
|
});
|
|
});
|
|
}
|
|
|
|
for (const typeOfContact of [undefined, "unsupported"]) {
|
|
test(`createcrmtask rejects category ${String(typeOfContact)}`, async () => {
|
|
const req = validContactTaskRequest({
|
|
body: {
|
|
contactEmail: "user@example.com",
|
|
contactSubject: contactSubjects.plq.en,
|
|
contactbody: "Details",
|
|
typeOfContact
|
|
}
|
|
});
|
|
await assertContactTaskRejectedBeforeRelay({
|
|
req,
|
|
status: 400,
|
|
code: "INVALID_CONTACT_TYPE"
|
|
});
|
|
});
|
|
}
|
|
|
|
for (const contactbody of [undefined, " ", "a".repeat(801)]) {
|
|
test(`createcrmtask rejects invalid message ${String(contactbody).slice(0, 20)}`, async () => {
|
|
const req = validContactTaskRequest({
|
|
body: {
|
|
contactEmail: "user@example.com",
|
|
contactSubject: contactSubjects.plq.en,
|
|
contactbody,
|
|
typeOfContact: "plq"
|
|
}
|
|
});
|
|
await assertContactTaskRejectedBeforeRelay({
|
|
req,
|
|
status: 400,
|
|
code: "INVALID_CONTACT_BODY"
|
|
});
|
|
});
|
|
}
|
|
|
|
test("createcrmtask rejects caller-supplied CRM ownership fields", async () => {
|
|
for (const field of ["ownerid", "ownerid@odata.bind", "teamId"]) {
|
|
const req = validContactTaskRequest({
|
|
body: { ...validContactTaskRequest().body, [field]: "attacker-owner" }
|
|
});
|
|
await assertContactTaskRejectedBeforeRelay({
|
|
req,
|
|
status: 400,
|
|
code: "UNSUPPORTED_REQUEST_FIELD"
|
|
});
|
|
}
|
|
});
|
|
|
|
test("createcrmtask accepts existing English and Welsh subjects for every category", async () => {
|
|
for (const [typeOfContact, subjects] of Object.entries(contactSubjects)) {
|
|
for (const contactSubject of [subjects.en, subjects.cy]) {
|
|
const loaded = loadContactTaskEndpoint();
|
|
const req = validContactTaskRequest({
|
|
body: {
|
|
contactEmail: "user@example.com",
|
|
contactSubject,
|
|
contactbody: "Details",
|
|
typeOfContact
|
|
}
|
|
});
|
|
const res = createRes();
|
|
|
|
await loaded.mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
const payload = JSON.parse(loaded.getRelayCalls()[0].data);
|
|
assert.strictEqual(payload.subject, `Contact Us Enquiry - ${contactSubject}`);
|
|
}
|
|
}
|
|
});
|
|
|
|
test("createcrmtask rejects an arbitrary or mismatched subject before CRM processing", async () => {
|
|
for (const contactSubject of ["Arbitrary subject", contactSubjects.ipq.en]) {
|
|
const req = validContactTaskRequest({
|
|
body: { ...validContactTaskRequest().body, contactSubject }
|
|
});
|
|
await assertContactTaskRejectedBeforeRelay({
|
|
req,
|
|
status: 400,
|
|
code: "INVALID_CONTACT_SUBJECT"
|
|
});
|
|
}
|
|
});
|
|
|
|
test("createcrmtask catch path returns CRM_TASK_CREATE_FAILED", async () => {
|
|
let tokenCalls = 0;
|
|
const mod = loadModule("pages/api/endpoint/createcrmtask_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
isNonEmptyString: (value) =>
|
|
typeof value === "string" && value.trim().length > 0,
|
|
sanitizeString: (value) =>
|
|
typeof value === "string" ? value.trim() : "",
|
|
getToken: async () => {
|
|
tokenCalls += 1;
|
|
return { access_token: "token" };
|
|
},
|
|
hashAPIPath: () => "?hash=expected",
|
|
axios: async () => {
|
|
throw new Error("create failed");
|
|
},
|
|
consoleLogger: () => {},
|
|
process: {
|
|
env: {
|
|
NEXTAUTH_URL: trustedContactOrigin,
|
|
CY_API_ROOT: trustedWelshContactOrigin,
|
|
RELAY_ROOT: "https://relay.example/"
|
|
}
|
|
}
|
|
});
|
|
const res = createRes();
|
|
|
|
await mod.default(validContactTaskRequest(), res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "CRM_TASK_CREATE_FAILED");
|
|
assert.strictEqual(tokenCalls, 1);
|
|
});
|
|
|
|
test("gethash returns UNAUTHENTICATED when session missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/gethash_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
hashAPIPath: () => "&hash=expected",
|
|
getServerSession: async () => null,
|
|
authOptions: () => ({}),
|
|
nextConnect: () => {
|
|
const handler = { registeredGet: null };
|
|
handler.get = (cb) => {
|
|
handler.registeredGet = cb;
|
|
return handler;
|
|
};
|
|
return handler;
|
|
}
|
|
});
|
|
|
|
const req = { query: { path: "/api/endpoint/getportallogin_api?x=1" } };
|
|
const res = createRes();
|
|
await mod.default.registeredGet(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 401);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "UNAUTHENTICATED");
|
|
});
|
|
|
|
test("gethash returns INVALID_HASH_PATH when path is invalid", async () => {
|
|
const mod = loadModule("pages/api/endpoint/gethash_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
hashAPIPath: () => "&hash=expected",
|
|
getServerSession: async () => ({
|
|
user: { email: "user@test.local" }
|
|
}),
|
|
authOptions: () => ({}),
|
|
nextConnect: () => {
|
|
const handler = { registeredGet: null };
|
|
handler.get = (cb) => {
|
|
handler.registeredGet = cb;
|
|
return handler;
|
|
};
|
|
return handler;
|
|
}
|
|
});
|
|
|
|
const req = { query: { path: "/api/endpoint/gethash_api" } };
|
|
const res = createRes();
|
|
await mod.default.registeredGet(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "INVALID_HASH_PATH");
|
|
});
|
|
|
|
test("getpicklists returns WHICH_FORM_REQUIRED when whichForm missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getpicklists_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "WHICH_FORM_REQUIRED");
|
|
});
|
|
|
|
test("getmandatoryfields returns WHICH_FORM_REQUIRED when whichForm missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getmandatoryfields_api.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock
|
|
});
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "WHICH_FORM_REQUIRED");
|
|
});
|
|
|
|
test("getappealtypesfornewappeal returns success payload contract", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getappealtypesfornewappeal_api.js",
|
|
{
|
|
respondSuccess: respondSuccessMock
|
|
}
|
|
);
|
|
|
|
const req = { query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(Array.isArray(res.state.jsonBody.value), true);
|
|
assert.strictEqual(
|
|
res.state.jsonBody.value[0].value,
|
|
"Planning Appeal - S78"
|
|
);
|
|
});
|
|
|
|
test("getToken success returns token payload contract", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getToken.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
axios: {
|
|
post: async () => ({
|
|
data: {
|
|
access_token: "token",
|
|
token_type: "Bearer"
|
|
}
|
|
})
|
|
},
|
|
process: {
|
|
env: {
|
|
ACCESS_TOKEN_ENDPOINT: "https://login.microsoftonline.com/",
|
|
TENANT: "tenant-id",
|
|
GRANT_TYPE: "client_credentials",
|
|
CLIENT_ID: "client-id",
|
|
CLIENT_SECRET: "secret",
|
|
RELAYURI: "relay.example"
|
|
}
|
|
}
|
|
});
|
|
|
|
const req = { body: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
|
|
access_token: "token",
|
|
token_type: "Bearer"
|
|
});
|
|
});
|
|
|
|
test("getToken catch path returns TOKEN_FETCH_FAILED", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getToken.js", {
|
|
respondError: respondErrorMock,
|
|
respondSuccess: respondSuccessMock,
|
|
axios: {
|
|
post: async () => {
|
|
throw new Error("token fetch failed");
|
|
}
|
|
},
|
|
process: {
|
|
env: {
|
|
ACCESS_TOKEN_ENDPOINT: "https://login.microsoftonline.com/",
|
|
TENANT: "tenant-id",
|
|
GRANT_TYPE: "client_credentials",
|
|
CLIENT_ID: "client-id",
|
|
CLIENT_SECRET: "secret",
|
|
RELAYURI: "relay.example"
|
|
}
|
|
}
|
|
});
|
|
|
|
const req = { body: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "TOKEN_FETCH_FAILED");
|
|
});
|
|
|
|
test("getsipsmedia returns success contract", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getsipsmedia_api.js", {
|
|
respondError: respondErrorMock,
|
|
relayGet: async ({ res }) =>
|
|
respondSuccessMock(res, {
|
|
"@odata.count": 4,
|
|
value: []
|
|
})
|
|
});
|
|
|
|
const req = {
|
|
method: "GET",
|
|
query: {
|
|
caseid: "11111111-1111-4111-8111-111111111111"
|
|
}
|
|
};
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 200);
|
|
assert.strictEqual(res.state.jsonBody["@odata.count"], 4);
|
|
});
|
|
|
|
test("getsipsmedia returns CASE_ID_REQUIRED when caseid missing", async () => {
|
|
const mod = loadModule("pages/api/endpoint/getsipsmedia_api.js", {
|
|
respondError: respondErrorMock
|
|
});
|
|
|
|
const req = { method: "POST", query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 400);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "CASE_ID_REQUIRED");
|
|
});
|
|
|
|
test("getappealtypesfornewappeal returns METHOD_NOT_ALLOWED for non-GET methods", async () => {
|
|
const mod = loadModule(
|
|
"pages/api/endpoint/getappealtypesfornewappeal_api.js",
|
|
{
|
|
respondSuccess: respondSuccessMock,
|
|
respondError: respondErrorMock
|
|
}
|
|
);
|
|
|
|
const req = { method: "POST", query: {} };
|
|
const res = createRes();
|
|
await mod.default(req, res);
|
|
|
|
assert.strictEqual(res.state.statusCode, 405);
|
|
assert.strictEqual(res.state.jsonBody.error.code, "METHOD_NOT_ALLOWED");
|
|
});
|
|
|
|
const run = async () => {
|
|
const filter = process.env.PEDW_TEST_FILTER;
|
|
|
|
const selectedTests = filter
|
|
? tests.filter((currentTest) => currentTest.name.includes(filter))
|
|
: tests;
|
|
|
|
if (selectedTests.length === 0) {
|
|
throw new Error(`No tests match filter: ${filter}`);
|
|
}
|
|
|
|
let passed = 0;
|
|
|
|
for (const currentTest of selectedTests) {
|
|
await currentTest.fn();
|
|
passed += 1;
|
|
}
|
|
|
|
console.log(
|
|
`Phase 21 endpoint-handler contract tests passed (${passed}/${selectedTests.length}).`
|
|
);
|
|
};
|
|
|
|
module.exports = run;
|
|
|
|
if (require.main === module) {
|
|
run().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|
|
}
|