Defer media loading and strengthen persistence tests
All checks were successful
Deploy Sokko G / deploy (push) Successful in 18s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 18s
This commit is contained in:
parent
09a2d4b71a
commit
d0e1fd73b1
19 changed files with 459 additions and 71 deletions
43
tests/deferred-module-data.test.mjs
Normal file
43
tests/deferred-module-data.test.mjs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Rôle : vérifie la frontière entre médias différés, données vides et écritures concurrentes.
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { DEFERRED_MODULE_DATA as deferred, getDeferredModuleKeys, mergeLoadedModuleData, splitModuleData } from "../website/src/features/toolboxes/storage/deferredModuleData.js";
|
||||
import { createPersistenceQueue } from "../website/src/features/toolboxes/storage/persistenceQueue.js";
|
||||
|
||||
test("only images and annotations are deferred; alert and text tools remain available", () => {
|
||||
assert.deepEqual(getDeferredModuleKeys([{ id: "box", modules: [
|
||||
{ id: "image", type: "images" }, { id: "map", type: "imageAnnotation" },
|
||||
{ id: "timer", type: "timer" }, { id: "calendar", type: "calendar" },
|
||||
{ id: "memos", type: "memos" }, { id: "notepad", type: "notepad" }
|
||||
] }]), ["box:image", "box:map"]);
|
||||
assert.deepEqual(splitModuleData({ "box:image": deferred, "box:timer": { countdowns: [] } }), {
|
||||
stored: { "box:timer": { countdowns: [] } }, deferred: ["box:image"]
|
||||
});
|
||||
});
|
||||
|
||||
test("loading never replaces edits or resurrects deleted module data", () => {
|
||||
const data = { pending: deferred, missing: deferred, edited: { images: ["new"] } };
|
||||
const loaded = mergeLoadedModuleData(data, ["pending", "missing", "edited", "deleted"], [
|
||||
{ key: "pending", data: { image: "loaded" } }, { key: "edited", data: "old" }, { key: "deleted", data: "old" }
|
||||
]);
|
||||
assert.deepEqual(loaded, { pending: { image: "loaded" }, edited: { images: ["new"] } });
|
||||
assert.equal(data.pending, deferred);
|
||||
assert.equal(data.missing, deferred);
|
||||
});
|
||||
|
||||
for (const failDelete of [false, true]) {
|
||||
test(`a load queued during deletion follows its confirmed outcome (failure=${failDelete})`, async () => {
|
||||
let finish;
|
||||
const transaction = new Promise((resolve) => { finish = resolve; });
|
||||
const queue = createPersistenceQueue({ media: deferred }, () => {});
|
||||
const removal = queue.enqueue(() => ({}), async () => {
|
||||
await transaction;
|
||||
if (failDelete) throw new Error("abort");
|
||||
});
|
||||
const load = queue.enqueue((current) => mergeLoadedModuleData(current, ["media"], [{ key: "media", data: "kept" }]), () => {});
|
||||
finish();
|
||||
assert.equal(await removal, !failDelete);
|
||||
assert.equal(await load, true);
|
||||
assert.deepEqual(queue.getCurrent(), failDelete ? { media: "kept" } : {});
|
||||
});
|
||||
}
|
||||
|
|
@ -117,6 +117,7 @@ export function validateSiteContent(site) {
|
|||
"about.contribute.promptText",
|
||||
"toolboxes.eyebrow",
|
||||
"toolboxes.storageStatus.loadingTitle",
|
||||
"toolboxes.storageStatus.mediaLoadingMessage",
|
||||
"toolboxes.storageStatus.loadingMessage",
|
||||
"toolboxes.storageStatus.errorTitle",
|
||||
"toolboxes.storageStatus.errorMessage",
|
||||
|
|
|
|||
|
|
@ -15,20 +15,17 @@ function countLines(source) {
|
|||
return source.trimEnd().split("\n").length;
|
||||
}
|
||||
|
||||
test("toolbox storage, cards and pages are wired", async () => {
|
||||
const source = await readFile("website/src/main.jsx", "utf8");
|
||||
test("toolbox cards and pages retain their public UI conventions", async () => {
|
||||
const toolboxCard = await readFile("website/src/features/toolboxes/ToolboxCard.jsx", "utf8");
|
||||
const toolboxPages = await readFile("website/src/features/toolboxes/ToolboxPages.jsx", "utf8");
|
||||
const toolboxCoverEditor = await readFile("website/src/features/toolboxes/ToolboxCoverEditor.jsx", "utf8");
|
||||
const toolboxActions = await readFile("website/src/features/toolboxes/useToolboxActions.js", "utf8");
|
||||
const toolboxStorage = await readFile("website/src/features/toolboxes/storage/toolboxStorage.js", "utf8");
|
||||
const storageCompactorRegistry = await readFile("website/src/features/toolboxes/storage/modules/index.js", "utf8");
|
||||
const checklistStorage = await readFile("website/src/features/toolboxes/storage/modules/checklist.js", "utf8");
|
||||
const timerStorage = await readFile("website/src/features/toolboxes/storage/modules/timer.js", "utf8");
|
||||
const calendarStorage = await readFile("website/src/features/toolboxes/storage/modules/calendar.js", "utf8");
|
||||
const resetUtils = await readFile("website/src/features/toolboxes/modules/resetUtils.js", "utf8");
|
||||
const equipmentStorage = await readFile("website/src/features/toolboxes/storage/modules/equipmentPlanner.js", "utf8");
|
||||
const indexedToolboxesHook = await readFile("website/src/features/toolboxes/storage/useIndexedToolboxes.js", "utf8");
|
||||
const storageQuota = await readFile("website/src/components/StorageQuota.jsx", "utf8");
|
||||
const importButton = await readFile("website/src/components/ImportButton.jsx", "utf8");
|
||||
const guidedTooltipTour = await readFile("website/src/components/GuidedTooltipTour.jsx", "utf8");
|
||||
|
|
@ -36,25 +33,15 @@ test("toolbox storage, cards and pages are wired", async () => {
|
|||
const groupedReorderHook = await readFile("website/src/hooks/useGroupedReorder.js", "utf8");
|
||||
const draftFormHook = await readFile("website/src/hooks/useDraftForm.js", "utf8");
|
||||
|
||||
assert.match(`${indexedToolboxesHook}\n${toolboxPages}`, /indexedDbStorage\.js/);
|
||||
assert.match(source, /features\/toolboxes\/storage\/useIndexedToolboxes\.js/);
|
||||
assert.match(source, /features\/toolboxes\/useToolboxActions\.js/);
|
||||
assert.match(indexedToolboxesHook, /export function useIndexedToolboxes/);
|
||||
assert.match(indexedToolboxesHook, /getStorageEstimate/);
|
||||
assert.match(toolboxActions, /export function useToolboxActions/);
|
||||
assert.match(toolboxActions, /importAllToolboxesPayload/);
|
||||
assert.match(toolboxActions, /async function addImageFiles/);
|
||||
assert.match(toolboxActions, /creationTemplate/);
|
||||
assert.match(toolboxActions, /type: "memos"/);
|
||||
assert.match(toolboxActions, /type: "links"/);
|
||||
assert.match(toolboxActions, /#\/library/);
|
||||
assert.match(`${source}\n${toolboxActions}`, /features\/toolboxes\/storage\/toolboxStorage\.js/);
|
||||
assert.match(toolboxStorage, /TOOLBOX_ICON_FILES/);
|
||||
assert.match(toolboxStorage, /export function normalizeToolboxIcon/);
|
||||
assert.match(toolboxStorage, /export function normalizeToolboxCustomCover/);
|
||||
assert.match(toolboxStorage, /customCover: normalizeToolboxCustomCover/);
|
||||
assert.match(toolboxStorage, /compact\.customCover = normalized\.customCover/);
|
||||
assert.match(toolboxStorage, /export function createGlobalExportPayload/);
|
||||
assert.match(checklistStorage, /qtyTarget/);
|
||||
assert.match(checklistStorage, /qtyCurrent/);
|
||||
assert.match(checklistStorage, /hideCompletedSections/);
|
||||
|
|
@ -62,23 +49,6 @@ test("toolbox storage, cards and pages are wired", async () => {
|
|||
assert.match(checklistStorage, /hideWhenComplete/);
|
||||
assert.match(equipmentStorage, /collapsed/);
|
||||
assert.match(toolboxStorage, /module\.scrollable/);
|
||||
assert.match(toolboxStorage, /normalizeLinksData/);
|
||||
assert.match(toolboxStorage, /normalizeCountersData/);
|
||||
assert.match(toolboxStorage, /normalizeCombosData/);
|
||||
assert.match(toolboxStorage, /normalizeCalculatorData/);
|
||||
assert.match(toolboxStorage, /normalizeTableData/);
|
||||
assert.match(toolboxStorage, /normalizeTimerData/);
|
||||
assert.match(toolboxStorage, /normalizeCalendarData/);
|
||||
assert.match(toolboxStorage, /normalizeTaskPlannerData/);
|
||||
assert.match(toolboxStorage, /normalizeGoalTreeData/);
|
||||
assert.match(toolboxStorage, /normalizeEquipmentPlannerData/);
|
||||
assert.match(toolboxStorage, /summarizeEquipmentPlannerData/);
|
||||
assert.match(toolboxStorage, /normalizeImageAnnotationData/);
|
||||
assert.match(toolboxStorage, /export function compactModuleDataForStorage\(type, value\)/);
|
||||
assert.match(storageCompactorRegistry, /export const MODULE_DATA_COMPACTORS/);
|
||||
assert.match(storageCompactorRegistry, /timer: compactTimerDataForStorage/);
|
||||
assert.match(storageCompactorRegistry, /calendar: compactCalendarDataForStorage/);
|
||||
assert.match(storageCompactorRegistry, /goalTree: compactGoalTreeDataForStorage/);
|
||||
assert.match(timerStorage, /scrollResults/);
|
||||
assert.match(calendarStorage, /normalizeCalendarData/);
|
||||
assert.match(resetUtils, /export function getLatestDailyReset/);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue