Updated the process for retrieving records from CRMServiceRequests

This commit is contained in:
2026-10-28 11:43:26 -03:00
parent 318459cef8
commit 3fa212e561
17 changed files with 796 additions and 328 deletions

View File

@@ -2,10 +2,10 @@ const assert = require("node:assert/strict");
const { test } = require("node:test");
const { loadApplication } = require("./support/application.cjs");
const response = data => new Response(JSON.stringify(data), { status: 200 });
function setup(fetch) {
function setup(fetch, searchFetch = async () => response({ items: [{ savedSearchNumber: "dynamic-sr-search" }] })) {
const document = { createElement: () => ({ attributes: {}, append() {}, addEventListener() {}, setAttribute(key, value) { this.attributes[key] = value; } }) };
document.createElementNS = (_, tag) => document.createElement(tag);
const app = loadApplication("content", { fetch, document, Intl, Date });
const app = loadApplication("content", { fetch: (url, options) => options.method === "GET" ? searchFetch(url, options) : fetch(url, options), document, Intl, Date });
app.currentUser.allowsCrmActivities = () => true;
app.debugContentView.renderDebugPanel = () => {};
app.opportunitiesQueryState.periodRequestVersion = 1;
@@ -15,6 +15,42 @@ const sr = (number, id = "SR-1") => ({ SrNumber: id, Title: "<script>synthetic</
OpportunityName_Id_c: { OptyNumber: number }, Owner: { PersonFirstName: "Test", PersonLastName: "Owner",
PrimaryEmail: { EmailAddress: "test@example.invalid" } }, DoNotCallFlag: false });
test("SR saved search runs once before pages and uses the first item, not the default", async () => {
const calls = [];
const app = setup(async (_url, options) => {
const payload = JSON.parse(options.body); calls.push(payload);
assert.equal(payload.copiedFrom, "queries/first-search");
return response({ items: [sr("A")], count: 1, offset: payload.offset, hasMore: payload.offset === 0 });
}, async (url, options) => {
assert.equal(options.method, "GET");
assert.equal(options.headers.Authorization, "Bearer synthetic");
assert.equal(url, "https://eeho.fa.us2.oraclecloud.com/crmRestApi/searchResources/latest/custom-actions/queries?applications=461e5791-9f15-4cd1-b5cd-19e8480cbce4&entity=CRMServiceRequest&language=en&limit=-1&onlyData=true");
calls.push("lookup");
return response({ items: [{ savedSearchNumber: "first-search" }, { savedSearchNumber: "other", isDefault: true }] });
});
await app.fusionCrmServiceRequests.requestCrmServiceRequest("synthetic", 1);
assert.equal(calls.length, 3); assert.equal(calls[0], "lookup");
assert.equal(app.debugContentView.getRequestCategory(app.debugState.requestLog[0]), "serviceRequests");
});
test("failed or empty SR search blocks POST; superseded search never starts pagination", async () => {
for (const lookup of [
async () => new Response("Denied", { status: 401 }),
async () => response({ items: [] }),
async () => response({ items: [{ savedSearchNumber: " " }] }),
async () => new Response("<html>Login</html>")
]) {
const app = setup(() => assert.fail("No POST without a saved search"), lookup);
await assert.rejects(app.fusionCrmServiceRequests.requestCrmServiceRequest("synthetic", 1));
assert.equal(app.debugState.requestLog[0].status, "failed");
}
const app = setup(() => assert.fail("Stale POST"), async () => {
app.opportunitiesQueryState.periodRequestVersion = 2;
return response({ items: [{ savedSearchNumber: "first" }] });
});
assert.equal(await app.fusionCrmServiceRequests.requestCrmServiceRequest("synthetic", 1), null);
});
test("SR badge shows reported hours, sums linked SRs and preserves missing values", async () => {
for (const [values, expected] of [[[4], "4h"], [[0], "0h"], [[2, "1.5"], "3.5h"], [[0.1, 0.2], "0.3h"], [[null], "N/A"], [[4, null], "N/A"], [[""], "N/A"], [["invalid"], "N/A"]]) {
const app = setup(async () => response({ items: values.map((value, index) => ({ ...sr("A", `SR-${index}`), ReportedHours_c: value })), hasMore: false }));
@@ -79,7 +115,7 @@ test("CRM query preserves payload and pagination after opportunities, uses token
assert.equal(options.headers.Preference, "transient");
assert.deepEqual(payload, {
aggregationResults: false, applications: ["ORACLE-ISS-APP"], onlyData: true, entity: "CRMServiceRequest",
copiedFrom: "queries/c521309c-1310-49a0-9723-da2eb1988205",
copiedFrom: "queries/dynamic-sr-search",
q: { op: "$and", criteria: [
{ op: "$in", attribute: "StatusCd", values: ["SVC_PENDING_DELIVERY"] },
{ op: "$eq", attribute: "RecordSet", value: "ORA_SVC_MY_SR_TEAM_SRS" }
@@ -90,8 +126,9 @@ test("CRM query preserves payload and pagination after opportunities, uses token
keywordsFields: ["SrNumber", "ServiceNew_Id_c.RecordName", "CustomerAccount", "OpportunityName_Id_c", "OpportunityName_Id_c.OptyNumber", "Owner"],
skipInValidFields: true, limit: 15, offset: 0
});
assert.equal(app.debugState.requestLog.length, 2);
for (const log of app.debugState.requestLog) {
assert.equal(app.debugState.requestLog.length, 3);
assert.equal(app.debugState.requestLog[0].name, "requestSRSearchResources");
for (const log of app.debugState.requestLog.slice(1)) {
assert.equal(log.name, "resquestCrmServiceRequest");
assert.equal(log.requestHeaders.Origin, "https://eeho.fa.us2.oraclecloud.com");
assert.equal(log.requestHeaders.Preference, "transient");
@@ -144,6 +181,7 @@ test("stale CRM results cannot overwrite a reopened modal or continue pagination
let resolveOld;
const app = setup(() => new Promise(resolve => { resolveOld = resolve; }));
const old = app.opportunityCrmServiceRequests.load("token", 1);
while (!resolveOld) await new Promise(resolve => setImmediate(resolve));
app.opportunitiesQueryState.periodRequestVersion = 2;
app.opportunityCrmServiceRequests.reset();
app.fusionCrmServiceRequests.requestCrmServiceRequest = async () => [sr("NEW")];
@@ -152,7 +190,7 @@ test("stale CRM results cannot overwrite a reopened modal or continue pagination
await old;
assert.equal(app.opportunityCrmServiceRequests.createBadge("NEW").textContent, "0h");
assert.equal(app.opportunityCrmServiceRequests.createBadge("OLD").textContent, "0h");
assert.equal(app.debugState.requestLog.length, 1);
assert.equal(app.debugState.requestLog.length, 2);
});
test("Reference changes share pending pagination and reuse completed CRM results", async () => {
@@ -167,6 +205,7 @@ test("Reference changes share pending pagination and reuse completed CRM results
app.opportunitiesQueryState.periodRequestVersion = 2;
const second = app.opportunityCrmServiceRequests.load("token", 2);
assert.equal(first, second);
while (!finish) await new Promise(resolve => setImmediate(resolve));
finish(response({ items: [sr("A")], count: 1, offset: 0, hasMore: true }));
await second;
app.opportunitiesQueryState.periodRequestVersion = 3;