test(01-02): add red PWA cache isolation contracts

- exercise signed-in service-worker install at CacheStorage boundary
- require data-free offline navigation and immutable public assets
- require current and legacy session cache cleanup
This commit is contained in:
Marc-André Bombeck committed 2026-07-29 13:37:20 +02:00
1 parent 668f85a58d
commit 3a813b51bd
3 files changed
+113 -1

No files matched your search

@@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { QueryClient } from "@tanstack/react-query";
import {
clearOfflineCachesForSessionEnd,
clearPersistedQueryCache,
isPersistableKey,
restorePersistedQueryCache,
@@ -86,6 +87,51 @@ describe("persister degrades gracefully without IndexedDB", () => {
});
});
describe("session-end CacheStorage cleanup", () => {
const originalCaches = (globalThis as { caches?: CacheStorage }).caches;
afterEach(() => {
if (originalCaches === undefined) {
delete (globalThis as { caches?: CacheStorage }).caches;
} else {
(globalThis as { caches?: CacheStorage }).caches = originalCaches;
}
});
it("deletes current and legacy HealthLog static/page/data caches only", async () => {
const cacheNames = [
"healthlog-static-v1.34.0",
"healthlog-static-v1.15.20",
"healthlog-pages-v1.34.0",
"healthlog-pages-v1.15.20",
"healthlog-data-v1.34.0",
"healthlog-data-v1.15.20",
"unrelated-app-static-v7",
"workbox-precache-healthlog",
];
const deleted: string[] = [];
(globalThis as { caches?: CacheStorage }).caches = {
keys: async () => cacheNames,
delete: async (name: string) => {
deleted.push(name);
return true;
},
} as CacheStorage;
await clearOfflineCachesForSessionEnd();
expect
.soft(deleted.sort())
.toEqual(
cacheNames
.filter((name) => /^healthlog-(?:static|pages|data)-/.test(name))
.sort(),
);
expect(deleted).not.toContain("unrelated-app-static-v7");
expect(deleted).not.toContain("workbox-precache-healthlog");
});
});
describe("persister round-trips through a fake IndexedDB", () => {
const original = (globalThis as { indexedDB?: unknown }).indexedDB;