commit 01a04be3a139e688076faa2a120b8354002b63c9
parent 907cfd4aa9b93d024c88d144bbfcc10e6f3860a2
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Fri, 25 Sep 2026 23:11:55 -0400
common: the service-worker routing test covers a non-ok and a failed online icon fetch, which leave the cached icon in place (brand S3)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/common/lib/archive/serviceWorkerRouting.test.ts b/common/lib/archive/serviceWorkerRouting.test.ts
@@ -20,8 +20,8 @@ const ORIGIN = "https://archive.example";
type FakeResponse = { body: string; ok: boolean; clone(): FakeResponse };
-function res(body: string): FakeResponse {
- return { body, ok: true, clone: () => res(body) };
+function res(body: string, ok = true): FakeResponse {
+ return { body, ok, clone: () => res(body, ok) };
}
// One worker, loaded fresh: returns a `request(path, {online})` that dispatches a
@@ -36,6 +36,7 @@ function loadWorker(file: string) {
};
let online = true;
let network = "";
+ let networkOk = true;
const fetched: string[] = [];
const keyOf = (r: string | { url: string }) =>
new URL(typeof r === "string" ? r : r.url, ORIGIN).href;
@@ -61,7 +62,7 @@ function loadWorker(file: string) {
fetch: async (r: { url: string }) => {
fetched.push(new URL(r.url).pathname);
if (!online) throw new TypeError("Failed to fetch");
- return res(network);
+ return res(network, networkOk);
},
Response: { error: () => ({ body: "<error>", ok: false }) },
URL,
@@ -77,9 +78,10 @@ function loadWorker(file: string) {
seed: (cacheName: string, p: string, body: string) =>
store(cacheName).set(new URL(p, ORIGIN).href, res(body)),
cached: (cacheName: string, p: string) => store(cacheName).get(new URL(p, ORIGIN).href)?.body,
- request: async (p: string, opts: { online: boolean; network?: string }) => {
+ request: async (p: string, opts: { online: boolean; network?: string; ok?: boolean }) => {
online = opts.online;
network = opts.network ?? "";
+ networkOk = opts.ok ?? true;
let served: Promise<FakeResponse> | undefined;
handlers.fetch({
request: { method: "GET", url: new URL(p, ORIGIN).href, mode: "no-cors", destination: "image" },
@@ -105,6 +107,28 @@ for (const file of ["export/service-worker/site-sw.js", "export/service-worker/s
assert.equal(await sw.request("/icons/icon.svg", { online: false }), "new mark");
});
+ test(`${file}: a non-ok online icon response is passed through and never replaces the cached icon`, async () => {
+ const sw = loadWorker(file);
+ sw.seed("shell-v2", "/icons/icon-192.png", "cached icon");
+ // A 404/503 mid-deploy reaches the page as it is, but is not stored…
+ assert.equal(
+ await sw.request("/icons/icon-192.png", { online: true, network: "<503>", ok: false }),
+ "<503>",
+ );
+ assert.deepEqual(sw.fetched, ["/icons/icon-192.png"]);
+ assert.equal(sw.cached("shell-v2", "/icons/icon-192.png"), "cached icon");
+ // …so the next offline launch still has the good icon.
+ assert.equal(await sw.request("/icons/icon-192.png", { online: false }), "cached icon");
+ });
+
+ test(`${file}: a failed online icon fetch falls back to the cached icon`, async () => {
+ const sw = loadWorker(file);
+ sw.seed("shell-v2", "/icons/icon.svg", "cached icon");
+ assert.equal(await sw.request("/icons/icon.svg", { online: false }), "cached icon");
+ assert.deepEqual(sw.fetched, ["/icons/icon.svg"]);
+ assert.equal(sw.cached("shell-v2", "/icons/icon.svg"), "cached icon");
+ });
+
test(`${file}: /_next/static/ stays cache-first`, async () => {
const sw = loadWorker(file);
sw.seed("shell-v2", "/_next/static/chunks/app.js", "cached chunk");