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.tsBlame95 lines · 1 contributor
eae38d1Claude1/**
2 * Block G1 — PWA route smoke tests.
3 *
4 * Verifies manifest/icon/service-worker endpoints serve the right content
5 * types + the manifest parses as JSON with the required install-prompt fields.
6 */
7
8import { describe, it, expect } from "bun:test";
9import app from "../app";
10import { MANIFEST, SERVICE_WORKER_SRC, PWA_REGISTER_SNIPPET } from "../routes/pwa";
11
12describe("pwa — manifest", () => {
13 it("GET /manifest.webmanifest → 200 JSON", async () => {
14 const res = await app.request("/manifest.webmanifest");
15 expect(res.status).toBe(200);
16 const ct = res.headers.get("content-type") || "";
17 expect(ct).toContain("application/manifest+json");
18 const body = await res.json();
19 expect(body.name).toBe("Gluecron");
20 expect(body.start_url).toBe("/");
21 expect(body.display).toBe("standalone");
22 expect(Array.isArray(body.icons)).toBe(true);
23 expect(body.icons.length).toBeGreaterThan(0);
24 });
25
26 it("MANIFEST constant has required install-prompt fields", () => {
27 expect(MANIFEST.name).toBeDefined();
28 expect(MANIFEST.short_name).toBeDefined();
29 expect(MANIFEST.start_url).toBeDefined();
30 expect(MANIFEST.icons.length).toBeGreaterThan(0);
31 expect(MANIFEST.display).toBe("standalone");
32 });
33});
34
35describe("pwa — service worker", () => {
36 it("GET /sw.js → 200 JavaScript", async () => {
37 const res = await app.request("/sw.js");
38 expect(res.status).toBe(200);
39 expect(res.headers.get("content-type") || "").toContain(
40 "application/javascript"
41 );
42 expect(res.headers.get("service-worker-allowed")).toBe("/");
43 });
44
45 it("service worker source contains install + fetch handlers", () => {
46 expect(SERVICE_WORKER_SRC).toContain("addEventListener('install'");
47 expect(SERVICE_WORKER_SRC).toContain("addEventListener('fetch'");
48 expect(SERVICE_WORKER_SRC).toContain("addEventListener('activate'");
49 });
50
51 it("service worker skips git + api + auth paths", () => {
52 expect(SERVICE_WORKER_SRC).toContain(".git/");
53 expect(SERVICE_WORKER_SRC).toContain("/api/");
54 expect(SERVICE_WORKER_SRC).toContain("/login");
55 });
56
57 it("service worker ignores non-GET requests", () => {
58 expect(SERVICE_WORKER_SRC).toContain("req.method !== 'GET'");
59 });
60});
61
62describe("pwa — icon", () => {
63 it("GET /icon.svg → 200 SVG", async () => {
64 const res = await app.request("/icon.svg");
65 expect(res.status).toBe(200);
66 expect(res.headers.get("content-type") || "").toContain("image/svg+xml");
67 const body = await res.text();
68 expect(body).toContain("<svg");
69 expect(body).toContain("</svg>");
70 });
71});
72
73describe("pwa — register snippet", () => {
74 it("registers a service worker when available", () => {
75 expect(PWA_REGISTER_SNIPPET).toContain("serviceWorker");
76 expect(PWA_REGISTER_SNIPPET).toContain("'/sw.js'");
77 });
78});
79
80describe("pwa — layout wiring", () => {
81 it("home page includes the manifest link", async () => {
82 const res = await app.request("/");
83 const body = await res.text();
84 expect(body).toContain('rel="manifest"');
85 expect(body).toContain("/manifest.webmanifest");
86 });
87
88 it("home page registers the service worker", async () => {
89 const res = await app.request("/");
90 const body = await res.text();
91 // JSX entity-escapes quotes inside <script>; just check the SW path is wired.
92 expect(body).toContain("serviceWorker.register");
93 expect(body).toContain("/sw.js");
94 });
95});