Implemented the Create Internal Service Request functionality
This commit is contained in:
@@ -3,6 +3,87 @@ const { test } = require("node:test");
|
||||
const { loadApplication } = require("./support/application.cjs");
|
||||
const flush = () => new Promise(resolve => setImmediate(resolve));
|
||||
|
||||
test("internal SR form validates Save, maps parent data, prevents duplicate posts and preserves failures", async () => {
|
||||
const h = setup();
|
||||
h.app.currentUser.getUserId = () => "current@example.invalid";
|
||||
h.app.opportunitiesTableState.opportunitiesTableState.items = [
|
||||
{ OptyNumber: "OTHER", Name: "Other opportunity", CustomerAccount: { PrimaryAddress: { CountryCode: "US" } } },
|
||||
{ OptyNumber: "OP1", Name: "<Opportunity name>", OptyId: 456, CountryCode: "CA",
|
||||
CustomerAccount: { PartyId: 789, Region_c_localizedValue: "LAD", CountryCode: "AR", PrimaryAddress: { CountryCode: "BR" } } }
|
||||
];
|
||||
h.app.debugContentView.renderDebugPanel = () => {};
|
||||
h.app.fusionCrmServiceRequests.requestCrmServiceRequest = async () => [{ SrId: "123", SrNumber: "SR123",
|
||||
CustomerDeadline_c: "2026-05-14T00:00:00.000+0000", PrimaryPillarNew_c: "Tech_Cloud_Infrastructure", Title: "<Parent SR title>", OpportunityName_Id_c: { OptyNumber: "OP1" } }];
|
||||
const calls = [];
|
||||
h.app.platformContentMessages.sendRuntimeMessage = async message => {
|
||||
calls.push(message);
|
||||
return { ok: true, items: message.type.endsWith("requestLookupTypePlatform") ? [{ code: "OCI", name: "Oracle Cloud" }]
|
||||
: message.type.endsWith("requestInternalSrServices") ? [{ Id: "45", RecordName: "Review", Description_c: "Architecture review" }] : [] };
|
||||
};
|
||||
await h.app.opportunityCrmServiceRequests.load("synthetic", 1);
|
||||
const badge = h.app.opportunityCrmServiceRequests.createBadge("OP1");
|
||||
h.modal.append(badge);
|
||||
badge.listeners.pointerenter();
|
||||
await flush();
|
||||
const add = h.walk(h.panel()).find(el => el.title === "Create Internal Service Request");
|
||||
assert.ok(add);
|
||||
assert.equal(add.parent.children[2].title, "Copy SR number");
|
||||
add.listeners.click({ preventDefault() {}, stopPropagation() {} });
|
||||
await flush();
|
||||
const nodes = h.walk(h.modal);
|
||||
const context = nodes.find(el => el.className === "opportunities-extension-action-form-context");
|
||||
assert.deepEqual(context.children.map(el => el.textContent), ["SR Number", "SR123", "Opportunity", "<Opportunity name>", "Title", "<Parent SR title>"]);
|
||||
assert.equal(nodes.find(el => el.name === "customerDeadline").value, "14/05/2026");
|
||||
assert.equal(nodes.find(el => el.name === "customerDeadline").readOnly, true);
|
||||
assert.equal(nodes.find(el => el.name === "customerDeadline").required, false);
|
||||
for (const name of ["title", "internalDeadline", "platform", "description", "services"]) {
|
||||
const input = nodes.find(el => el.name === name);
|
||||
assert.equal(input.required, true, name);
|
||||
assert.equal(input.attributes["aria-required"], "true", name);
|
||||
assert.match(input.parent.children[0].textContent, /\(required\)$/);
|
||||
}
|
||||
for (const name of ["platform", "services"]) {
|
||||
const input = nodes.find(el => el.id === `internal-sr-${name}-search`);
|
||||
assert.equal(input.required, true);
|
||||
assert.equal(input.attributes["aria-required"], "true");
|
||||
}
|
||||
assert.equal(nodes.find(el => el.name === "internalDeadline").type, "date");
|
||||
assert.equal(nodes.find(el => el.name === "platform").children[1].value, "OCI");
|
||||
assert.equal(nodes.find(el => el.name === "services").children[1].attributes["data-description"], "Architecture review");
|
||||
assert.equal(calls.at(-1).parentServiceId, "123");
|
||||
assert.equal(calls.at(-1).emailAddress, "current@example.invalid");
|
||||
const form = nodes.find(el => el.tag === "form");
|
||||
assert.deepEqual(h.walk(form).filter(el => el.tag === "button").map(el => el.textContent), ["Save", "Cancel"]);
|
||||
const submit = () => form.listeners.submit({ preventDefault() {} });
|
||||
const before = calls.length;
|
||||
await submit();
|
||||
assert.equal(calls.length, before);
|
||||
assert.equal(nodes.find(el => el.name === "title").attributes["aria-invalid"], "true");
|
||||
for (const [name, value] of Object.entries({ title: "New internal SR", internalDeadline: "2026-05-01", platform: "OCI", description: "Detailed request", services: "45" })) nodes.find(el => el.name === name).value = value;
|
||||
const posts = [], toasts = [];
|
||||
h.app.opportunitiesLinks.showCopyConfirmation = (message, isError = false) => toasts.push({ message, isError });
|
||||
h.app.platformContentMessages.sendRuntimeMessage = message => new Promise(resolve => posts.push({ message, resolve }));
|
||||
const saving = submit();
|
||||
await submit();
|
||||
assert.equal(posts.length, 1);
|
||||
assert.equal(posts[0].message.type, "opportunitiesExtension.requestPostInternalServiceRequest");
|
||||
assert.equal(posts[0].message.emailAddress, "current@example.invalid");
|
||||
assert.deepEqual(JSON.parse(JSON.stringify(posts[0].message.payload)), {
|
||||
Title: "New internal SR", ServiceNew_Id_c: "45",
|
||||
ProblemDescription: "Detailed request", CustomerDeadline_c: "2026-05-14", TechPlatformLookUp_c: "OCI",
|
||||
ServiceRequest_Id_SRToInternalSR: "123", SvcQuestionsCollection_c: [], InternalDeadline_c: "2026-05-01"
|
||||
});
|
||||
posts[0].resolve({ ok: false, httpStatus: 403, error: "Synthetic save failure" });
|
||||
await saving;
|
||||
assert.equal(nodes.find(el => el.name === "title").value, "New internal SR");
|
||||
assert.deepEqual(toasts, [{ message: "Synthetic save failure", isError: true }]);
|
||||
const retry = submit();
|
||||
posts[1].resolve({ ok: true, result: { SrNumber: "ISR1" } });
|
||||
await retry;
|
||||
assert.deepEqual(toasts.at(-1), { message: "Internal Service Request created successfully.", isError: false });
|
||||
assert.ok(!h.walk(h.modal).includes(form));
|
||||
});
|
||||
|
||||
test("internal SR uses Session without TokenRelay and reports unavailable iframe host", async () => {
|
||||
const h = setup();
|
||||
let renewals = 0;
|
||||
@@ -146,7 +227,8 @@ test("SR tooltip loads nested details with copy/link and empty text, discarding
|
||||
assert.equal(calls[0].message.token, undefined);
|
||||
assert.equal(calls[0].message.srId, "NOT-THE-URL-ID");
|
||||
assert.ok(h.walk(h.panel()).some(node => node.textContent === "Loading SR details..."));
|
||||
calls[0].resolve({ ok: true, items: [{ SrId: 99, SrNumber: "SR &child", Title: "<child>", ServiceNew_c: "Queue" }] });
|
||||
calls[0].resolve({ ok: true, items: [{ SrId: 99, SrNumber: "SR &child", Title: "<child>", ServiceNew_c: "Queue",
|
||||
LastUpdateDate: "2026-05-14T00:00:00.000+0000", OpenDate: "2026-04-01T23:30:00.000+0000" }] });
|
||||
calls[1].resolve({ ok: true, items: [] });
|
||||
await flush();
|
||||
const nodes = h.walk(h.panel());
|
||||
@@ -155,6 +237,8 @@ test("SR tooltip loads nested details with copy/link and empty text, discarding
|
||||
assert.ok(link.href.endsWith("srNumber=SR%20%26child&srId=99"));
|
||||
assert.equal(link.parent.children[2].title, "Copy SR number");
|
||||
assert.ok(nodes.some(node => node.textContent.includes("Service Queue: Queue")));
|
||||
assert.ok(nodes.some(node => node.textContent.includes("LastUpdateDate: 14/05/2026")));
|
||||
assert.ok(nodes.some(node => node.textContent.includes("OpenDate: 01/04/2026")));
|
||||
assert.ok(nodes.some(node => node.textContent === "No further details."));
|
||||
h.app.crmSrPopover?.close();
|
||||
h.app.opportunityCrmServiceRequests.reset();
|
||||
|
||||
Reference in New Issue
Block a user