Implemented a retry mechanism for retrieving the SPA token
This commit is contained in:
@@ -22,7 +22,7 @@ function createResponse(body, contentType) {
|
||||
};
|
||||
}
|
||||
|
||||
function loadBackground(responses, createdTabs, removedTabs) {
|
||||
function loadBackground(responses, createdTabs, removedTabs, options = {}) {
|
||||
let listener;
|
||||
const source = fs.readFileSync(path.join(root, "src", "background.js"), "utf8");
|
||||
const context = {
|
||||
@@ -37,6 +37,9 @@ function loadBackground(responses, createdTabs, removedTabs) {
|
||||
tabs: {
|
||||
async create(details) {
|
||||
createdTabs.push(details);
|
||||
if (options.createTab) {
|
||||
return options.createTab(details);
|
||||
}
|
||||
return { id: 27 };
|
||||
},
|
||||
async remove(tabId) {
|
||||
@@ -45,6 +48,9 @@ function loadBackground(responses, createdTabs, removedTabs) {
|
||||
}
|
||||
},
|
||||
fetch: async () => {
|
||||
if (options.onFetch) {
|
||||
options.onFetch();
|
||||
}
|
||||
const response = responses.shift();
|
||||
|
||||
if (!response) {
|
||||
@@ -64,7 +70,7 @@ function loadBackground(responses, createdTabs, removedTabs) {
|
||||
Object,
|
||||
Number,
|
||||
Math,
|
||||
setTimeout,
|
||||
setTimeout: options.setTimeout || setTimeout,
|
||||
clearTimeout
|
||||
};
|
||||
|
||||
@@ -113,6 +119,56 @@ async function run() {
|
||||
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.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user