const assert = require("node:assert/strict"); const { test } = require("node:test"); const { loadBackground, response } = require("./support/characterization.cjs"); const { loadApplication } = require("./support/application.cjs"); function assertDebugVisibility(result, secret) { const app = loadApplication("content"); const entries = result.debugRequests || []; const render = () => entries.map(entry => app.debugContentLog.formatHeaderBlock(entry.requestHeaders) + app.debugContentLog.formatDebugBody(entry.responseBody, entry.name)).join("\n"); assert.ok(!render().includes(secret)); app.debugState.debugSecretsVisible = true; assert.equal(render().includes(secret), JSON.stringify(entries).includes(secret)); } const type = "opportunitiesExtension.requestPostServiceRequest"; const emailAddress = "signed.in+sr@example.invalid"; const internalType = "opportunitiesExtension.requestPostInternalServiceRequest"; const internalInput = () => ({ Title: "Internal request title", ServiceNew_Id_c: "404", ProblemDescription: "Form description", CustomerDeadline_c: "2026-11-29", TechPlatformLookUp_c: "DATABASE", InternalDeadline_c: "2027-01-31", ServiceRequest_Id_SRToInternalSR: "505" }); const parentInfo = () => ({ SrId: 505, SrNumber: "SR505", AccountPartyId: 100000693906507, OpportunityName_c: "A8YPN8", OpportunityName_Id_c: 302959906052470, RegionText_c: "LAD", SvcHealth_c: "SVC_HEALTH_YELLOW", Language_c: "PORTUGUESE", CountryText_c: "BR", PrimaryPillarNew_c: "Tech_Cloud_Platform", SecondaryPillarNew_c: "Tech_Cloud_Infrastructure", ServiceNew_Id_c: 300010753841648 }); for (const family of ["chrome", "firefox"]) { test(`${family}: internal SR reads parent SRInfo, resolves user and posts form values with Session and observed client ID`, async () => { const calls = []; const h = loadBackground({ family, fetch: async (url, options) => { calls.push({ url, options }); if (options.method === "GET" && url.includes("/serviceRequests?")) return withClientId({ items: [parentInfo()] }, 200, "internal-client"); if (url.includes("/resourceUsers?")) return response({ resourcePartyId: 303 }); assert.ok(!url.includes("Catalogue_c"), "Internal SR must not use catalog signing"); return response({ SrNumber: "ISR1" }, 201); } }); const input = { ...internalInput(), AccountPartyId: 1, OpportunityName_c: "STALE", OpportunityName_Id_c: 2, RegionText_c: "APAC", SvcHealth_c: "SVC_HEALTH_GREEN", Language_c: "ENGLISH", CountryText_c: "US", PrimaryPillarNew_c: "STALE", SecondaryPillarNew_c: null, ReportedByPartyId: 999 }; const result = await h.dispatch({ type: internalType, emailAddress, payload: input }); assert.equal(result.ok, true); assert.equal(calls.length, 3); const info = new URL(calls[0].url); assert.match(info.pathname, /SeaaS_SR_management.*\/oalsetCRMRestAPI\/.*resources\/latest\/serviceRequests$/); assert.equal(info.searchParams.get("q"), "SrId=505"); assert.equal(info.searchParams.get("onlyData"), "true"); assert.equal(info.searchParams.get("orderBy"), "LastUpdateDate:desc"); assert.equal(info.searchParams.get("fields"), "PrimaryPillarNew_c,SecondaryPillarNew_c,SvcHealth_c,SrNumber,AccountPartyId,CountryText_c,Language_c,OpportunityName_Id_c,OpportunityName_c,RegionText_c,ServiceNew_Id_c"); const post = calls[2]; assert.equal(new URL(calls[1].url).searchParams.get("emailAddress"), emailAddress); assert.match(post.url, /SeaaS_SR_management.*oalsetCRMRestAPICloudAccount.*resources\/latest\/serviceRequests$/); assert.equal(post.options.method, "POST"); const { SrId, SrNumber, ...parent } = parentInfo(); assert.deepEqual(JSON.parse(post.options.body), { ...parent, ...internalInput(), ServiceRequest_Id_SRToInternalSR: "505", ServiceNew_Id_c: 404, InternalDeadline_c: "2027-01-31T00:00:00.000Z", ReportedByPartyId: 303, SvcQuestionsCollection_c: [] }); assert.ok(calls.every(call => call.options.headers.Authorization === "Session" && call.options.credentials === "include")); const origin = "https://comcipapic-oalprod.integration.ocp.oraclecloud.com"; assert.deepEqual({ ...post.options.headers }, { Accept: "application/json", "Content-Type": "application/json", Authorization: "Session", Origin: origin, "x-appbuilder-client-id": "internal-client" }); assertDebugVisibility(result, "internal-client"); assert.equal(calls[0].options.headers.Origin, undefined); assert.equal(result.debugRequests[2].requestHeaders.Origin, origin); assert.equal(h.headerRules.length, 1); const { removeRuleIds, addRules } = h.headerRules[0]; assert.deepEqual(removeRuleIds, [7203]); assert.equal(addRules.length, 1); const rule = addRules[0]; assert.deepEqual(rule.action, { type: "modifyHeaders", requestHeaders: [{ header: "Origin", operation: "set", value: origin }] }); assert.deepEqual(rule.condition.initiatorDomains, ["synthetic-extension"]); assert.deepEqual(rule.condition.requestMethods, ["post"]); assert.deepEqual(rule.condition.resourceTypes, ["xmlhttprequest"]); const pattern = new RegExp(rule.condition.regexFilter); assert.ok(pattern.test(post.url)); assert.ok(!pattern.test(calls[0].url)); assert.ok(!pattern.test(post.url + "/other")); assert.ok(!pattern.test(post.url + "?other=1")); assert.deepEqual(result.debugRequests.map(entry => entry.name), ["requestSRInfo", "requestResourceUser", "requestPostInternalServiceRequest"]); }); } test("internal SR queries the current parent on every Save and reuses captured client ID after worker restart", async () => { const sessionStorage = {}; const queries = [], posts = []; const fetch = async (url, options) => { if (url.includes("/serviceRequests?")) { const id = Number(new URL(url).searchParams.get("q").slice("SrId=".length)); queries.push(id); const parent = { ...parentInfo(), SrId: id, SecondaryPillarNew_c: null, ServiceNew_Id_c: id + 1000 }; if (id === 606) delete parent.ServiceNew_Id_c; return id === 505 ? withClientId({ items: [parent] }, 200, "saved-internal-client") : response({ items: [parent] }); } if (url.includes("/resourceUsers?")) return response({ resourcePartyId: 303 }); posts.push(options); return response({ SrNumber: "ISR1" }, 201); }; const h = loadBackground({ fetch, sessionStorage }); assert.equal((await h.dispatch({ type: internalType, emailAddress, payload: internalInput() })).ok, true); const restarted = loadBackground({ fetch, sessionStorage }); assert.equal((await restarted.dispatch({ type: internalType, emailAddress, payload: { ...internalInput(), ServiceRequest_Id_SRToInternalSR: "606" } })).ok, true); assert.deepEqual(queries, [505, 606]); assert.equal(posts[1].headers["x-appbuilder-client-id"], "saved-internal-client"); assert.equal(JSON.parse(posts[1].body).ServiceRequest_Id_SRToInternalSR, "606", "links to parent SrId, independently of the parent's service ID"); assert.equal(JSON.parse(posts[1].body).SecondaryPillarNew_c, null); }); test("internal SR save validates form fields and parent ID before requesting SRInfo", async () => { let calls = 0; const h = loadBackground({ fetch: async () => { calls++; return response({}, 403); } }); for (const change of [{ Title: "" }, { ProblemDescription: "" }, { TechPlatformLookUp_c: "" }, { InternalDeadline_c: "2026-02-30" }, { CustomerDeadline_c: "2026-02-30" }, { ServiceNew_Id_c: "bad" }, { ServiceRequest_Id_SRToInternalSR: "bad" }]) { assert.equal((await h.dispatch({ type: internalType, emailAddress, payload: { ...internalInput(), ...change } })).ok, false); } assert.equal(calls, 0); assert.equal((await h.dispatch({ type: internalType, emailAddress, payload: internalInput() })).ok, false); assert.equal(calls, 1); }); test("internal SR stops after missing or rejected parent data, failed user lookup or POST and never retries creation", async () => { for (const mode of ["info-401", "info-500", "empty", "multiple", "wrong-parent", "missing-country", "user", "post-403", "post-500", "network"]) { const calls = []; const h = loadBackground({ fetch: async (url, options) => { calls.push({ url, options }); if (url.includes("/serviceRequests?")) { const parent = parentInfo(); if (mode === "wrong-parent") parent.SrId = 999; if (mode === "missing-country") delete parent.CountryText_c; return response({ items: mode === "empty" ? [] : mode === "multiple" ? [parent, parent] : [parent] }, mode === "info-401" ? 401 : mode === "info-500" ? 500 : 200); } if (url.includes("/resourceUsers?")) return response({ resourcePartyId: 303 }, mode === "user" ? 403 : 200); if (mode === "network") throw new Error("Synthetic network failure"); return response({}, mode === "post-403" ? 403 : 500); } }); const result = await h.dispatch({ type: internalType, emailAddress, payload: internalInput() }); assert.equal(result.ok, false, mode); const hasPost = ["post-403", "post-500", "network"].includes(mode); assert.equal(calls.length, hasPost ? 3 : mode === "user" ? 2 : 1, mode); assert.equal(calls.filter(call => call.options.method === "POST").length, hasPost ? 1 : 0); assert.equal(result.debugRequests.at(-1).status, ["empty", "multiple", "wrong-parent", "missing-country"].includes(mode) ? "success" : "failed"); } }); const payload = () => ({ AccountPartyId: 100000000000101, OpportunityName_Id_c: 202, ServiceNew_Id_c: 404, Title: "Service-OP1-Customer", RegionText_c: "LAD", CountryText_c: "BR", ProblemDescription: "Test description", Language_c: "ENGLISH", CustomerDeadline_c: "2027-01-31", TechPlatformLookUp_c: "NO_ALL_PLATFORM", PrimaryPillarNew_c: "Tech_Cloud_Infrastructure" }); const withClientId = (body, status, value) => { const result = response(body, status); result.headers.set("X-AppBuilder-Client-Id", value); return result; }; for (const family of ["chrome", "firefox"]) { test(`${family}: response client ID from resource lookup appears in confirmation and token request`, async () => { const calls = []; const h = loadBackground({ family, fetch: async (url, options) => { calls.push({ url, options }); if (url.includes("/resourceUsers?")) return withClientId({ resourcePartyId: 303 }, 200, "response-client"); if (url.endsWith("/Catalogue_c/505")) return response({ result: "test-token" }); return response({ SrNumber: "SR1" }, 201); } }); const prepared = await h.dispatch({ type, phase: "prepare", emailAddress, payload: payload() }); assert.equal(prepared.ok, true); assert.equal(prepared.headers.requestSrTokenCatalog["x-appbuilder-client-id"], "response-client"); assert.deepEqual(prepared.headers.requestPostServiceRequest, { ...prepared.headers.requestSrTokenCatalog, "vb-proxy-header-x-oracle-ectoken": "(generated after confirmation)" }); assert.equal(calls.length, 1); const result = await h.dispatch({ type, phase: "confirm", catalogId: 505, payload: prepared.payload }); assert.equal(result.ok, true); assert.equal(calls[1].options.headers["x-appbuilder-client-id"], "response-client"); assert.deepEqual({ ...calls[2].options.headers }, { ...calls[1].options.headers, "vb-proxy-header-x-oracle-ectoken": "test-token" }); assert.equal(calls.filter(call => call.url.endsWith("/mgmt/serviceRequests")).length, 1); }); } test("response observation includes background responses and excludes other apps and private requests", async () => { const h = loadBackground(); assert.equal(h.responseHeaderListeners.length, 1); const capture = h.responseHeaderListeners[0]; assert.deepEqual(capture.options, ["responseHeaders"]); const details = { tabId: -1, url: "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live;profile=PROD/services/auth/1.1/proxy/example", responseHeaders: [{ name: "X-AppBuilder-Client-ID", value: "background-response-client" }, { name: "Set-Cookie", value: "not-retained" }] }; capture.listener({ ...details, incognito: true }); capture.listener({ ...details, url: details.url.replace("SeaaS_initiation", "unrelated") }); assert.deepEqual(h.sessionStorage, {}); capture.listener(details); assert.equal(Object.values(h.sessionStorage)[0].value, "background-response-client"); assert.ok(!JSON.stringify(h.sessionStorage).includes("not-retained")); }); test("token 403 retries once only with a newly returned client ID; SR POST is never retried", async () => { for (const mode of ["recovered", "still-forbidden", "unchanged", "no-header", "save-failure"]) { const calls = []; let tokens = 0; const h = loadBackground({ fetch: async (url, options) => { calls.push({ url, options }); if (url.includes("/resourceUsers?")) return withClientId({ resourcePartyId: 303 }, 200, "old-client"); if (url.endsWith("/Catalogue_c/505")) { tokens += 1; if (tokens === 1) return mode === "no-header" ? response({}, 403) : withClientId({}, 403, mode === "unchanged" ? "old-client" : "new-client"); if (mode === "still-forbidden") return withClientId({}, 403, "another-client"); return response({ result: "retry-token" }); } return response({ SrNumber: "SR1" }, mode === "save-failure" ? 403 : 201); } }); const prepared = await h.dispatch({ type, phase: "prepare", emailAddress, payload: payload() }); const result = await h.dispatch({ type, phase: "confirm", catalogId: 505, payload: prepared.payload }); assert.equal(result.ok, mode === "recovered"); const expectedTokens = ["unchanged", "no-header"].includes(mode) ? 1 : 2; assert.equal(tokens, expectedTokens); const tokenCalls = calls.filter(call => call.url.endsWith("/Catalogue_c/505")); assert.equal(tokenCalls[0].options.headers["x-appbuilder-client-id"], "old-client"); if (expectedTokens === 2) assert.equal(tokenCalls[1].options.headers["x-appbuilder-client-id"], "new-client"); assert.equal(calls.filter(call => call.url.endsWith("/mgmt/serviceRequests")).length, ["recovered", "save-failure"].includes(mode) ? 1 : 0); if (["recovered", "save-failure"].includes(mode)) { assert.deepEqual({ ...calls.at(-1).options.headers }, { ...tokenCalls.at(-1).options.headers, "vb-proxy-header-x-oracle-ectoken": "retry-token" }); } assertDebugVisibility(result, "retry-token"); } }); for (const family of ["chrome", "firefox"]) { test(`${family}: Save resolves current user, discovers catalog, obtains token and creates SR once with protected diagnostics`, async () => { const calls = []; const h = loadBackground({ family, fetch: async (url, options) => { calls.push({ url, options }); if (calls.length === 1) return response({ emailAddress, resourceEmail: emailAddress, resourcePartyId: 303, resourceProfileId: 999 }); if (calls.length === 2) return response({ items: [{ Id: 505 }] }); if (calls.length === 3) return response({ result: "synthetic-secret-token" }); return response({ SrId: 606, SrNumber: "SR606" }, 201); } }); const prepared = await h.dispatch({ type, phase: "prepare", emailAddress, payload: { ...payload(), ReportedByPartyId: 999 } }); assert.equal(prepared.ok, true); assert.equal(calls.length, 1, "preview only resolves the user, never generates a token or creates SR"); assert.equal(h.headerRules.length, 0, "preview does not install request modifications"); assert.equal(prepared.headers.requestSrTokenCatalog["Content-Type"], "application/vnd.oracle.adf.action+json"); assert.equal(prepared.headers.requestPostServiceRequest["vb-proxy-header-x-oracle-ectoken"], "(generated after confirmation)"); assert.equal(prepared.payload.ReportedByPartyId, 303); const result = await h.dispatch({ type, phase: "confirm", payload: prepared.payload }); assert.equal(result.ok, true); assert.equal(result.result.SrNumber, "SR606"); assert.equal(calls.length, 4); assert.equal(calls[0].options.method, "GET"); assert.equal(new URL(calls[0].url).searchParams.get("emailAddress"), emailAddress); assert.ok(calls[0].url.includes("/set/seaas/crm/resourceUsers?")); assert.equal(calls[1].options.method, "GET"); assert.ok(calls[2].url.endsWith("/Catalogue_c/505")); assert.deepEqual(JSON.parse(calls[2].options.body), { name: "getJwtToken" }); assert.equal(calls[2].options.headers["Content-Type"], "application/vnd.oracle.adf.action+json"); assert.equal(calls[2].options.headers.Origin, new URL(calls[2].url).origin); assert.deepEqual({ ...calls[3].options.headers }, { ...calls[2].options.headers, "vb-proxy-header-x-oracle-ectoken": "synthetic-secret-token" }); assert.equal(h.headerRules.length, 1); const rule = h.headerRules[0].addRules[0]; const serviceRule = h.headerRules[0].addRules[1]; assert.ok(new RegExp(serviceRule.condition.regexFilter).test(calls[3].url)); assert.ok(!new RegExp(serviceRule.condition.regexFilter).test(calls[2].url)); assert.ok(!new RegExp(serviceRule.condition.regexFilter).test(calls[3].url + "/other")); assert.deepEqual(serviceRule.condition.initiatorDomains, ["synthetic-extension"]); assert.deepEqual(serviceRule.condition.requestMethods, ["post"]); assert.deepEqual(serviceRule.action, rule.action); assert.deepEqual(rule.condition.initiatorDomains, ["synthetic-extension"]); assert.deepEqual(rule.condition.requestMethods, ["post"]); assert.ok(new RegExp(rule.condition.regexFilter).test(calls[2].url)); assert.ok(!new RegExp(rule.condition.regexFilter).test(calls[3].url)); assert.ok(!new RegExp(rule.condition.regexFilter).test(calls[2].url + "/other")); assert.deepEqual(rule.action.requestHeaders, [{ header: "Origin", operation: "set", value: new URL(calls[2].url).origin }]); assert.equal(calls[3].options.method, "POST"); assert.ok(calls[3].url.endsWith("/set/seaas/mgmt/serviceRequests")); assert.equal(calls[3].options.headers["vb-proxy-header-x-oracle-ectoken"], "synthetic-secret-token"); assert.ok(calls.slice(0, 3).every(call => !call.options.headers["vb-proxy-header-x-oracle-ectoken"])); assert.ok(calls.every(call => call.options.credentials === "include" && call.options.headers.Authorization === "Session")); assert.deepEqual(JSON.parse(calls[3].options.body), { ...payload(), ReportedByPartyId: 303, SvcQuestionsCollection_c: [], SourceCd: "SVC_OPPORTUNITY_SCREEN", SeverityCd: "ORA_SVC_SEV2", ChannelTypeCd: "ORA_SVC_WEB" }); assert.equal(calls[3].options.body, JSON.stringify(prepared.payload)); assertDebugVisibility(result, "synthetic-secret-token"); assert.equal(h.tabs.length, 0); }); } test("missing region, invalid dates or unsafe IDs stop before token acquisition", async () => { const h = loadBackground({ fetch: async () => assert.fail("Unexpected network") }); for (const change of [{ RegionText_c: null }, { CustomerDeadline_c: "2027-02-30" }, { AccountPartyId: "9007199254740993" }, { OpportunityName_Id_c: "bad/id" }]) { assert.equal((await h.dispatch({ type, phase: "prepare", emailAddress, payload: { ...payload(), ...change } })).ok, false); } assert.equal((await h.dispatch({ type, phase: "prepare", payload: payload() })).ok, false); assert.equal((await h.dispatch({ type, phase: "confirm", payload: payload() })).ok, false); assert.equal((await h.dispatch({ type, emailAddress, payload: payload() })).ok, false); }); for (const family of ["chrome", "firefox"]) { test(`${family}: captures only SeaaS client ID, reuses it after worker restart and expires stale values`, async () => { const tokenCalls = []; const sessionStorage = {}; const fetch = async (url, options) => { if (url.includes("/resourceUsers?")) return response({ resourcePartyId: 303 }); if (url.endsWith("/Catalogue_c/505")) { tokenCalls.push(options); return response({ result: "synthetic-token" }); } return response({ SrNumber: "SR1" }, 201); }; const h = loadBackground({ family, fetch, sessionStorage }); assert.equal(h.headerListeners.length, 1); const capture = h.headerListeners[0]; assert.deepEqual(capture.options, ["requestHeaders"]); assert.deepEqual(capture.filter.types, ["xmlhttprequest"]); const request = { tabId: 12, url: "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live;profile=PROD/services/auth/1.1/proxy/example", requestHeaders: [{ name: "X-AppBuilder-Client-Id", value: "synthetic-client" }, { name: "Cookie", value: "do-not-store-cookie" }, { name: "Authorization", value: "do-not-store-auth" }] }; capture.listener({ ...request, url: request.url.replace("SeaaS_initiation", "otherApp") }); capture.listener({ ...request, url: request.url.replace("comcipapic-oalprod.integration.ocp.oraclecloud.com", "other.example") }); capture.listener({ ...request, tabId: -1 }); capture.listener({ ...request, incognito: true }); capture.listener({ ...request, requestHeaders: [{ name: "x-appbuilder-client-id", value: "invalid\r\nheader" }] }); assert.deepEqual(sessionStorage, {}); capture.listener(request); assert.equal(Object.keys(sessionStorage).length, 1); assert.ok(!JSON.stringify(sessionStorage).includes("do-not-store")); const prepared = await h.dispatch({ type, phase: "prepare", emailAddress, payload: payload() }); assert.equal(prepared.headers.requestSrTokenCatalog["x-appbuilder-client-id"], "synthetic-client"); assert.equal(tokenCalls.length, 0); const restarted = loadBackground({ family, fetch, sessionStorage }); const result = await restarted.dispatch({ type, phase: "confirm", catalogId: 505, payload: prepared.payload }); assert.equal(result.ok, true); assert.equal(tokenCalls[0].headers["x-appbuilder-client-id"], "synthetic-client"); assert.equal(result.debugRequests[0].metadata.appBuilderClientId, "Observed in SeaaS requests"); restarted.advance(60 * 60 * 1000 + 1); const expired = await restarted.dispatch({ type, phase: "confirm", catalogId: 505, payload: prepared.payload }); assert.equal(expired.ok, true); assert.equal(tokenCalls[1].headers["x-appbuilder-client-id"], undefined); assert.equal(expired.debugRequests[0].metadata.appBuilderClientId, "Not observed in SeaaS requests"); capture.listener({ ...request, requestHeaders: [{ name: "x-appbuilder-client-id", value: "renewed-client" }] }); const refreshed = await h.dispatch({ type, phase: "prepare", emailAddress, payload: payload() }); assert.equal(refreshed.headers.requestSrTokenCatalog["x-appbuilder-client-id"], "renewed-client"); assert.equal(h.tabs.length, 0, "header discovery does not add background page loads"); }); } test("Origin rule failure blocks token acquisition and SR creation", async () => { const h = loadBackground({ ruleError: true, fetch: async () => assert.fail("No request expected") }); const result = await h.dispatch({ type, phase: "confirm", catalogId: 505, payload: { ...payload(), ReportedByPartyId: 303 } }); assert.equal(result.ok, false); assert.match(result.error, /Rule permission denied/); }); test("Origin rule failure prevents the Internal SR POST", async () => { const calls = []; const h = loadBackground({ ruleError: true, fetch: async url => { calls.push(url); if (url.includes("/serviceRequests?")) return response({ items: [parentInfo()] }); assert.match(url, /\/resourceUsers\?/); return response({ resourcePartyId: 303 }); } }); const result = await h.dispatch({ type: internalType, emailAddress, payload: internalInput() }); assert.equal(result.ok, false); assert.match(result.error, /Rule permission denied/); assert.equal(calls.length, 2); }); test("resource lookup failures or invalid resourcePartyId never obtain a token or create SR", async () => { for (const body of [{ resourcePartyId: null }, { resourceProfileId: 999 }, { resourcePartyId: "9007199254740993" }, { resourcePartyId: 0 }, "unauthorized"]) { let calls = 0; const h = loadBackground({ fetch: async () => { calls += 1; return response(body, body === "unauthorized" ? 401 : 200); } }); const result = await h.dispatch({ type, phase: "prepare", emailAddress, payload: payload() }); assert.equal(result.ok, false); assert.equal(calls, 1); assert.equal(result.debugRequests[0].name, "requestResourceUser"); } }); test("token rejection never creates SR; creation failures are never automatically retried", async () => { for (const failure of ["token", "create", "empty-token", "network"]) { let calls = 0; const h = loadBackground({ fetch: async () => { calls += 1; if (calls === 1) return response({ resourcePartyId: 303 }); if (calls === 2) return failure === "token" ? response({}, 401) : response({ result: failure === "empty-token" ? "" : "secret-token" }); if (failure === "network") throw new Error("Network error"); return response({}, 500); } }); const prepared = await h.dispatch({ type, phase: "prepare", emailAddress, payload: payload() }); const result = await h.dispatch({ type, phase: "confirm", catalogId: 505, payload: prepared.payload }); assert.equal(result.ok, false); assert.equal(calls, failure === "token" || failure === "empty-token" ? 2 : 3); assertDebugVisibility(result, "secret-token"); assert.equal(h.tabs.length, 0); } });