Partially implemented the Manage Time functionality
This commit is contained in:
71
tests/formRequestCache.test.cjs
Normal file
71
tests/formRequestCache.test.cjs
Normal file
@@ -0,0 +1,71 @@
|
||||
const assert = require("node:assert/strict");
|
||||
const fs = require("node:fs");
|
||||
const vm = require("node:vm");
|
||||
const { test } = require("node:test");
|
||||
const { loadBackground } = require("./support/characterization.cjs");
|
||||
function setup() {
|
||||
let now = 100000, hours = 24, user = "a@example.invalid";
|
||||
const factory = new vm.Script(fs.readFileSync("src/features/preferences/request-cache.js", "utf8") + "\ncreateFormRequestCache;").runInNewContext({ Date: { now: () => now } });
|
||||
const cache = factory({ getHours: () => hours, getUserId: () => user });
|
||||
return { cache, advance: value => { now += value; }, hours: value => { hours = value; }, user: value => { user = value; } };
|
||||
}
|
||||
const message = (name, fields = {}) => ({ type: `opportunitiesExtension.${name}`, ...fields });
|
||||
test("all four form query families reuse successes with parameter-specific keys and live duration", async () => {
|
||||
const h = setup(); let calls = 0;
|
||||
const fetch = async request => { calls++; assert.equal(request.cacheMaxAgeMs, 24 * 3600000); return { ok: true, items: [{ name: "Original" }], debugRequests: [{ name: "network" }] }; };
|
||||
for (const name of ["requestWeekDetails", "requestActiveServiceRequests", "requestServiceRequestExpand", "requestLookupTaskType", "requestActionTeamMembers", "requestActionFindLookup", "requestSrLookupPrimaryPillar", "requestSrLookupLanguage", "requestSrLookupTechPlatform", "requestSrLookupOpportunityBusiness", "requestLookupTypePlatform", "requestInternalSrServices"]) {
|
||||
const msg = message(name, { id: 1 });
|
||||
const result = await h.cache.send(msg, fetch); result.items[0].name = "Edited";
|
||||
const cached = await h.cache.send(msg, fetch);
|
||||
assert.equal(cached.fromCache, true); assert.equal(cached.items[0].name, "Original"); assert.equal(cached.debugRequests.length, 0);
|
||||
await h.cache.send(message(name, { id: 2 }), fetch);
|
||||
}
|
||||
assert.equal(calls, 24);
|
||||
h.advance(2 * 3600000); h.hours(1);
|
||||
await h.cache.send(message("requestWeekDetails", { id: 1 }), async request => { calls++; assert.equal(request.cacheMaxAgeMs, 3600000); return { ok: true }; });
|
||||
assert.equal(calls, 25);
|
||||
});
|
||||
test("failed results are never cached and identity changes discard previous responses", async () => {
|
||||
const h = setup(); let calls = 0;
|
||||
const send = async () => { calls++; return { ok: calls > 1 }; };
|
||||
const msg = message("requestLookupTaskType");
|
||||
await h.cache.send(msg, send); await h.cache.send(msg, send); await h.cache.send(msg, send); assert.equal(calls, 2);
|
||||
h.user("b@example.invalid"); await h.cache.send(msg, send); assert.equal(calls, 3);
|
||||
h.user(""); await h.cache.send(msg, send); await h.cache.send(msg, send); assert.equal(calls, 5);
|
||||
});
|
||||
test("writes and token requests always execute; successful saves and Refresh all invalidate queries", async () => {
|
||||
for (const name of ["requestMgmtAction", "requestPostServiceRequest", "requestPostInternalServiceRequest", "invalidateProductsCache"]) {
|
||||
const h = setup(); let queries = 0, writes = 0;
|
||||
const query = message("requestActionFindLookup");
|
||||
const queryTransport = async () => { queries++; return { ok: true }; };
|
||||
await h.cache.send(query, queryTransport);
|
||||
for (let i = 0; i < 2; i++) await h.cache.send(message(name, { phase: "confirm" }), async () => { writes++; return { ok: true }; });
|
||||
await h.cache.send(query, queryTransport);
|
||||
assert.equal(writes, 2); assert.equal(queries, 2);
|
||||
}
|
||||
const h = setup(); let calls = 0;
|
||||
for (let i = 0; i < 2; i++) await h.cache.send(message("requestSrTokenCatalog"), async () => { calls++; return { ok: true }; });
|
||||
assert.equal(calls, 2);
|
||||
});
|
||||
test("concurrent queries share work but old responses cannot repopulate an invalidated cache", async () => {
|
||||
const h = setup(); let resolve, calls = 0;
|
||||
const msg = message("requestLookupTypePlatform");
|
||||
const transport = () => { calls++; return new Promise(done => { resolve = done; }); };
|
||||
const first = h.cache.send(msg, transport), second = h.cache.send(msg, transport);
|
||||
assert.equal(calls, 1); h.cache.invalidate(); resolve({ ok: true, items: [] }); await Promise.all([first, second]);
|
||||
await h.cache.send(msg, async () => { calls++; return { ok: true }; }); assert.equal(calls, 2);
|
||||
});
|
||||
test("resource user respects duration and Refresh all invalidation", async () => {
|
||||
let calls = 0;
|
||||
const app = loadBackground({ fetch: async () => { calls++; return new Response(JSON.stringify({ resourcePartyId: 123 })); } });
|
||||
const msg = message("requestResourceUser", { emailAddress: "a@example.invalid", cacheMaxAgeMs: 3600000 });
|
||||
await app.dispatch(msg); await app.dispatch(msg); assert.equal(calls, 1);
|
||||
app.advance(3600000); await app.dispatch(msg); assert.equal(calls, 2);
|
||||
await app.dispatch(message("invalidateProductsCache")); await app.dispatch(msg); assert.equal(calls, 3);
|
||||
});
|
||||
test("Preferences displays generic cache duration while preserving the saved preference key", () => {
|
||||
const source = fs.readFileSync("src/features/preferences/view.js", "utf8");
|
||||
assert.match(source, /cacheLabel.textContent = "Cache duration"/);
|
||||
assert.doesNotMatch(source, /Product cache duration/);
|
||||
assert.match(source, /cacheSelect.name = "opptyProductsCacheHours"/);
|
||||
});
|
||||
Reference in New Issue
Block a user