Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237import { describe, expect, it, vi } from "vitest";import { account, githubEnv, landingFrom, landingHref, open, seal } from "$lib/server/github";
const env = { ...githubEnv(), publicOrigin: "https://github.com", apiOrigin: "https://api.github.com"};
const publicRepo = (id: number) => ({ id, name: "pub", full_name: "ada/pub", visibility: "public", clone_url: "https://github.com/ada/pub.git", html_url: "https://github.com/ada/pub", default_branch: "main"});const privateRepo = (id: number) => ({ ...publicRepo(id), name: "priv", full_name: "ada/priv", visibility: "private", private: true, clone_url: "https://github.com/ada/priv.git", html_url: "https://github.com/ada/priv"});
const linked = (body: unknown, next?: string) => Response.json(body, next ? { headers: { link: `<${next}>; rel="next"` } } : undefined);
describe("github oauth boundaries", () => { it("rejects tampered sealed state", async () => { const value = await seal({ exp: Date.now() - 1 }, "test secret"); expect(await open(value, "test secret")).toEqual({ exp: expect.any(Number) }); expect(await open(value + "x", "test secret")).toBeNull(); }); it.each([ ["/repo/import/github", "/repo/import/github"], ["/repo/migrate", "/repo/migrate"], ["/repo/migrate?knot=at&github_error=denied", "/repo/migrate?knot=at"], ["/repo/new?import=github", "/repo/new?import=github"], ["/welcome?step=github", "/welcome?step=github"], ["https://evil.example/", "/?github_error=return_unexpected"], ["//evil.example/", "/?github_error=return_unexpected"], ["/\\evil.example", "/?github_error=return_unexpected"], ["/settings/emails", "/?github_error=return_unexpected"], [null, "/"] ])("lands %s at %s", (raw, expected) => { expect(landingHref(landingFrom(raw))).toBe(expected); });
it("carries a failure notice onto the page that asked", () => { expect(landingHref(landingFrom("/repo/migrate"), "denied")).toBe( "/repo/migrate?github_error=denied" ); });
it("authenticates every paginated repository request and follows the link cursor", async () => { const seen: { path: string; auth: string | null }[] = []; const fetcher = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { const u = new URL(String(input)); seen.push({ path: u.pathname, auth: new Headers(init?.headers).get("authorization") }); const second = u.searchParams.get("cursor") === "2"; if (u.pathname === "/user") return Response.json({ login: "ada", avatar_url: "https://avatars.githubusercontent.com/u/1" }); if (u.pathname === "/user/emails") return linked([{ primary: true, verified: true, email: "a@example.test" }]); if (u.pathname === "/user/keys") return linked([{ id: 1, key: "ssh-ed25519 AAA", title: "x" }]); if (u.pathname === "/users/ada/repos") { expect(u.searchParams.get("type")).toBe("owner"); return second ? linked([publicRepo(101)]) : linked( Array.from({ length: 100 }, (_, i) => publicRepo(i)), "https://api.github.com/users/ada/repos?type=owner&cursor=2" ); } if (u.pathname === "/user/installations") return linked({ installations: [{ id: 7 }] }); if (u.pathname === "/user/installations/7/repositories") return linked({ repositories: [publicRepo(101), privateRepo(102)] }); return linked([]); });
const result = await account(env, "secret", fetcher); expect(result).toMatchObject({ login: "ada", email: "a@example.test", keys: [{ id: 1 }] }); expect(result.repos).toContainEqual( expect.objectContaining({ id: 101, fullName: "ada/pub", private: false }) ); expect(result.repos).toContainEqual( expect.objectContaining({ id: 102, private: true, installationId: 7 }) ); expect(result.repos).toHaveLength(102); expect(seen.find((s) => s.path === "/users/ada/repos")?.auth).toBe("Bearer secret"); expect(seen.find((s) => s.path === "/user/installations")?.auth).toBe("Bearer secret"); expect(fetcher.mock.calls.some(([input]) => String(input).includes("cursor=2"))).toBe(true); });
it("refuses a link cursor that walks off the api origin", async () => { const fetcher = vi.fn(async (input: RequestInfo | URL) => { const u = new URL(String(input)); if (u.pathname === "/user") return Response.json({ login: "ada", avatar_url: "https://a" }); if (u.pathname === "/user/emails") return linked([], "https://evil.example/user/emails?page=2"); return linked([]); }); await expect(account(env, "secret", fetcher)).rejects.toThrow(/malformed/); expect(fetcher.mock.calls.some(([input]) => String(input).includes("evil.example"))).toBe( false ); });
it("still reports the account when nothing is installed", async () => { const fetcher = vi.fn(async (input: RequestInfo | URL) => { const u = new URL(String(input)); if (u.pathname === "/user") return Response.json({ login: "ada", avatar_url: "https://a" }); if (u.pathname === "/users/ada/repos") return linked([publicRepo(1)]); if (u.pathname === "/user/installations") return linked({ total_count: 0, installations: [] }); return linked([]); }); const result = await account(env, "secret", fetcher); expect(result.repos).toEqual([expect.objectContaining({ id: 1, private: false })]); expect(result.repos[0].installationId).toBeUndefined(); expect(result.emails).toEqual([]); });
it("carries the profile fields the welcome form can prefill", async () => { const fetcher = vi.fn(async (input: RequestInfo | URL) => { const u = new URL(String(input)); if (u.pathname === "/user") return Response.json({ login: "ada", avatar_url: "https://a", bio: "builds things", blog: "ada.example.test" }); if (u.pathname === "/user/installations") return linked({ total_count: 0, installations: [] }); return linked([]); }); const result = await account(env, "secret", fetcher); expect([result.bio, result.blog]).toEqual(["builds things", "ada.example.test"]); });
it("collects every email and skips malformed rows without throwing", async () => { const fetcher = vi.fn(async (input: RequestInfo | URL) => { const u = new URL(String(input)); if (u.pathname === "/user") return Response.json({ login: "ada", avatar_url: "https://a" }); if (u.pathname === "/user/emails") return linked([ { email: "a@example.test", primary: true, verified: true }, { email: 42, primary: true, verified: true }, { email: "b@example.test", verified: "yes", primary: false }, { primary: true, verified: true }, { email: "c@example.test" } ]); if (u.pathname === "/user/installations") return linked({ total_count: 0, installations: [] }); return linked([]); }); const result = await account(env, "secret", fetcher); expect(result.emails).toEqual([ { address: "a@example.test", primary: true, verified: true }, { address: "b@example.test", primary: false, verified: false }, { address: "c@example.test", primary: false, verified: false } ]); expect(result.email).toBe("a@example.test"); });});
describe("repo metadata", () => { const full = { ...publicRepo(1), language: "Rust", stargazers_count: 42, open_issues_count: 3, forks_count: 7, size: 21504, pushed_at: "2026-09-14T12:00:00Z" }; const accountOf = (owned: unknown[]) => { const fetcher = vi.fn(async (input: RequestInfo | URL) => { const u = new URL(String(input)); if (u.pathname === "/user") return Response.json({ login: "ada", avatar_url: "https://a" }); if (u.pathname === "/users/ada/repos") return linked(owned); if (u.pathname === "/user/installations") return linked({ total_count: 0, installations: [] }); return linked([]); }); return account(env, "secret", fetcher).then((a) => a.repos[0]); };
it("maps repo metadata through when present", async () => { expect(await accountOf([full])).toMatchObject({ language: "Rust", stars: 42, issues: 3, forks: 7, sizeKb: 21504, updatedAt: "2026-09-14T12:00:00Z" }); });
it("maps absent metadata to nulls without throwing", async () => { expect(await accountOf([publicRepo(1)])).toMatchObject({ language: null, stars: null, issues: null, forks: null, updatedAt: null, sizeKb: null }); });
it("nulls out wrong-typed metadata instead of throwing", async () => { expect(await accountOf([{ ...full, stargazers_count: "lots" }])).toMatchObject({ stars: null, language: "Rust" }); });
it("prefers pushed_at for updatedAt", async () => { expect(await accountOf([{ ...full, updated_at: "2026-09-10T00:00:00Z" }])).toMatchObject({ updatedAt: "2026-09-14T12:00:00Z" }); });});