TASK22211: normalize case creation and media endpoint contracts

This commit is contained in:
2026-03-23 11:55:23 +00:00
parent e0e91c843b
commit 98e159d523
4 changed files with 257 additions and 88 deletions
+68 -24
View File
@@ -42,26 +42,67 @@
*/ */
import axios from "axios"; import axios from "axios";
import CryptoJS from "crypto-js"; import { consoleLogger } from "../../../actions/core/logger";
import _ from "lodash";
import { getToken } from "../../../actions/core/token"; import { getToken } from "../../../actions/core/token";
import { getCaseBlob } from "../../../actions/azurestorage"; import { getCaseBlob } from "../../../actions/azurestorage";
import { hashAPIPath } from "../../../actions/core/hash"; import { hashAPIPath } from "../../../actions/core/hash";
import { respondError, respondSuccess } from "../middleware/apiResponse";
const WEBAPI_URL = const WEBAPI_URL =
process.env.RELAY_ROOT || process.env.RELAY_ROOT ||
"https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/"; "https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/";
export default async function ApiProxy(req, res) { export default async function ApiProxy(req, res) {
var createCaseBody = req.body; const createCaseBody = req.body;
var contactid = req.query.contactid; const contactid = req.query.contactid;
var appealTypeId = req.query.appealTypeId; const appealTypeId = req.query.appealTypeId;
var containerName = req.query.containername; const containerName = req.query.containername;
var lpaID = req.query.lpaID; const lpaID = req.query.lpaID;
var queryUrl = "incidents"; const queryUrl = "incidents";
var token = await getToken();
var data = { if (!createCaseBody || typeof createCaseBody !== "object") {
return respondError(res, {
status: 400,
code: "CASE_PAYLOAD_REQUIRED",
message: "Case payload is required"
});
}
if (typeof contactid !== "string" || contactid.trim().length === 0) {
return respondError(res, {
status: 400,
code: "CONTACT_ID_REQUIRED",
message: "contactid is required"
});
}
if (typeof appealTypeId !== "string" || appealTypeId.trim().length === 0) {
return respondError(res, {
status: 400,
code: "APPEAL_TYPE_ID_REQUIRED",
message: "appealTypeId is required"
});
}
if (
typeof containerName !== "string" ||
containerName.trim().length === 0
) {
return respondError(res, {
status: 400,
code: "CONTAINER_NAME_REQUIRED",
message: "containername is required"
});
}
if (typeof lpaID !== "string" || lpaID.trim().length === 0) {
return respondError(res, {
status: 400,
code: "LPA_ID_REQUIRED",
message: "lpaID is required"
});
}
try {
const token = await getToken();
const data = {
"title": "insertion test case", "title": "insertion test case",
"caseorigincode": 3, "caseorigincode": 3,
"servicestage": 1, "servicestage": 1,
@@ -69,14 +110,14 @@ export default async function ApiProxy(req, res) {
"pinswg_appealcasetype": appealTypeId, "pinswg_appealcasetype": appealTypeId,
"pinswg_AssociatedLPA@odata.bind": "/accounts(" + lpaID + ")" "pinswg_AssociatedLPA@odata.bind": "/accounts(" + lpaID + ")"
}; };
var newData = Object.assign(data, createCaseBody); const newData = Object.assign(data, createCaseBody);
delete newData.lpaTypes; delete newData.lpaTypes;
delete newData.appealTypes; delete newData.appealTypes;
console.log("/////Create Case:\n", newData, "\n//////////////"); console.log("/////Create Case:\n", newData, "\n//////////////");
var config = { const config = {
method: "post", method: "post",
url: WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), url: WEBAPI_URL + queryUrl + hashAPIPath(queryUrl),
headers: { headers: {
@@ -89,18 +130,21 @@ export default async function ApiProxy(req, res) {
}, },
data: JSON.stringify(newData) data: JSON.stringify(newData)
}; };
var apiResponse = _.isEmpty(req.query)
? res.status(400).json()
: axios(config)
.then(({ data }) => {
getCaseBlob(containerName, data.ticketnumber, createCaseBody);
res.status(200).json(data); const { data: responseData } = await axios(config);
}) await getCaseBlob(
.catch((error) => { containerName,
//consoleLogger(error); responseData.ticketnumber,
res.status(400).json(error); createCaseBody
);
return respondSuccess(res, responseData);
} catch (error) {
consoleLogger(error);
return respondError(res, {
status: 400,
code: "CASE_CREATE_FAILED",
message: "Failed to create case"
}); });
}
return apiResponse;
} }
+20 -14
View File
@@ -17,11 +17,11 @@
*/ */
import axios from "axios"; import axios from "axios";
import CryptoJS from "crypto-js";
import { azureHeaders } from "../../../actions/core/headers"; import { azureHeaders } from "../../../actions/core/headers";
import { consoleLogger } from "../../../actions/core/logger"; import { consoleLogger } from "../../../actions/core/logger";
import { getToken } from "../../../actions/core/token"; import { getToken } from "../../../actions/core/token";
import { hashAPIPath } from "../../../actions/core/hash"; import { hashAPIPath } from "../../../actions/core/hash";
import { respondError, respondSuccess } from "../middleware/apiResponse";
const WEBAPI_URL = const WEBAPI_URL =
process.env.RELAY_ROOT || process.env.RELAY_ROOT ||
@@ -57,25 +57,28 @@ const groupArray = (arr) => {
}; };
export default async function ApiProxy(req, res) { export default async function ApiProxy(req, res) {
var incidentID = req.query.incidentid; const incidentID = req.query.incidentid;
if (typeof incidentID === "undefined" || incidentID.length === 0) { if (typeof incidentID !== "string" || incidentID.trim().length === 0) {
return res.status(400).json(); return respondError(res, {
status: 400,
code: "INCIDENT_ID_REQUIRED",
message: "incidentid is required"
});
} }
var token = await getToken(); try {
const token = await getToken();
var queryUrl = const queryUrl =
"pinswg_documents?$count=true&$filter=_pinswg_documentids_value eq " + "pinswg_documents?$count=true&$filter=_pinswg_documentids_value eq " +
incidentID + incidentID +
" and not(contains(pinswg_name,'_Appeal_Form.pdf'))&$select=pinswg_name,pinswg_isharedocumentlocations"; " and not(contains(pinswg_name,'_Appeal_Form.pdf'))&$select=pinswg_name,pinswg_isharedocumentlocations";
return axios const { data } = await axios.get(
.get(
WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), WEBAPI_URL + queryUrl + hashAPIPath(queryUrl),
azureHeaders(token.access_token) azureHeaders(token.access_token)
) );
.then(({ data }) => {
// //delete data["pinswg_documentid"]; // //delete data["pinswg_documentid"];
// data.value.forEach(function (element) { // data.value.forEach(function (element) {
// delete element["pinswg_documentid"]; // delete element["pinswg_documentid"];
@@ -92,10 +95,13 @@ export default async function ApiProxy(req, res) {
item.name = item.pinswg_name; item.name = item.pinswg_name;
}); });
res.status(200).json(data); return respondSuccess(res, data);
}) } catch (error) {
.catch((error) => {
consoleLogger(error); consoleLogger(error);
res.status(400).json(error); return respondError(res, {
status: 400,
code: "APPEAL_PDF_DOCUMENTS_FETCH_FAILED",
message: "Failed to fetch appeal PDF documents"
}); });
} }
}
+2 -11
View File
@@ -1,13 +1,4 @@
import axios from "axios"; import { respondSuccess } from "../middleware/apiResponse";
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";
const WEBAPI_URL =
process.env.RELAY_ROOT ||
"https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/";
// export default async function ApiProxy(req, res) { // export default async function ApiProxy(req, res) {
// var caseid = req.query.caseid; // var caseid = req.query.caseid;
@@ -134,5 +125,5 @@ export default function ApiProx(req, res) {
} }
] ]
}; };
return res.status(200).json(data); return respondSuccess(res, data);
} }
@@ -3119,6 +3119,134 @@ test("getdnscoords catch path returns DNS_COORDS_FETCH_FAILED", async () => {
); );
}); });
test("getappealpdfdocuments returns INCIDENT_ID_REQUIRED when incidentid missing", async () => {
const mod = loadModule("pages/api/endpoint/getappealpdfdocuments_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, "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,
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("createcase returns CASE_PAYLOAD_REQUIRED when body missing", async () => {
const mod = loadModule("pages/api/endpoint/createcase_api.js", {
respondError: respondErrorMock,
respondSuccess: respondSuccessMock,
getToken: async () => ({ access_token: "token" }),
getCaseBlob: async () => {},
hashAPIPath: () => "&hash=expected",
axios: async () => ({ data: { ticketnumber: "CAS-1" } }),
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, "CASE_PAYLOAD_REQUIRED");
});
test("createcase returns CONTACT_ID_REQUIRED when contactid missing", async () => {
const mod = loadModule("pages/api/endpoint/createcase_api.js", {
respondError: respondErrorMock,
respondSuccess: respondSuccessMock,
getToken: async () => ({ access_token: "token" }),
getCaseBlob: async () => {},
hashAPIPath: () => "&hash=expected",
axios: async () => ({ data: { ticketnumber: "CAS-1" } }),
consoleLogger: () => {}
});
const req = {
query: { appealTypeId: "a1", containername: "c1", lpaID: "l1" },
body: { title: "x" }
};
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("createcase catch path returns CASE_CREATE_FAILED", async () => {
const mod = loadModule("pages/api/endpoint/createcase_api.js", {
respondError: respondErrorMock,
respondSuccess: respondSuccessMock,
getToken: async () => ({ access_token: "token" }),
getCaseBlob: async () => {},
hashAPIPath: () => "&hash=expected",
axios: async () => {
throw new Error("create failed");
},
consoleLogger: () => {}
});
const req = {
query: {
contactid: "c1",
appealTypeId: "a1",
containername: "container",
lpaID: "l1"
},
body: { title: "x" }
};
const res = createRes();
await mod.default(req, res);
assert.strictEqual(res.state.statusCode, 400);
assert.strictEqual(res.state.jsonBody.error.code, "CASE_CREATE_FAILED");
});
test("getsipsmedia returns success contract", async () => {
const mod = loadModule("pages/api/endpoint/getsipsmedia_api.js", {
respondSuccess: respondSuccessMock
});
const req = { query: {} };
const res = createRes();
await mod.default(req, res);
assert.strictEqual(res.state.statusCode, 200);
assert.strictEqual(res.state.jsonBody["@odata.count"], 4);
});
const run = async () => { const run = async () => {
let passed = 0; let passed = 0;
for (const currentTest of tests) { for (const currentTest of tests) {