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

94 lines
4.1 KiB
JavaScript

const assert = require("node:assert/strict");
const { test } = require("node:test");
const { loadApplication } = require("./support/application.cjs");
test("failed preparation exposes Retry, deduplicates clicks and removes it on success", async () => {
const host = { append() {} };
const nodes = [];
const app = loadApplication("content", {
document: { querySelector: () => host, getElementById: () => null,
createElement: tag => {
const node = { tag, children: [], setAttribute() {}, append(child) { this.children.push(child); },
addEventListener(_event, fn) { this.click = fn; },
set textContent(value) { this.text = value; this.children = []; } };
nodes.push(node); return node;
} },
setTimeout: () => 1, clearTimeout() {}
});
let attempts = 0;
app.currentUser.ensure = async () => {};
app.currentUser.allowsCrmActivities = () => true;
app.currentUser.getUserId = () => "test@example.invalid";
app.debugContentLog.appendBackgroundRequestLog = () => {};
app.platformContentMessages.sendRuntimeMessage = async message => {
if (message.type === "opportunitiesExtension.requestResourceUser") return { ok: true };
return { ok: ++attempts > 1 };
};
await app.srSessionPreparation.ensure();
const retry = nodes.find(node => node.tag === "button");
assert.equal(retry.text, "Retry");
retry.click();
const pending = app.srSessionPreparation.retry();
assert.equal(app.srSessionPreparation.retry(), pending);
await pending;
assert.equal(attempts, 2);
assert.equal(nodes[0].text, "SR session ready");
assert.equal(nodes[0].children.length, 0);
await app.srSessionPreparation.retry();
assert.equal(attempts, 2);
});
test("preparation runs once, shares pending work and reports loading and completion", async () => {
const app = loadApplication("content");
const progress = [];
let requests = 0;
let resourceRequests = 0;
let resolveUser, resolveSession;
app.currentUser.ensure = () => new Promise(resolve => { resolveUser = resolve; });
app.currentUser.allowsCrmActivities = () => true;
app.currentUser.getUserId = () => "test@example.invalid";
app.activityProgress.update = (...args) => progress.push(args);
app.debugContentLog.appendBackgroundRequestLog = () => {};
app.platformContentMessages.sendRuntimeMessage = message => {
if (message.type === "opportunitiesExtension.requestResourceUser") {
resourceRequests += 1;
assert.equal(message.emailAddress, "test@example.invalid");
assert.deepEqual(progress.at(-1), ["session", "complete"]);
return Promise.resolve({ ok: true, resource: { resourcePartyId: 123 } });
}
assert.equal(message.type, "opportunitiesExtension.prepareSrSession");
requests += 1;
return new Promise(resolve => { resolveSession = resolve; });
};
const first = app.srSessionPreparation.ensure();
assert.equal(app.srSessionPreparation.ensure(), first);
assert.equal(requests, 1, "SR session starts while SPA identity is pending");
assert.equal(resourceRequests, 0, "resource user still requires the identity");
resolveUser();
await new Promise(resolve => setImmediate(resolve));
assert.deepEqual(progress, [["session", "running"]]);
resolveSession({ ok: true });
await first;
await app.srSessionPreparation.ensure();
assert.equal(requests, 1);
assert.equal(resourceRequests, 1);
assert.deepEqual(progress.at(-1), ["session", "complete"]);
});
test("failed parallel preparation does not auto-repeat or reject modal loading", async () => {
for (const allowed of [false, true]) {
const app = loadApplication("content");
let requests = 0;
const progress = [];
app.currentUser.ensure = async () => {};
app.currentUser.allowsCrmActivities = () => allowed;
app.activityProgress.update = (...args) => progress.push(args);
app.debugContentLog.appendBackgroundRequestLog = () => {};
app.platformContentMessages.sendRuntimeMessage = async () => { requests += 1; return { ok: false }; };
await app.srSessionPreparation.ensure();
await app.srSessionPreparation.ensure();
assert.equal(requests, 1);
assert.deepEqual(progress, [["session", "running"], ["session", "error"]]);
}
});