Added the Refresh All button to invalidate caches and force requests to be sent again
This commit is contained in:
92
tests/activityCache.test.cjs
Normal file
92
tests/activityCache.test.cjs
Normal file
@@ -0,0 +1,92 @@
|
||||
const assert = require("node:assert/strict");
|
||||
const { test } = require("node:test");
|
||||
const { loadApplication } = require("./support/application.cjs");
|
||||
const flush = () => new Promise(resolve => setImmediate(resolve));
|
||||
function setup(family, saved = {}, principal = "user@example.invalid") {
|
||||
const local = {
|
||||
get: async key => ({ [key]: saved[key] }),
|
||||
set: async values => Object.assign(saved, JSON.parse(JSON.stringify(values)))
|
||||
};
|
||||
const api = family === "firefox" ? { browser: { storage: { local } } } : {
|
||||
chrome: { runtime: {}, storage: { local: {
|
||||
get: (key, done) => local.get(key).then(done), set: (values, done) => local.set(values).then(done)
|
||||
} } }
|
||||
};
|
||||
const app = loadApplication("content", { ...api, document: { createElement: () => ({ setAttribute() {}, addEventListener() {} }) } });
|
||||
app.authSessionState.principal = principal;
|
||||
app.currentUser.allowsCrmActivities = () => true;
|
||||
app.preferencesState.opptyProductsCacheHours = 24;
|
||||
app.opportunitiesQueryState.periodRequestVersion = 1;
|
||||
app.activityProgress.update = () => {};
|
||||
app.productsContentJobs.queueProductsTableRender = () => {};
|
||||
app.debugContentLog.appendBackgroundRequestLog = () => {};
|
||||
app.authContentSession.requestConsumerTokenServiceOnce = async () => ({ workloadActions: { value: "synthetic-token" } });
|
||||
const calls = [];
|
||||
app.fusionCrmServiceRequests.requestCrmServiceRequest = async () => {
|
||||
calls.push("sr");
|
||||
return [{ SrNumber: "SR1", ReportedHours_c: 4, OpportunityName_Id_c: { OptyNumber: "OP1" } }];
|
||||
};
|
||||
app.platformContentMessages.sendRuntimeMessage = async () => {
|
||||
calls.push("actions");
|
||||
return { ok: true, actions: [{ owner: principal, name: "Test action" }], hasNext: false };
|
||||
};
|
||||
async function load(cachedAt, cacheOnly) {
|
||||
app.opportunityCrmServiceRequests.reset();
|
||||
await app.opportunityCrmServiceRequests.load("synthetic-token", 1, { cachedAt, cacheOnly });
|
||||
const products = { items: [{ RevnId: "123" }], cachedAt, fromCache: cacheOnly };
|
||||
app.productsContentState.opptyProductsByNumber.set("OP1", products);
|
||||
app.opportunityWorkloadActions.loadProducts(products, true, { cachedAt, cacheOnly });
|
||||
await flush();
|
||||
}
|
||||
return { app, calls, load, saved, local };
|
||||
}
|
||||
for (const family of ["chrome", "firefox"]) {
|
||||
test(`${family}: activities persist across instances with product timestamps and no credential storage`, async () => {
|
||||
const h = setup(family);
|
||||
const stamp = Date.now() - 1000;
|
||||
await h.load(stamp, false);
|
||||
assert.deepEqual(h.calls, ["sr", "actions"]);
|
||||
assert.equal(Object.keys(h.saved).length, 2);
|
||||
Object.values(h.saved).forEach(entry => assert.equal(entry.fetchedAt, stamp));
|
||||
assert.doesNotMatch(JSON.stringify(h.saved), /synthetic-token|debugRequests|authorization/i);
|
||||
const restored = setup(family, h.saved);
|
||||
await restored.load(stamp, true);
|
||||
assert.deepEqual(restored.calls, []);
|
||||
assert.equal(restored.app.opportunityCrmServiceRequests.createBadge("OP1").textContent, "\u2705 SR (4h)");
|
||||
assert.equal(restored.app.opportunityWorkloadActions.createBadge("OP1").textContent, "\u2705 Act");
|
||||
await restored.load(stamp, false);
|
||||
assert.deepEqual(restored.calls, [], "valid matching cache also deduplicates repeated fresh-product notifications");
|
||||
const other = setup(family, h.saved, "other@example.invalid");
|
||||
await other.load(stamp, true);
|
||||
assert.deepEqual(other.calls, []);
|
||||
assert.equal(other.app.opportunityCrmServiceRequests.createBadge("OP1"), null);
|
||||
assert.equal(other.app.opportunityWorkloadActions.createBadge("OP1").textContent, "Act ?");
|
||||
await restored.load(stamp + 1, false);
|
||||
assert.deepEqual(restored.calls, ["sr", "actions"]);
|
||||
});
|
||||
}
|
||||
test("TTL follows product preferences, rejects stale/mismatched cache and stores empty success", async () => {
|
||||
const h = setup("firefox");
|
||||
const stamp = Date.now() - 2 * 3600000;
|
||||
await h.app.activityCache.write("sr", "all", stamp, []);
|
||||
assert.ok(await h.app.activityCache.read("sr", "all", stamp));
|
||||
h.app.preferencesState.opptyProductsCacheHours = 1;
|
||||
assert.equal(await h.app.activityCache.read("sr", "all", stamp), null);
|
||||
h.app.preferencesState.opptyProductsCacheHours = 24;
|
||||
assert.equal(await h.app.activityCache.read("sr", "all", stamp + 1), null);
|
||||
assert.equal(await h.app.activityCache.read("sr", "all", Date.now() + 100000), null);
|
||||
await h.load(stamp + 1, true);
|
||||
assert.deepEqual(h.calls, []);
|
||||
});
|
||||
test("storage failure does not lose live activity results and failures are never cached", async () => {
|
||||
const h = setup("firefox");
|
||||
h.local.get = async () => { throw new Error("Synthetic storage read failure"); };
|
||||
h.local.set = async () => { throw new Error("Synthetic storage write failure"); };
|
||||
await h.load(Date.now() - 1000, false);
|
||||
assert.equal(h.app.opportunityCrmServiceRequests.createBadge("OP1").textContent, "\u2705 SR (4h)");
|
||||
const failed = setup("firefox");
|
||||
failed.app.fusionCrmServiceRequests.requestCrmServiceRequest = async () => { throw new Error("Synthetic failure"); };
|
||||
failed.app.platformContentMessages.sendRuntimeMessage = async () => ({ ok: false });
|
||||
await failed.load(Date.now() - 1000, false);
|
||||
assert.deepEqual(failed.saved, {});
|
||||
});
|
||||
Reference in New Issue
Block a user