Refresh UI components and showcase; release updated framework packages
This commit is contained in:
1 parent
d800228585
commit
c77f5e1cec
293 files changed
+22544
-35778
No files matched your search
@@ -0,0 +1,40 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { generateServiceWorker } from "../src/index.ts";
|
||||
function worker(fetcher: (r:any)=>Promise<Response>, failStore = false) {
|
||||
const listeners: Record<string,Function> = {};
|
||||
const saved: string[] = [];
|
||||
const cache = {match:async()=>undefined,put:async(r:any)=>{if(failStore)throw Error("quota");saved.push(r.url)}};
|
||||
const self = {location:{origin:"https://account.example.test"},addEventListener:(name:string,fn:Function)=>listeners[name]=fn,skipWaiting(){},clients:{claim:async()=>{}}};
|
||||
new Function("self","caches","fetch",generateServiceWorker())(self,{open:async()=>cache,keys:async()=>[],delete:async()=>true},fetcher);
|
||||
return {saved, async fetch(path:string, mode="cors") {
|
||||
let result:Promise<Response>|undefined;
|
||||
const req = new Request(new URL(path,self.location.origin));
|
||||
Object.defineProperty(req,"mode",{value:mode});
|
||||
listeners.fetch({request:req,respondWith:(r:Promise<Response>)=>result=r,waitUntil:()=>{}});
|
||||
return result;
|
||||
}};
|
||||
}
|
||||
test("handoffs and API calls bypass service worker interception", async()=>{
|
||||
const w=worker(async()=>{throw Error("must not intercept")});
|
||||
expect(await w.fetch("/organization-add?sso_code=one-time")).toBeUndefined();
|
||||
expect(await w.fetch("/api/account")).toBeUndefined();
|
||||
});
|
||||
test("private responses and navigations never enter cache", async()=>{
|
||||
const w=worker(async()=>new Response("private",{headers:{"cache-control":"private, no-store"}}));
|
||||
expect(await (await w.fetch("/profile"))?.text()).toBe("private");
|
||||
expect(w.saved).toEqual([]);
|
||||
const nav=worker(async()=>new Response("personal page"));
|
||||
await nav.fetch("/profile","navigate"); expect(nav.saved).toEqual([]);
|
||||
});
|
||||
test("cache quota errors do not turn successful requests into network errors", async()=>{
|
||||
const w=worker(async()=>new Response("asset"),true);
|
||||
expect(await (await w.fetch("/app.js"))?.text()).toBe("asset");
|
||||
});
|
||||
test("offline without a cached fallback always returns a Response", async()=>{
|
||||
const w=worker(async()=>{throw Error("offline")});
|
||||
expect((await w.fetch("/profile","navigate"))?.status).toBe(503);
|
||||
});
|
||||
test("public static assets remain cacheable", async()=>{
|
||||
const w=worker(async()=>new Response("asset",{headers:{"cache-control":"public, max-age=3600"}}));
|
||||
await w.fetch("/app.js"); expect(w.saved).toHaveLength(1);
|
||||
});
|
||||
Reference in new issue
Block a user