Cold loads on versioned CDN deploys now show a consent card (editor MB + symbol/footprint lib figures, downloaded-now vs on-demand) and wait for OK before any big fetch; warm loads skip it and show truthful stages (loading from cache / Compiling / Starting KiCad) instead of the first-download line. - wasm-assets: resolveWasmMeta (bundle/ver/sizes), download-completion marker keyed by content-addressed bundle/ver, update wording, auto-download opt-out, HEAD size fallback - boot: manifest raw size as the progress total (fixes the br/gzip Content-Length mismatch), marker written after download+instantiate succeed - cdn-source: syncState() — IDB warmth peek + sizes.json cold sums - synced-source: syncState() from the backend envelope's sync refs (private platform); remote-source passes libSchema.sync through - publish-wasm: manifest schema 2 with per-bundle sizes (registry-persisted, reuse + snapshot modes); publish-libs: sizes.json sibling key + top-up mode - fixed 4 stale unit tests (bundle mapping, session-identity email) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011CC8aAnUUHcnHy3QCJtUwb
72 lines
2.2 KiB
TypeScript
72 lines
2.2 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import {
|
|
loadSessionIdentity,
|
|
resetSessionIdentityForTest,
|
|
sessionIdentity,
|
|
} from "./session-identity";
|
|
|
|
function mockMe(body: unknown, ok = true) {
|
|
return vi.spyOn(globalThis, "fetch").mockResolvedValue({
|
|
ok,
|
|
json: () => Promise.resolve(body),
|
|
} as Response);
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
resetSessionIdentityForTest();
|
|
});
|
|
|
|
describe("loadSessionIdentity", () => {
|
|
it("resolves the session user (name preferred, slug as id)", async () => {
|
|
const f = mockMe({ user: { slug: "alice", name: "Alice A", email: "a@x.y" } });
|
|
expect(await loadSessionIdentity("http://api")).toEqual({
|
|
slug: "alice",
|
|
name: "Alice A",
|
|
email: "a@x.y",
|
|
});
|
|
expect(sessionIdentity()).toEqual({
|
|
slug: "alice",
|
|
name: "Alice A",
|
|
email: "a@x.y",
|
|
});
|
|
expect(f).toHaveBeenCalledWith("http://api/api/me", {
|
|
credentials: "include",
|
|
});
|
|
});
|
|
|
|
it("falls back to email, then slug, for the display name", async () => {
|
|
mockMe({ user: { slug: "bob", name: "", email: "bob@x.y" } });
|
|
expect(await loadSessionIdentity("http://api")).toEqual({
|
|
slug: "bob",
|
|
name: "bob@x.y",
|
|
email: "bob@x.y",
|
|
});
|
|
});
|
|
|
|
it("is null for anonymous sessions ({user: null})", async () => {
|
|
mockMe({ user: null, authMode: "open" });
|
|
expect(await loadSessionIdentity("http://api")).toBeNull();
|
|
expect(sessionIdentity()).toBeNull();
|
|
});
|
|
|
|
it("is null when the endpoint is missing (example backend / demo)", async () => {
|
|
mockMe({ error: "not found" }, false);
|
|
expect(await loadSessionIdentity("http://api")).toBeNull();
|
|
});
|
|
|
|
it("is null on network failure and never throws", async () => {
|
|
vi.spyOn(globalThis, "fetch").mockRejectedValue(new Error("offline"));
|
|
expect(await loadSessionIdentity("http://api")).toBeNull();
|
|
});
|
|
|
|
it("fetches once — concurrent and later callers share the flight", async () => {
|
|
const f = mockMe({ user: { slug: "alice", name: "A", email: "" } });
|
|
await Promise.all([
|
|
loadSessionIdentity("http://api"),
|
|
loadSessionIdentity("http://api"),
|
|
]);
|
|
await loadSessionIdentity("http://api");
|
|
expect(f).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|