110 lines
3.9 KiB
JavaScript
110 lines
3.9 KiB
JavaScript
const assert = require("node:assert/strict");
|
|
const { test } = require("node:test");
|
|
const { loadApplication } = require("./support/application.cjs");
|
|
|
|
function fixture(reduced = false) {
|
|
let now = 0, nextId = 0;
|
|
const timers = new Map();
|
|
const badge = { hidden: false, attributes: {}, setAttribute(key, value) { this.attributes[key] = value; } };
|
|
const timestamp = {};
|
|
const app = loadApplication("content", {
|
|
document: { getElementById: id => id === app.contracts.PRODUCTS_PROGRESS_ID ? badge : timestamp, querySelector: () => badge },
|
|
setTimeout: (fn, delay) => { const id = ++nextId; timers.set(id, { fn, at: now + delay }); return id; },
|
|
clearTimeout: id => timers.delete(id), matchMedia: () => ({ matches: reduced })
|
|
});
|
|
const render = state => {
|
|
app.productsContentState.productsProgress = { state, completed: 2, total: 2, failed: 0, cacheHits: 0 };
|
|
app.productsContentJobs.renderProductsProgress();
|
|
};
|
|
function advance(ms) {
|
|
const end = now + ms;
|
|
while (true) {
|
|
const entry = [...timers].filter(([, timer]) => timer.at <= end).sort((a, b) => a[1].at - b[1].at)[0];
|
|
if (!entry) break;
|
|
now = entry[1].at;
|
|
timers.delete(entry[0]);
|
|
entry[1].fn();
|
|
}
|
|
now = end;
|
|
}
|
|
app.productsContentState.currentProductsRequestId = "first";
|
|
app.productsContentState.productsLastCachedAt = 1;
|
|
return { app, badge, timestamp, render, advance, timers };
|
|
}
|
|
|
|
test("Products ready stays for five seconds then fades for 300ms before hidden", () => {
|
|
const h = fixture();
|
|
h.render("complete");
|
|
h.advance(4999);
|
|
assert.equal(h.badge.hidden, false);
|
|
assert.equal(h.badge.attributes["data-fading"], "false");
|
|
h.render("complete");
|
|
h.advance(1);
|
|
assert.equal(h.badge.attributes["data-fading"], "true");
|
|
assert.equal(h.badge.hidden, false);
|
|
h.advance(300);
|
|
assert.equal(h.badge.hidden, true);
|
|
h.render("complete");
|
|
assert.equal(h.badge.hidden, true, "rerenders do not restart the completion timer");
|
|
assert.equal(h.timestamp.hidden, false, "Last update remains visible");
|
|
});
|
|
|
|
test("new product jobs cancel a pending fade and errors remain visible", () => {
|
|
const h = fixture();
|
|
h.render("complete");
|
|
h.advance(5000);
|
|
h.app.productsContentState.currentProductsRequestId = "second";
|
|
h.render("running");
|
|
h.advance(10000);
|
|
assert.equal(h.badge.hidden, false);
|
|
assert.equal(h.badge.attributes["data-fading"], "false");
|
|
assert.equal(h.timers.size, 0);
|
|
for (const state of ["complete-with-errors", "error"]) {
|
|
h.render(state);
|
|
h.advance(10000);
|
|
assert.equal(h.badge.hidden, false);
|
|
}
|
|
h.render("complete");
|
|
h.advance(5300);
|
|
assert.equal(h.badge.hidden, true);
|
|
});
|
|
|
|
test("reduced motion hides at five seconds without an animated delay", () => {
|
|
const h = fixture(true);
|
|
h.render("complete");
|
|
h.advance(5000);
|
|
assert.equal(h.badge.hidden, true);
|
|
});
|
|
|
|
test("Authenticated fades after five seconds without restarting on repeated status updates", () => {
|
|
const h = fixture();
|
|
const update = () => h.app.contentModal.updateAuthBadge(h.app.contracts.AUTH_STATUS.authenticated);
|
|
update();
|
|
h.advance(4999);
|
|
assert.equal(h.badge.hidden, false);
|
|
update();
|
|
h.advance(1);
|
|
assert.equal(h.badge.attributes["data-fading"], "true");
|
|
h.advance(300);
|
|
assert.equal(h.badge.hidden, true);
|
|
update();
|
|
assert.equal(h.badge.hidden, true);
|
|
h.app.contentModal.updateAuthBadge(h.app.contracts.AUTH_STATUS.unauthenticated);
|
|
h.advance(10000);
|
|
assert.equal(h.badge.hidden, false);
|
|
assert.equal(h.badge.attributes["data-fading"], "false");
|
|
update();
|
|
h.advance(5000);
|
|
h.app.contentModal.updateAuthBadge(h.app.contracts.AUTH_STATUS.pending);
|
|
h.advance(300);
|
|
assert.equal(h.badge.hidden, false);
|
|
assert.equal(h.badge.textContent, "Authenticating");
|
|
});
|
|
|
|
test("Authenticated respects reduced motion", () => {
|
|
const h = fixture(true);
|
|
h.app.contentModal.updateAuthBadge(h.app.contracts.AUTH_STATUS.authenticated);
|
|
h.advance(5000);
|
|
assert.equal(h.badge.hidden, true);
|
|
});
|