const assert = require("node:assert/strict"); const { test } = require("node:test"); const { loadBackground, response } = require("./support/characterization.cjs"); const tokens = [ { tokenService: "ACCP-TS", uiaasHeader: { value: "synthetic-account" } }, { tokenService: "OCICONS-TS", uiaasHeader: { value: "synthetic-consumption" } }, { tokenService: "WWB-TS", uiaasHeader: { value: "synthetic-actions" } } ]; const request = { type: "opportunitiesExtension.requestConsumerTokenService" }; for (const family of ["chrome", "firefox"]) { for (const status of [401, 403]) { test(`${family}: HTTP ${status} opens an inactive SPA session and closes it after valid JSON`, async () => { let attempts = 0; const h = loadBackground({ family, fetch: async (_url, options) => { attempts += 1; assert.equal(options.credentials, "include"); if (attempts === 1) return response({ error: "Session unavailable" }, status); assert.equal(h.tabs.length, 1, "session tab must open before retrying"); return response(tokens); } }); const result = await h.dispatch(request); assert.equal(result.ok, true); assert.equal(attempts, 2); assert.equal(h.tabs.length, 1); assert.equal(h.tabs[0].active, false); assert.equal(h.tabs[0].windowId, 3); assert.equal(h.tabs[0].cookieStoreId, family === "firefox" ? "test-store" : undefined); assert.equal(h.tabs[0].url, "https://spa.oracle.com/"); assert.deepEqual(h.removedTabs, [91]); assert.equal(result.debugRequests[0].httpStatus, status); assert.match(result.debugRequests[0].metadata.retryReason, /SPA session recovery/); assert.equal(result.debugRequests[1].metadata.sessionBootstrapState, "closed-after-valid-json"); assert.equal(result.authorizations.workloadActions.value, "synthetic-actions"); }); } test(`${family}: persistent 403 stops after five attempts and removes the auxiliary tab`, async () => { let attempts = 0; const h = loadBackground({ family, fetch: async () => { attempts += 1; return response({}, 403); } }); const result = await h.dispatch(request); assert.equal(result.ok, false); assert.equal(attempts, 5); assert.equal(h.tabs.length, 1); assert.deepEqual(h.removedTabs, [91]); assert.match(result.error, /403 after 5 attempts/); assert.equal(result.debugRequests.at(-1).metadata.retryLimitReached, "true"); assert.equal(result.debugRequests.at(-1).metadata.sessionBootstrapState, "closed-after-retry-finished"); }); } test("mixed 403/HTML recovery shares one tab and the existing retry budget", async () => { let attempts = 0; const h = loadBackground({ fetch: async () => { attempts += 1; if (attempts === 1) return response({}, 403); if (attempts === 2) return new Response("Login"); return response(tokens); } }); const result = await h.dispatch(request); assert.equal(result.ok, true); assert.equal(attempts, 3); assert.equal(h.tabs.length, 1); assert.deepEqual(h.removedTabs, [91]); assert.equal(result.debugRequests[1].metadata.sessionBootstrapState, "waiting-for-valid-session"); }); test("unrelated HTTP failures do not launch the SPA session page", async () => { const h = loadBackground({ fetch: async () => response({}, 500) }); const result = await h.dispatch(request); assert.equal(result.ok, false); assert.equal(result.debugRequests.length, 1); assert.equal(h.tabs.length, 0); });