clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

main
lofi / package / recipes / scope-extension_test.ts
scope-extension_test.ts 2.3K
1import {2 createScopeExtension,3 createWebAppOriginAssociation,4 verifyWebAppOriginAssociation,5} from "./scope-extension.ts";67function assert(condition: unknown, message: string): asserts condition {8 if (!condition) throw new Error(message);9}1011Deno.test("scope extension helpers produce reciprocal deployment values", () => {12 const declaration = createScopeExtension("https://help.example.com");13 assert(declaration.origin === "https://help.example.com", "origin changed");14 const association = createWebAppOriginAssociation({15 manifestId: "https://app.example.com/products/notes",16 scope: "/notes/",17 });18 assert(19 association["https://app.example.com/products/notes"]?.scope === "/notes/",20 "association did not use the exact manifest ID",21 );22 assert(23 verifyWebAppOriginAssociation(association, {24 manifestId: "https://app.example.com/products/notes",25 scope: "/notes/",26 }),27 "generated association failed verification",28 );29});3031Deno.test("association verification fails closed for partial or unexpected values", () => {32 const expected = { manifestId: "https://app.example.com/app", scope: "/help/" };33 for (34 const value of [35 null,36 {},37 { "https://app.example.com/": { scope: "/help/" } },38 { [expected.manifestId]: { scope: "/other/" } },39 { [expected.manifestId]: { scope: "/help/", authorization: true } },40 ]41 ) {42 assert(!verifyWebAppOriginAssociation(value, expected), "invalid association passed");43 }44});4546Deno.test("scope extension helpers reject unsafe URLs and paths", () => {47 for (48 const run of [49 () => createScopeExtension("http://help.example.com"),50 () => createScopeExtension("https://help.example.com/path"),51 () => createScopeExtension("https://user:secret@help.example.com"),52 () =>53 createWebAppOriginAssociation({54 manifestId: "https://app.example.com/app?version=1",55 scope: "/help/",56 }),57 () =>58 createWebAppOriginAssociation({59 manifestId: "https://app.example.com/app",60 scope: "/help/../private/",61 }),62 ]63 ) {64 let rejected = false;65 try {66 run();67 } catch (error) {68 rejected = error instanceof TypeError;69 }70 assert(rejected, "unsafe scope extension input passed");71 }72});