const assert = require("node:assert/strict"); const { test } = require("node:test"); const { loadApplication } = require("./support/application.cjs"); function setup() { let document; class Element { constructor(tag) { this.tag = tag; this.children = []; this.attributes = {}; this.listeners = {}; this.isConnected = true; this.text = ""; } set textContent(value) { this.text = value; this.children = []; } get textContent() { return this.text + this.children.map(child => child.textContent).join(""); } append(...nodes) { for (const node of nodes) { node.parent = this; this.children.push(node); } } setAttribute(key, value) { this.attributes[key] = value; } addEventListener(key, fn) { this.listeners[key] = fn; } focus() { document.activeElement = this; } remove() { this.parent.children = this.parent.children.filter(child => child !== this); this.isConnected = false; } click() { this.listeners.click?.({ target: this, preventDefault() {}, stopPropagation() {} }); } } const host = new Element("host"); document = { createElement: tag => new Element(tag), createElementNS: (_, tag) => new Element(tag), getElementById: id => id === "opportunities-extension-modal" ? host : null, listeners: {}, addEventListener(key, fn) { this.listeners[key] = fn; } }; const app = loadApplication("content", { document, window: {} }); app.currentUser.allowsCrmActivities = () => true; app.authSessionState.principal = "synthetic@example.invalid"; app.productsContentState.opptyProductsByNumber.set("A", { items: [] }); app.productsContentState.opptyProductsByNumber.set("B", { items: [] }); app.platformContentMessages.sendRuntimeMessage = () => assert.fail("Form must not send requests"); const walk = node => [node, ...node.children.flatMap(walk)]; const nodes = () => walk(host); const form = () => nodes().find(node => node.tag === "form"); return { app, host, document, nodes, form }; } test("only plus on the missing Action badge opens a form with six fields and no save operation", () => { const h = setup(); const badge = h.app.opportunityWorkloadActions.createBadge("A"); assert.equal(badge.textContent, "0+"); badge.click(); assert.equal(h.host.children.length, 0); const plus = badge.children.find(node => node.tag === "button"); assert.equal(plus.textContent, "+"); assert.equal(plus.attributes["aria-haspopup"], "dialog"); plus.click(); assert.equal(h.host.children.length, 1); assert.equal(h.host.children[0].attributes.role, "dialog"); assert.deepEqual(h.nodes().filter(node => node.name).map(node => node.name), ["team", "startDate", "endDate", "status", "complexity", "notes"]); assert.equal(h.nodes().find(node => node.name === "notes").tag, "textarea"); assert.equal(h.nodes().find(node => node.name === "startDate").type, "date"); assert.equal(h.document.activeElement.name, "team"); assert.equal(h.nodes().find(node => node.textContent === "Save").disabled, true); let prevented = false; h.form().listeners.submit({ preventDefault() { prevented = true; } }); assert.equal(prevented, true); h.nodes().find(node => node.textContent === "Cancel").click(); assert.equal(h.host.children.length, 0); assert.equal(h.document.activeElement, plus); }); test("form traps focus, handles Escape, replaces rather than duplicates, and resets its fields", () => { const h = setup(); h.app.contentModal.ensureEscapeKeyHandler(); const first = h.app.opportunityWorkloadActions.createBadge("A").children.find(node => node.tag === "button"); first.click(); h.nodes().find(node => node.name === "notes").value = "Draft"; const second = h.app.opportunityWorkloadActions.createBadge("B").children.find(node => node.tag === "button"); second.click(); assert.equal(h.host.children.length, 1); assert.equal(h.nodes().find(node => node.name === "notes").value, undefined); const cancel = h.nodes().find(node => node.textContent === "Cancel"); cancel.focus(); let prevented = false; h.host.children[0].listeners.keydown({ key: "Tab", preventDefault() { prevented = true; } }); assert.equal(prevented, true); assert.equal(h.document.activeElement.title, "Close"); h.document.listeners.keydown({ key: "Escape", preventDefault() {} }); assert.equal(h.host.children.length, 0); assert.equal(h.document.activeElement, second); }); test("SALES_REP, loading/unknown Actions and stale triggers cannot open the modal", () => { const h = setup(); const plus = h.app.opportunityWorkloadActions.createBadge("A").children.find(node => node.tag === "button"); h.app.currentUser.allowsCrmActivities = () => false; plus.click(); assert.equal(h.host.children.length, 0); assert.equal(h.app.opportunityWorkloadActions.createBadge("A"), null); h.app.currentUser.allowsCrmActivities = () => true; h.app.productsContentState.opptyProductsByNumber.set("A", { items: [{ RevnId: "pending" }] }); plus.click(); assert.equal(h.host.children.length, 0); assert.equal(h.app.opportunityWorkloadActions.createBadge("A").children.some(node => node.tag === "button"), false); h.app.authSessionState.principal = ""; assert.equal(h.app.opportunityWorkloadActions.createBadge("B").children.some(node => node.tag === "button"), false); }); test("resetting Actions closes an open form without leaving an old opportunity context", () => { const h = setup(); h.app.opportunityWorkloadActions.createBadge("A").children.find(node => node.tag === "button").click(); h.app.opportunityWorkloadActions.reset(); assert.equal(h.host.children.length, 0); }); test("Action header shows the selected opportunity customer, name and formatted close date safely", () => { const h = setup(); h.app.opportunitiesTableState.opportunitiesTableState.items = [ { OptyNumber: "A", Name: "", CustomerAccount: { PartyUniqueName: "Customer A" }, EffectiveDate: "2026-11-30" }, { OptyNumber: "B", Name: "Opportunity B", CustomerAccount: { PartyUniqueName: "Customer B" }, EffectiveDate: null } ]; h.app.opportunityWorkloadActions.createBadge("A").children.find(node => node.tag === "button").click(); assert.deepEqual(h.nodes().filter(node => node.tag === "dt").map(node => node.textContent), ["Customer", "Name", "Close Date"]); assert.deepEqual(h.nodes().filter(node => node.tag === "dd").map(node => node.textContent), ["Customer A", "", "30/11/2026"]); assert.equal(h.nodes().some(node => node.tag === "script"), false); h.app.opportunityWorkloadActions.createBadge("B").children.find(node => node.tag === "button").click(); assert.deepEqual(h.nodes().filter(node => node.tag === "dd").map(node => node.textContent), ["Customer B", "Opportunity B", "-"]); });