TASK22224: harden createappealcompletemessage parity
This commit is contained in:
@@ -516,3 +516,37 @@ Validation:
|
||||
Follow-ups:
|
||||
|
||||
- Remaining optional cleanup in these handlers is dead import/unused local pruning (non-behavioral) if we want a final low-risk tidy pass.
|
||||
|
||||
---
|
||||
|
||||
### CL-013: TASK22224 completion-message route parity closure slice
|
||||
|
||||
date: 2026-03-24
|
||||
author: Cline
|
||||
scope: `pages/api/file/createappealcompletemessage_api.js`, `tests/phase21/file-handler-contract.test.cjs`
|
||||
type: change
|
||||
rationale: Continue next requested slice by closing the final promise-chain parity outlier in file completion-message flow and strengthening phase21 contract coverage.
|
||||
impact: Improves maintainability and async error hygiene while preserving route behavior and existing error contracts.
|
||||
status: completed
|
||||
|
||||
Summary:
|
||||
|
||||
- `pages/api/file/createappealcompletemessage_api.js`
|
||||
- replaced inline `.catch(...)` on fire-and-forget `updateAccount(...)` with explicit async IIFE + `try/catch` and `void` invocation
|
||||
- preserved non-blocking behavior and logging semantics for account-update failure path
|
||||
- preserved primary route contracts and success payload (`{ status: "success" }`)
|
||||
- phase21 file contract tests expanded:
|
||||
- success path for encoded hash candidate on `createappealcompletemessage_api`
|
||||
- dependency-failure contract assertion for `CREATE_APPEAL_COMPLETE_MESSAGE_FAILED`
|
||||
|
||||
Validation:
|
||||
|
||||
- `node tests/phase21/api-contract-slice1.test.cjs` -> pass
|
||||
- helper: 4/4
|
||||
- file-handler: 53/53
|
||||
- email-handler: 12/12
|
||||
- endpoint-handler: 152/152
|
||||
|
||||
Follow-ups:
|
||||
|
||||
- Optional final low-risk tidy sweep: remove dead imports/unused locals in legacy file handlers now that contract hardening stream is functionally complete.
|
||||
|
||||
@@ -115,15 +115,19 @@ ApiProxy.get(async (req, res) => {
|
||||
contactId = contactId.match(/\(([^)]+)\)/);
|
||||
|
||||
if (typeofinvolvement != 846040000) {
|
||||
updateAccount(
|
||||
contactId[1],
|
||||
{
|
||||
pinswg_typeofinvolvement: 846040001
|
||||
},
|
||||
true
|
||||
).catch((error) => {
|
||||
consoleLogger(error);
|
||||
});
|
||||
void (async () => {
|
||||
try {
|
||||
await updateAccount(
|
||||
contactId[1],
|
||||
{
|
||||
pinswg_typeofinvolvement: 846040001
|
||||
},
|
||||
true
|
||||
);
|
||||
} catch (error) {
|
||||
consoleLogger(error);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
await createCaseCompleteMessage(containerName, tempCaseRef);
|
||||
|
||||
@@ -694,6 +694,98 @@ test("createappealcompletemessageproxy dependency failure returns CREATE_APPEAL_
|
||||
);
|
||||
});
|
||||
|
||||
test("createappealcompletemessage_api accepts encoded hash variant and returns success", async () => {
|
||||
const mod = loadModule(
|
||||
"pages/api/file/createappealcompletemessage_api.js",
|
||||
{
|
||||
nextConnect: createNextConnectMock(),
|
||||
middleware: () => {},
|
||||
respondError: respondErrorMock,
|
||||
respondSuccess: respondSuccessMock,
|
||||
hashAPIPath: (queryPath) =>
|
||||
queryPath.includes("tempcaseref=TMP%2F1")
|
||||
? "&hash=expected"
|
||||
: "&hash=other",
|
||||
getProgressBlobs: async () => ({ path: "TMP/1/progress.json" }),
|
||||
downloadProgressFile: async (_container, path) => {
|
||||
if (path.includes("_case.json")) {
|
||||
return {
|
||||
"customerid_contact@odata.bind":
|
||||
"/contacts(00000000-0000-0000-0000-000000000001)"
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
pinswg_siteaddressline1: "Line 1",
|
||||
pinswg_siteaddressline2: "",
|
||||
pinswg_siteaddresstown: "Town",
|
||||
pinswg_siteaddresscounty: "County",
|
||||
pinswg_siteaddresspostcode: "CF1 1AA",
|
||||
pinswg_lpaapplicationreference: "LPA-1",
|
||||
pinswg_developmentdescription: "Desc",
|
||||
pinswg_name: "tmp"
|
||||
};
|
||||
},
|
||||
createBlob: async () => ({}),
|
||||
getCaseBlob: async () => ({}),
|
||||
createCaseCompleteMessage: async () => ({}),
|
||||
updateAccount: async () => ({}),
|
||||
consoleLogger: () => {},
|
||||
_: { isEmpty: (v) => v === undefined || v === null || v === "" }
|
||||
}
|
||||
);
|
||||
|
||||
const req = {
|
||||
query: {
|
||||
container: "cont/1",
|
||||
tempcaseref: "TMP/1",
|
||||
inv: "846040001",
|
||||
hash: "expected"
|
||||
}
|
||||
};
|
||||
const res = createRes();
|
||||
await mod.default.handler(req, res);
|
||||
|
||||
assert.strictEqual(res.state.statusCode, 200);
|
||||
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
|
||||
status: "success"
|
||||
});
|
||||
});
|
||||
|
||||
test("createappealcompletemessage_api dependency failure returns CREATE_APPEAL_COMPLETE_MESSAGE_FAILED", async () => {
|
||||
const mod = loadModule(
|
||||
"pages/api/file/createappealcompletemessage_api.js",
|
||||
{
|
||||
nextConnect: createNextConnectMock(),
|
||||
middleware: () => {},
|
||||
respondError: respondErrorMock,
|
||||
respondSuccess: respondSuccessMock,
|
||||
hashAPIPath: () => "&hash=expected",
|
||||
getProgressBlobs: async () => {
|
||||
throw new Error("progress failed");
|
||||
},
|
||||
consoleLogger: () => {},
|
||||
_: { isEmpty: () => true }
|
||||
}
|
||||
);
|
||||
|
||||
const req = {
|
||||
query: {
|
||||
container: "c1",
|
||||
tempcaseref: "TMP1",
|
||||
hash: "expected"
|
||||
}
|
||||
};
|
||||
const res = createRes();
|
||||
await mod.default.handler(req, res);
|
||||
|
||||
assert.strictEqual(res.state.statusCode, 400);
|
||||
assert.strictEqual(
|
||||
res.state.jsonBody.error.code,
|
||||
"CREATE_APPEAL_COMPLETE_MESSAGE_FAILED"
|
||||
);
|
||||
});
|
||||
|
||||
test("createcaseinvolvement returns record exists on 412 conflict", async () => {
|
||||
const mod = loadModule("pages/api/file/createcaseinvolvement_api.js", {
|
||||
respondError: respondErrorMock,
|
||||
|
||||
Reference in New Issue
Block a user