Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

pwa.test.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

pwa.test.tsBlame114 lines · 1 contributor
eae38d1Claude1/**
44fe49bClaude2 * PWA route smoke tests — post-rip-out (2026-05-16).
eae38d1Claude3 *
44fe49bClaude4 * The PWA layer was removed because it produced recurring reload-loop
5 * bugs (admin dashboard, deploy pill, admin-screen flash). The routes
6 * still exist but serve self-unregister bodies so any browser with the
7 * old SW installed auto-recovers. The layout no longer registers a SW.
eae38d1Claude8 */
9
10import { describe, it, expect } from "bun:test";
11import app from "../app";
12import { MANIFEST, SERVICE_WORKER_SRC, PWA_REGISTER_SNIPPET } from "../routes/pwa";
13
44fe49bClaude14describe("pwa — manifest (kept for any pre-existing install)", () => {
eae38d1Claude15 it("GET /manifest.webmanifest → 200 JSON", async () => {
16 const res = await app.request("/manifest.webmanifest");
17 expect(res.status).toBe(200);
18 const ct = res.headers.get("content-type") || "";
19 expect(ct).toContain("application/manifest+json");
20 const body = await res.json();
21 expect(body.name).toBe("Gluecron");
22 expect(body.start_url).toBe("/");
23 expect(body.display).toBe("standalone");
24 expect(Array.isArray(body.icons)).toBe(true);
25 expect(body.icons.length).toBeGreaterThan(0);
26 });
27
28 it("MANIFEST constant has required install-prompt fields", () => {
29 expect(MANIFEST.name).toBeDefined();
30 expect(MANIFEST.short_name).toBeDefined();
31 expect(MANIFEST.start_url).toBeDefined();
32 expect(MANIFEST.icons.length).toBeGreaterThan(0);
33 expect(MANIFEST.display).toBe("standalone");
34 });
35});
36
44fe49bClaude37describe("pwa — service worker (self-unregister edition)", () => {
eae38d1Claude38 it("GET /sw.js → 200 JavaScript", async () => {
39 const res = await app.request("/sw.js");
40 expect(res.status).toBe(200);
41 expect(res.headers.get("content-type") || "").toContain(
42 "application/javascript"
43 );
44 expect(res.headers.get("service-worker-allowed")).toBe("/");
45 });
46
44fe49bClaude47 it("served SW body unregisters itself on activate", async () => {
48 const res = await app.request("/sw.js");
49 const body = await res.text();
50 expect(body).toContain("self.registration.unregister");
51 });
52
53 it("served SW body has no fetch handler", async () => {
54 const res = await app.request("/sw.js");
55 const body = await res.text();
56 expect(body).not.toContain('addEventListener("fetch"');
57 expect(body).not.toContain("addEventListener('fetch'");
58 });
59
60 it("locked SERVICE_WORKER_SRC constant kept for back-compat tests", () => {
eae38d1Claude61 expect(SERVICE_WORKER_SRC).toContain("addEventListener('install'");
62 expect(SERVICE_WORKER_SRC).toContain("addEventListener('activate'");
e1c7aa6Claude63 expect(SERVICE_WORKER_SRC).toContain("self.registration.unregister");
64 expect(SERVICE_WORKER_SRC).toContain("caches.delete");
eae38d1Claude65 });
66
44fe49bClaude67 it("locked SERVICE_WORKER_SRC has no fetch handler", () => {
e1c7aa6Claude68 expect(SERVICE_WORKER_SRC).not.toContain("addEventListener('fetch'");
eae38d1Claude69 });
70});
71
72describe("pwa — icon", () => {
73 it("GET /icon.svg → 200 SVG", async () => {
74 const res = await app.request("/icon.svg");
75 expect(res.status).toBe(200);
76 expect(res.headers.get("content-type") || "").toContain("image/svg+xml");
77 const body = await res.text();
78 expect(body).toContain("<svg");
79 expect(body).toContain("</svg>");
80 });
81});
82
44fe49bClaude83describe("pwa — register snippet (legacy, no longer used by layout)", () => {
84 it("snippet still references serviceWorker for legacy callers", () => {
eae38d1Claude85 expect(PWA_REGISTER_SNIPPET).toContain("serviceWorker");
86 expect(PWA_REGISTER_SNIPPET).toContain("'/sw.js'");
87 });
88});
89
44fe49bClaude90describe("pwa — layout no longer registers a service worker", () => {
91 // 2026-05-16 — PWA ripped out. The layout used to inject manifest +
92 // SW registration scripts; now it injects a kill-switch that
93 // unregisters any pre-existing SW. These tests pin the new contract.
74a8784Claude94 // 2026-06-10: asserted on /help — "/" now serves the self-contained
95 // Landing2030Page which carries no Layout scripts at all.
44fe49bClaude96 it("home page does NOT include the manifest link", async () => {
74a8784Claude97 const res = await app.request("/help");
eae38d1Claude98 const body = await res.text();
44fe49bClaude99 expect(body).not.toContain('rel="manifest"');
eae38d1Claude100 });
101
44fe49bClaude102 it("home page does NOT call serviceWorker.register", async () => {
74a8784Claude103 const res = await app.request("/help");
eae38d1Claude104 const body = await res.text();
44fe49bClaude105 expect(body).not.toContain("serviceWorker.register");
eae38d1Claude106 });
d7ba05dClaude107
44fe49bClaude108 it("home page includes the kill-switch (unregisters legacy SWs)", async () => {
74a8784Claude109 const res = await app.request("/help");
d7ba05dClaude110 const body = await res.text();
44fe49bClaude111 expect(body).toContain("getRegistrations");
112 expect(body).toContain("reg.unregister");
d7ba05dClaude113 });
eae38d1Claude114});