diff --git a/pages/api/endpoint/getadvancedsearchpaged_api.js b/pages/api/endpoint/getadvancedsearchpaged_api.js index 1422f748..915efdeb 100644 --- a/pages/api/endpoint/getadvancedsearchpaged_api.js +++ b/pages/api/endpoint/getadvancedsearchpaged_api.js @@ -48,33 +48,69 @@ // */ import axios from "axios"; -import CryptoJS from "crypto-js"; import _ from "lodash"; -import { - azureHeadersPagedCustom, - azureHeadersPaged, - azureHeaders -} from "../../../actions/core/headers"; +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; - var token = await getToken(); + const rawSearchString = req.query.searchstring; + const pageNumber = req.query.pageNumber; + const orderby = req.query.orderby; + const fieldSort = req.query.fieldSort; + const showNumberOfRecords = req.query.showNumberOfRecords; - var orderby = req.query.orderby; - var fieldSort = req.query.fieldSort; - var showNumberOfRecords = req.query.showNumberOfRecords; + if ( + typeof rawSearchString !== "string" || + rawSearchString.trim().length === 0 + ) { + return respondError(res, { + status: 400, + code: "SEARCH_STRING_REQUIRED", + message: "searchstring is required" + }); + } + if (typeof orderby !== "string" || orderby.trim().length === 0) { + return respondError(res, { + status: 400, + code: "ORDER_BY_REQUIRED", + message: "orderby is required" + }); + } + if (typeof fieldSort !== "string" || fieldSort.trim().length === 0) { + return respondError(res, { + status: 400, + code: "FIELD_SORT_REQUIRED", + message: "fieldSort is required" + }); + } + if ( + typeof showNumberOfRecords !== "string" || + showNumberOfRecords.trim().length === 0 + ) { + return respondError(res, { + status: 400, + code: "SHOW_NUMBER_OF_RECORDS_REQUIRED", + message: "showNumberOfRecords is required" + }); + } - searchString = _.isEmpty(searchString) - ? searchString - : JSON.parse(decodeURI(searchString)); + let searchString; + try { + searchString = JSON.parse(decodeURI(rawSearchString)); + } catch (error) { + return respondError(res, { + status: 400, + code: "INVALID_SEARCH_STRING", + message: "searchstring must be valid encoded JSON" + }); + } var queryString = ""; @@ -146,84 +182,81 @@ export default async function ApiProxy(req, res) { console.log("adv qu: ", queryUrl); - var apiResponse = _.isEmpty(searchString) - ? res.status(400).json() - : axios - .get( - WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), - azureHeadersPagedCustom( - token.access_token, - showNumberOfRecords - ) - ) - .then(async ({ data }) => { - var dataStr; - _.has(data, "@odata.nextLink") == true && - ((dataStr = JSON.stringify(data["@odata.nextLink"])), - (data["@odata.nextLink"] = dataStr.split("/v8.2/")[1])); + try { + const token = await getToken(); + const { data } = await axios.get( + WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), + azureHeadersPagedCustom(token.access_token, showNumberOfRecords) + ); - if (_.has(searchString, "projecttype")) { - // await updateValueArray(data, token); - // async function updateValueArray(data, token) { - // for (let i = 0; i < data.value.length; i++) { - // const item = data.value[i]; - // try { - // // Axios call using the `incidentid` to fetch additional data - // const response = await axios.get( - // WEBAPI_URL + - // "pinswg_sipses?$filter=_pinswg_sipscase_value eq " + - // item.incidentid + - // " and _pinswg_projecttype_value eq " + - // searchString.projecttype + - // "&$select=_pinswg_projecttype_value" + - // hashAPIPath( - // "pinswg_sipses?$filter=_pinswg_sipscase_value eq " + - // item.incidentid + - // " and _pinswg_projecttype_value eq " + - // searchString.projecttype + - // "&$select=_pinswg_projecttype_value" - // ), - // azureHeadersPaged(token.access_token) - // ); - // // Assuming the response contains the additional data you want to add - // // console.log(response.data.value[0]); - // console.log(response.data.value); - // if ( - // response.data.value.length > 0 && - // response.data.value[0] - // ._pinswg_projecttype_value != null - // ) { - // Object.assign( - // item, - // response.data.value[0] - // ); // Update item with new data - // } else { - // console.log( - // `No project type found for incident ID ${item.incidentid}` - // ); - // } - // } catch (error) { - // console.error( - // `Error fetching data for incident ID ${item.incidentid}:`, - // error - // ); - // } - // } - // } - // data.value = data.value.filter( - // (item) => item._pinswg_projecttype_value != null - // ); - // data["@odata.count"] = data.value.length; - } + let 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); - }); + if (_.has(searchString, "projecttype")) { + // await updateValueArray(data, token); + // async function updateValueArray(data, token) { + // for (let i = 0; i < data.value.length; i++) { + // const item = data.value[i]; + // try { + // // Axios call using the `incidentid` to fetch additional data + // const response = await axios.get( + // WEBAPI_URL + + // "pinswg_sipses?$filter=_pinswg_sipscase_value eq " + + // item.incidentid + + // " and _pinswg_projecttype_value eq " + + // searchString.projecttype + + // "&$select=_pinswg_projecttype_value" + + // hashAPIPath( + // "pinswg_sipses?$filter=_pinswg_sipscase_value eq " + + // item.incidentid + + // " and _pinswg_projecttype_value eq " + + // searchString.projecttype + + // "&$select=_pinswg_projecttype_value" + // ), + // azureHeadersPaged(token.access_token) + // ); + // // Assuming the response contains the additional data you want to add + // // console.log(response.data.value[0]); + // console.log(response.data.value); + // if ( + // response.data.value.length > 0 && + // response.data.value[0] + // ._pinswg_projecttype_value != null + // ) { + // Object.assign( + // item, + // response.data.value[0] + // ); // Update item with new data + // } else { + // console.log( + // `No project type found for incident ID ${item.incidentid}` + // ); + // } + // } catch (error) { + // console.error( + // `Error fetching data for incident ID ${item.incidentid}:`, + // error + // ); + // } + // } + // } + // data.value = data.value.filter( + // (item) => item._pinswg_projecttype_value != null + // ); + // data["@odata.count"] = data.value.length; + } - return apiResponse; + return respondSuccess(res, data); + } catch (error) { + consoleLogger(error); + return respondError(res, { + status: 400, + code: "ADVANCED_SEARCH_PAGED_FETCH_FAILED", + message: "Failed to fetch advanced search paged results" + }); + } } // export default async function ApiProxy(req, res) { diff --git a/tests/phase21/endpoint-handler-contract.test.cjs b/tests/phase21/endpoint-handler-contract.test.cjs index 443d3737..267dcce0 100644 --- a/tests/phase21/endpoint-handler-contract.test.cjs +++ b/tests/phase21/endpoint-handler-contract.test.cjs @@ -971,6 +971,92 @@ test("getadvancedsearch catch path returns ADVANCED_SEARCH_FETCH_FAILED", async ); }); +test("getadvancedsearchpaged returns SEARCH_STRING_REQUIRED when searchstring missing", async () => { + const mod = loadModule("pages/api/endpoint/getadvancedsearchpaged_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: { + 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, + getToken: async () => ({ access_token: "token" }), + hashAPIPath: () => "&hash=expected", + azureHeadersPagedCustom: () => ({}), + axios: { get: async () => ({ data: { value: [] } }) }, + consoleLogger: () => {}, + _: { has: () => false } + }); + + 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, + getToken: async () => ({ access_token: "token" }), + hashAPIPath: () => "&hash=expected", + azureHeadersPagedCustom: () => ({}), + axios: { + get: async () => { + throw new Error("relay failed"); + } + }, + consoleLogger: () => {}, + _: { has: () => false } + }); + + 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",