Files
opportunities-extension/tests/consumerTokenSessionRetry.test.cjs

179 lines
5.4 KiB
JavaScript

const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");
const vm = require("node:vm");
const root = path.resolve(__dirname, "..");
function createResponse(body, contentType) {
return {
ok: true,
status: 200,
statusText: "OK",
headers: {
get(name) {
return name.toLowerCase() === "content-type" ? contentType : null;
},
forEach(callback) {
callback(contentType, "content-type");
}
},
text: async () => body
};
}
function loadBackground(responses, createdTabs, removedTabs, options = {}) {
let listener;
const source = fs.readFileSync(path.join(root, "src", "background.js"), "utf8");
const context = {
chrome: {
runtime: {
onMessage: {
addListener(callback) {
listener = callback;
}
}
},
tabs: {
async create(details) {
createdTabs.push(details);
if (options.createTab) {
return options.createTab(details);
}
return { id: 27 };
},
async remove(tabId) {
removedTabs.push(tabId);
}
}
},
fetch: async () => {
if (options.onFetch) {
options.onFetch();
}
const response = responses.shift();
if (!response) {
throw new Error("Unexpected fetch call.");
}
return response;
},
Date,
Error,
JSON,
Map,
Set,
Promise,
String,
Array,
Object,
Number,
Math,
setTimeout: options.setTimeout || setTimeout,
clearTimeout
};
vm.runInNewContext(source, context);
return listener;
}
function dispatch(listener) {
return new Promise((resolve) => {
assert.equal(listener({ type: "opportunitiesExtension.requestConsumerTokenService" }, {
tab: { windowId: 1 }
}, resolve), true);
});
}
async function run() {
const createdTabs = [];
const removedTabs = [];
const listener = loadBackground([
createResponse("<html><body>Fallback</body></html>", "text/html"),
createResponse(JSON.stringify([
{
tokenService: "ACCP-TS",
uiaasHeader: { label: "Account-Ti-Authorization", value: "account-token" }
},
{
tokenService: "OCICONS-TS",
uiaasHeader: { label: "G2m-Authorization", value: "consumption-token" }
}
]), "application/json")
], createdTabs, removedTabs);
const response = await dispatch(listener);
assert.equal(response.ok, true);
assert.equal(response.authorizations.accountSummary.value, "account-token");
assert.equal(response.authorizations.accountPlans.value, "consumption-token");
assert.equal(createdTabs.length, 1);
assert.equal(createdTabs[0].active, false);
assert.equal(
createdTabs[0].url,
"https://spa.oracle.com/oalcrm/web/api/g2m-consumer-application/ui/index.html"
);
assert.deepEqual(removedTabs, [27]);
assert.equal(response.debugRequests.length, 2);
assert.equal(response.debugRequests[0].status, "failed");
assert.equal(response.debugRequests[0].metadata.sessionBootstrapState, "opened-inactive-tab");
assert.equal(response.debugRequests[1].metadata.sessionBootstrapState, "closed-after-valid-json");
// Even six opening failures must leave the second token request available.
const retryTabs = [];
const retryRemovedTabs = [];
const delays = [];
let tokenRequests = 0;
let openAttempts = 0;
const retryListener = loadBackground([
createResponse("<html>Fallback</html>", "text/html"),
createResponse(JSON.stringify([
{ tokenService: "ACCP-TS", uiaasHeader: { value: "account-token" } },
{ tokenService: "OCICONS-TS", uiaasHeader: { value: "consumption-token" } }
]), "application/json")
], retryTabs, retryRemovedTabs, {
onFetch() { tokenRequests += 1; },
createTab() {
assert.equal(tokenRequests, 1, "Token requests must wait for the tab to open");
openAttempts += 1;
if (openAttempts <= 6) {
throw new Error("Temporary tab creation failure");
}
return { id: 81 };
},
setTimeout(callback, delay) {
delays.push(delay);
return setTimeout(callback, 0);
}
});
const retryResponse = await dispatch(retryListener);
assert.equal(retryResponse.ok, true);
assert.equal(tokenRequests, 2);
assert.equal(openAttempts, 7);
assert.deepEqual(retryRemovedTabs, [81]);
assert.deepEqual(delays.slice(0, 6), [750, 1500, 3000, 4000, 4000, 4000]);
assert.ok(retryTabs.every(tab => tab.active === false && tab.windowId === 1));
assert.equal(retryResponse.debugRequests[0].metadata.sessionTabOpenAttempt, "7");
assert.equal(retryResponse.debugRequests[0].metadata.sessionTabLastOpenError, "Temporary tab creation failure");
assert.equal(retryResponse.debugRequests[0].metadata.sessionTabNextRetryDelayMs, undefined);
const failedTabs = [];
const failedRemovedTabs = [];
const exhausted = await dispatch(loadBackground(
Array.from({ length: 5 }, () => createResponse("<html>Fallback</html>", "text/html")),
failedTabs, failedRemovedTabs,
{ setTimeout: callback => setTimeout(callback, 0) }
));
assert.equal(exhausted.ok, false);
assert.match(exhausted.error, /after 5 attempts/);
assert.equal(failedTabs.length, 1);
assert.deepEqual(failedRemovedTabs, [27]);
console.log("Consumer token session retry tests passed.");
}
run().catch((error) => {
console.error(error);
process.exitCode = 1;
});