diff --git a/pages/api/endpoint/getbasicsearch_by_lparref_api.js b/pages/api/endpoint/getbasicsearch_by_lparref_api.js index f50f2db8..228bf990 100644 --- a/pages/api/endpoint/getbasicsearch_by_lparref_api.js +++ b/pages/api/endpoint/getbasicsearch_by_lparref_api.js @@ -1,9 +1,9 @@ import axios from "axios"; -import CryptoJS from "crypto-js"; import { azureHeaders } from "../../../actions/core/headers"; import { consoleLogger } from "../../../actions/core/logger"; import { getToken } from "../../../actions/core/token"; import { hashAPIPath } from "../../../actions/core/hash"; +import { respondError, respondSuccess } from "../middleware/apiResponse"; const WEBAPI_URL = process.env.RELAY_ROOT || @@ -285,9 +285,11 @@ export default async function ApiProxy(req, res) { let lpaRef = (req.query.lpaRef || "").trim(); if (!lpaRef) { - return res - .status(400) - .json({ error: "Missing required query param: lpaRef" }); + return respondError(res, { + status: 400, + code: "LPA_REF_REQUIRED", + message: "lpaRef is required" + }); } // ✅ Escape single quotes for OData @@ -298,10 +300,6 @@ export default async function ApiProxy(req, res) { // contains(tolower(pinswg_lpaapplicationreference), 'lowered search') const lowered = lpaRef.toLowerCase(); - console.log( - `\n=== LPA REF SEARCH ===\nSearching for "${lpaRef}" (case-insensitive contains)\nAcross ${appealTypeArrayWithLpaRef.length} entity types\n======================\n` - ); - const resultsPerType = await Promise.all( appealTypeArrayWithLpaRef.map(async (item) => { // You can expand/select more fields if needed, but keep light for speed @@ -323,17 +321,6 @@ export default async function ApiProxy(req, res) { `&$count=true` + `&$orderby=modifiedon desc`; - console.log( - "\n------------------------------------------\n", - "Entity:", - item.LogicalCollectionName, - "\nQuery:", - queryUrl, - "\nFull:", - WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), - "\n------------------------------------------\n" - ); - const { data } = await axios.get( WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), azureHeaders(token.access_token) @@ -353,10 +340,6 @@ export default async function ApiProxy(req, res) { ] || null })); - console.log( - `Returned ${normalized.length} records from ${item.LogicalCollectionName}` - ); - return normalized; }) ); @@ -372,9 +355,13 @@ export default async function ApiProxy(req, res) { value: flattened }; - return res.status(200).json(output); + return respondSuccess(res, output); } catch (error) { consoleLogger(error); - return res.status(400).json(error); + return respondError(res, { + status: 400, + code: "BASIC_SEARCH_LPA_REF_FETCH_FAILED", + message: "Failed to fetch basic search by lpa reference" + }); } } diff --git a/pages/api/endpoint/getbasicsearchdetails_api.js b/pages/api/endpoint/getbasicsearchdetails_api.js index 7370f714..1224ace0 100644 --- a/pages/api/endpoint/getbasicsearchdetails_api.js +++ b/pages/api/endpoint/getbasicsearchdetails_api.js @@ -30,80 +30,114 @@ */ import axios from "axios"; -import CryptoJS from "crypto-js"; import { azureHeaders } from "../../../actions/core/headers"; import { consoleLogger } from "../../../actions/core/logger"; import { getToken } from "../../../actions/core/token"; import { getSelectQuery } from "../../../actions/selectQueryTypes"; import { getNavigationPropertyByPrimaryAttribute } from "../../../components/utils"; import { hashAPIPath } from "../../../actions/core/hash"; +import { respondError, respondSuccess } from "../middleware/apiResponse"; const WEBAPI_URL = process.env.RELAY_ROOT || "https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/"; export default async function ApiProxy(req, res) { - var appealTypeName = req.query.appealTypeName; - var primaryIdAttribute = req.query.primaryIdAttribute; - var incidentID = req.query.incidentID; - var token = await getToken(); + const appealTypeName = req.query.appealTypeName; + const primaryIdAttribute = req.query.primaryIdAttribute; + const incidentID = req.query.incidentID; - let navigationProperty = - getNavigationPropertyByPrimaryAttribute( - primaryIdAttribute - ).NavigationProperty; + if ( + typeof appealTypeName !== "string" || + appealTypeName.trim().length === 0 + ) { + return respondError(res, { + status: 400, + code: "APPEAL_TYPE_NAME_REQUIRED", + message: "appealTypeName is required" + }); + } - var queryUrl = - appealTypeName + - "?$filter=_" + - (primaryIdAttribute == "pinswg_sipscase" - ? "pinswg_sipscase_value" - : primaryIdAttribute + "s_value ") + - " eq " + - incidentID + - "&$count=true" + - "&$expand=" + - navigationProperty + - "($select=ticketnumber)"; + if ( + typeof primaryIdAttribute !== "string" || + primaryIdAttribute.trim().length === 0 + ) { + return respondError(res, { + status: 400, + code: "PRIMARY_ID_ATTRIBUTE_REQUIRED", + message: "primaryIdAttribute is required" + }); + } - //" and statuscode eq 1&$count=true"; + if (typeof incidentID !== "string" || incidentID.trim().length === 0) { + return respondError(res, { + status: 400, + code: "INCIDENT_ID_REQUIRED", + message: "incidentID is required" + }); + } - // queryUrl = - // queryUrl + - // getSelectQuery(appealTypeName) + - // ",_" + - // (primaryIdAttribute == "pinswg_sipscase" - // ? "pinswg_sipscase_value" - // : primaryIdAttribute + "s_value"); + try { + const token = await getToken(); - queryUrl = queryUrl + getSelectQuery(appealTypeName); + const navigationProperty = + getNavigationPropertyByPrimaryAttribute( + primaryIdAttribute + ).NavigationProperty; - // console.log( - // "\n==========================================\n", - // "\nSearch Details query ", - // "\nAppealType: " + appealTypeName, - // "\nIncident ID: " + incidentID, - // "\n\nQuery url: " + queryUrl, - // "\n==========================================\n" - // ); + let queryUrl = + appealTypeName + + "?$filter=_" + + (primaryIdAttribute == "pinswg_sipscase" + ? "pinswg_sipscase_value" + : primaryIdAttribute + "s_value ") + + " eq " + + incidentID + + "&$count=true" + + "&$expand=" + + navigationProperty + + "($select=ticketnumber)"; - return axios - .get( + //" and statuscode eq 1&$count=true"; + + // queryUrl = + // queryUrl + + // getSelectQuery(appealTypeName) + + // ",_" + + // (primaryIdAttribute == "pinswg_sipscase" + // ? "pinswg_sipscase_value" + // : primaryIdAttribute + "s_value"); + + queryUrl = queryUrl + getSelectQuery(appealTypeName); + + // console.log( + // "\n==========================================\n", + // "\nSearch Details query ", + // "\nAppealType: " + appealTypeName, + // "\nIncident ID: " + incidentID, + // "\n\nQuery url: " + queryUrl, + // "\n==========================================\n" + // ); + + const { data } = await axios.get( WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), azureHeaders(token.access_token) - ) - .then(({ data }) => { - let flattened = data.value.map((r) => ({ - ...r, - ticketnumber: r[navigationProperty]?.ticketnumber || null - })); + ); - data.value = flattened; + let flattened = data.value.map((r) => ({ + ...r, + ticketnumber: r[navigationProperty]?.ticketnumber || null + })); - res.status(200).json(data); - }) - .catch((error) => { - consoleLogger(error); - res.status(400).json(error); + data.value = flattened; + + return respondSuccess(res, data); + } catch (error) { + consoleLogger(error); + return respondError(res, { + status: 400, + code: "BASIC_SEARCH_DETAILS_FETCH_FAILED", + message: "Failed to fetch basic search details" }); + } } diff --git a/pages/api/endpoint/getbasicsearchdetailspaged_api.js b/pages/api/endpoint/getbasicsearchdetailspaged_api.js index e12924db..ba20d7a7 100644 --- a/pages/api/endpoint/getbasicsearchdetailspaged_api.js +++ b/pages/api/endpoint/getbasicsearchdetailspaged_api.js @@ -30,7 +30,6 @@ */ import axios from "axios"; -import CryptoJS from "crypto-js"; import _ from "lodash"; import { azureHeadersPaged } from "../../../actions/core/headers"; import { consoleLogger } from "../../../actions/core/logger"; @@ -38,82 +37,105 @@ import { getToken } from "../../../actions/core/token"; import { getSelectQuery } from "../../../actions/selectQueryTypes"; import { getNavigationPropertyByPrimaryAttribute } from "../../../components/utils"; import { hashAPIPath } from "../../../actions/core/hash"; +import { respondError, respondSuccess } from "../middleware/apiResponse"; const WEBAPI_URL = process.env.RELAY_ROOT || "https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/"; export default async function ApiProxy(req, res) { - var appealTypeName = req.query.appealTypeName; - var primaryIdAttribute = req.query.primaryIdAttribute; - var incidentID = req.query.incidentID; + const appealTypeName = req.query.appealTypeName; + const primaryIdAttribute = req.query.primaryIdAttribute; + const incidentID = req.query.incidentID; if ( - !appealTypeName || - !primaryIdAttribute || - !incidentID || - String(appealTypeName).trim().length === 0 || - String(primaryIdAttribute).trim().length === 0 || - String(incidentID).trim().length === 0 + typeof appealTypeName !== "string" || + appealTypeName.trim().length === 0 ) { - return res.status(400).json(); + return respondError(res, { + status: 400, + code: "APPEAL_TYPE_NAME_REQUIRED", + message: "appealTypeName is required" + }); } - var token = await getToken(); + if ( + typeof primaryIdAttribute !== "string" || + primaryIdAttribute.trim().length === 0 + ) { + return respondError(res, { + status: 400, + code: "PRIMARY_ID_ATTRIBUTE_REQUIRED", + message: "primaryIdAttribute is required" + }); + } - let navigationProperty = - getNavigationPropertyByPrimaryAttribute( - primaryIdAttribute - ).NavigationProperty; + if (typeof incidentID !== "string" || incidentID.trim().length === 0) { + return respondError(res, { + status: 400, + code: "INCIDENT_ID_REQUIRED", + message: "incidentID is required" + }); + } - // "?$filter=_" + - // (primaryIdAttribute == "pinswg_sipscase" - // ? "pinswg_sipscase_value" - // : primaryIdAttribute + "s_value ") + - // " eq " + - // incidentID + + try { + const token = await getToken(); - var queryUrl = - appealTypeName + - "?$filter=" + - incidentID + - "&$count=true" + - "&$expand=" + - navigationProperty + - "($select=ticketnumber)"; + const navigationProperty = + getNavigationPropertyByPrimaryAttribute( + primaryIdAttribute + ).NavigationProperty; - //" and statuscode eq 1&$count=true"; + // "?$filter=_" + + // (primaryIdAttribute == "pinswg_sipscase" + // ? "pinswg_sipscase_value" + // : primaryIdAttribute + "s_value ") + + // " eq " + + // incidentID + - queryUrl = - queryUrl + - getSelectQuery(appealTypeName) + - ",_" + - (primaryIdAttribute == "pinswg_sipscase" - ? "pinswg_sipscase_value" - : primaryIdAttribute + "s_value"); + let queryUrl = + appealTypeName + + "?$filter=" + + incidentID + + "&$count=true" + + "&$expand=" + + navigationProperty + + "($select=ticketnumber)"; - return axios - .get( + //" and statuscode eq 1&$count=true"; + + queryUrl = + queryUrl + + getSelectQuery(appealTypeName) + + ",_" + + (primaryIdAttribute == "pinswg_sipscase" + ? "pinswg_sipscase_value" + : primaryIdAttribute + "s_value"); + + const { data } = await axios.get( WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), azureHeadersPaged(token.access_token) - ) - .then(({ data }) => { - let flattened = data.value.map((r) => ({ - ...r, - ticketnumber: r[navigationProperty]?.ticketnumber || null - })); + ); - data.value = flattened; + let flattened = data.value.map((r) => ({ + ...r, + ticketnumber: r[navigationProperty]?.ticketnumber || null + })); - var dataStr; - _.has(data, "@odata.nextLink") == true && - ((dataStr = JSON.stringify(data["@odata.nextLink"])), - (data["@odata.nextLink"] = dataStr.split("/v8.2/")[1])); + data.value = flattened; - return res.status(200).json(data); - }) - .catch((error) => { - consoleLogger(error); - res.status(400).json(error); + if (_.has(data, "@odata.nextLink") === true) { + const dataStr = JSON.stringify(data["@odata.nextLink"]); + data["@odata.nextLink"] = dataStr.split("/v8.2/")[1]; + } + + return respondSuccess(res, data); + } catch (error) { + consoleLogger(error); + return respondError(res, { + status: 400, + code: "BASIC_SEARCH_DETAILS_PAGED_FETCH_FAILED", + message: "Failed to fetch paged basic search details" }); + } } diff --git a/pages/api/endpoint/getbasicsearchpaged_api.js b/pages/api/endpoint/getbasicsearchpaged_api.js index 547f5846..12bd6d36 100644 --- a/pages/api/endpoint/getbasicsearchpaged_api.js +++ b/pages/api/endpoint/getbasicsearchpaged_api.js @@ -48,70 +48,96 @@ import { azureHeadersPagedCustom } from "../../../actions/core/headers"; import { consoleLogger } from "../../../actions/core/logger"; import { getToken } from "../../../actions/core/token"; import { hashAPIPath } from "../../../actions/core/hash"; +import { respondError, respondSuccess } from "../middleware/apiResponse"; const WEBAPI_URL = process.env.RELAY_ROOT || "https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/"; export default async function ApiProxy(req, res) { - var searchString = req.query.searchString; - var pageNumber = req.query.pageNumber; + let searchString = req.query.searchString; + const pageNumber = req.query.pageNumber; + const orderby = req.query.orderby; + const fieldSort = req.query.fieldSort; + const showNumberOfRecords = req.query.showNumberOfRecords; - if (typeof searchString === "undefined" || searchString.length === 0) { - return res.status(400).json(); + if (typeof searchString !== "string" || searchString.trim().length === 0) { + return respondError(res, { + status: 400, + code: "SEARCH_STRING_REQUIRED", + message: "searchString is required" + }); } - var token = await getToken(); + if (typeof orderby !== "string" || orderby.trim().length === 0) { + return respondError(res, { + status: 400, + code: "ORDER_BY_REQUIRED", + message: "orderby is required" + }); + } - var orderby = req.query.orderby; - var fieldSort = req.query.fieldSort; - var showNumberOfRecords = req.query.showNumberOfRecords; + if (typeof fieldSort !== "string" || fieldSort.trim().length === 0) { + return respondError(res, { + status: 400, + code: "FIELD_SORT_REQUIRED", + message: "fieldSort is required" + }); + } - searchString = searchString.replace(/\'/g, "''"); + if ( + typeof showNumberOfRecords !== "string" || + showNumberOfRecords.trim().length === 0 + ) { + return respondError(res, { + status: 400, + code: "SHOW_NUMBER_OF_RECORDS_REQUIRED", + message: "showNumberOfRecords is required" + }); + } - var queryUrl = - "incidents?$select=pinswg_environmentalstatementlocation,pinswg_caseaddress,modifiedon,description,numberofchildincidents,_accountid_value,_customerid_value,_pinswg_associatedlpa_value,_ownerid_value,pinswg_appealcasetype,statuscode,ticketnumber,title, _primarycontactid_value,pinswg_lpareference,pinswg_appellantagent,pinswg_appellantfirstname,pinswg_appellantlastname&$expand=primarycontactid($select=fullname)&$filter=(contains(title, '" + - searchString + - "') or contains(ticketnumber, '" + - searchString + - "') or contains(pinswg_lpareference, '" + - searchString + - "')) and pinswg_appealcasetype ne null " + - (process.env.SHOWSIPS !== "true" - ? "and pinswg_appealcasetype ne 846040002 " - : "") + - "and pinswg_publishtoweb eq true&$orderby=" + - orderby + - " " + - fieldSort + - "&$count=true" + - (typeof pageNumber != "undefined" - ? "&$skiptoken=" + '' - : ""); + try { + const token = await getToken(); - var apiResponse = - searchString.length > 0 - ? axios - .get( - WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), - azureHeadersPagedCustom( - token.access_token, - showNumberOfRecords - ) - ) - .then(({ data }) => { - var dataStr; - _.has(data, "@odata.nextLink") == true && - ((dataStr = JSON.stringify(data["@odata.nextLink"])), - (data["@odata.nextLink"] = - dataStr.split("/v8.2/")[1])); - res.status(200).json(data); - }) - .catch((error) => { - consoleLogger(error); - res.status(400).json(error); - }) - : res.status(400).json(); + searchString = searchString.replace(/\'/g, "''"); - return apiResponse; + const queryUrl = + "incidents?$select=pinswg_environmentalstatementlocation,pinswg_caseaddress,modifiedon,description,numberofchildincidents,_accountid_value,_customerid_value,_pinswg_associatedlpa_value,_ownerid_value,pinswg_appealcasetype,statuscode,ticketnumber,title, _primarycontactid_value,pinswg_lpareference,pinswg_appellantagent,pinswg_appellantfirstname,pinswg_appellantlastname&$expand=primarycontactid($select=fullname)&$filter=(contains(title, '" + + searchString + + "') or contains(ticketnumber, '" + + searchString + + "') or contains(pinswg_lpareference, '" + + searchString + + "')) and pinswg_appealcasetype ne null " + + (process.env.SHOWSIPS !== "true" + ? "and pinswg_appealcasetype ne 846040002 " + : "") + + "and pinswg_publishtoweb eq true&$orderby=" + + orderby + + " " + + fieldSort + + "&$count=true" + + (typeof pageNumber != "undefined" + ? "&$skiptoken=" + '' + : ""); + + const { data } = await axios.get( + WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), + azureHeadersPagedCustom(token.access_token, showNumberOfRecords) + ); + + if (_.has(data, "@odata.nextLink") === true) { + const dataStr = JSON.stringify(data["@odata.nextLink"]); + data["@odata.nextLink"] = dataStr.split("/v8.2/")[1]; + } + + return respondSuccess(res, data); + } catch (error) { + consoleLogger(error); + return respondError(res, { + status: 400, + code: "BASIC_SEARCH_PAGED_FETCH_FAILED", + message: "Failed to fetch paged basic search results" + }); + } } diff --git a/tests/phase21/endpoint-handler-contract.test.cjs b/tests/phase21/endpoint-handler-contract.test.cjs index 1676961f..abbe8671 100644 --- a/tests/phase21/endpoint-handler-contract.test.cjs +++ b/tests/phase21/endpoint-handler-contract.test.cjs @@ -1522,6 +1522,257 @@ test("getawaitingsubmission catch path returns AWAITING_SUBMISSION_FETCH_FAILED" ); }); +test("getbasicsearchdetails returns APPEAL_TYPE_NAME_REQUIRED when appealTypeName missing", async () => { + const mod = loadModule("pages/api/endpoint/getbasicsearchdetails_api.js", { + respondError: respondErrorMock, + respondSuccess: respondSuccessMock, + 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, + 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, + 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, + 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, + 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, + 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("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, + getToken: async () => { + throw new Error("token failed"); + }, + hashAPIPath: () => "&hash=expected", + azureHeaders: () => ({}), + axios: { get: async () => ({ data: { value: [] } }) }, + 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" + ); +}); + const run = async () => { let passed = 0; for (const currentTest of tests) {