import { describe, expect, it } from "vitest"; import { FakeBrowserPermissionAdapter, FakeClientWorkflowAdapter, FakeFeatureFlagAdapter, FakeFileTransferAdapter, FakeGeneratedApiAdapter, FakeLargeDataUiAdapter, FakeMultiTabAdapter, FakeRealtimeAdapter, FakeServiceWorkerUpdateAdapter, FakeWorkerTaskAdapter, MemoryOfflineRepository, RecordingAnalyticsAdapter, createUnavailableAdapters, } from "../../recipes/frontend-capabilities/index.ts"; describe("optional capability recipes", () => { it("requires realtime cleanup and rejects duplicate or out-of-order events", async () => { const adapter = new FakeRealtimeAdapter<{ value: string }>(); const received: string[] = []; const subscription = await adapter.subscribe({ channel: "orders", onEvent(result) { received.push(result.ok ? result.value.payload.value : result.failure.code); }, }); expect(subscription.ok).toBe(true); adapter.emit("orders", { id: "event-2", sequence: 2, occurredAt: "2026-07-26T00:00:00.000Z", payload: { value: "new" }, }); adapter.emit("orders", { id: "event-1", sequence: 1, occurredAt: "2026-07-26T00:00:00.000Z", payload: { value: "old" }, }); expect(received).toEqual(["new", "STALE_RESULT"]); if (subscription.ok) subscription.value.unsubscribe(); expect(adapter.activeSubscriptionCount).toBe(0); }); it("models offline schema migration and closed-repository fallback", async () => { const repository = new MemoryOfflineRepository<{ id: string; name: string }>(); expect(await repository.open({ schemaVersion: 1 })).toEqual({ ok: true, value: undefined, }); await repository.put({ id: "one", name: "offline" }); expect(await repository.migrate({ from: 1, to: 2 })).toEqual({ ok: true, value: undefined, }); expect(await repository.get("one")).toEqual({ ok: true, value: { id: "one", name: "offline" }, }); repository.close(); expect((await repository.get("one")).ok).toBe(false); }); it("covers service-worker stale update and explicit unregister", async () => { const adapter = new FakeServiceWorkerUpdateAdapter("v1", "v2"); expect((await adapter.inspect()).ok).toBe(true); expect((await adapter.activate("stale")).ok).toBe(false); expect(await adapter.activate("v2")).toEqual({ ok: true, value: undefined }); expect(await adapter.unregister()).toEqual({ ok: true, value: undefined }); }); it("covers file validation, progress and AbortSignal cancellation", async () => { const adapter = new FakeFileTransferAdapter(10, new Set(["text/plain"])); const progress: number[] = []; const controller = new AbortController(); const uploaded = await adapter.upload({ file: { name: "safe.txt", size: 4, type: "text/plain", content: { byteLength: 4, chunks: (async function* () { yield new TextEncoder().encode("safe"); })(), }, }, signal: controller.signal, onProgress(value) { progress.push(value.transferredBytes); }, }); expect(uploaded.ok).toBe(true); expect(progress).toEqual([4]); controller.abort(); const cancelled = await adapter.download({ resourceId: "one", signal: controller.signal, onProgress() {}, }); expect(cancelled).toMatchObject({ ok: false, failure: { code: "ABORTED" }, }); }); it("keeps generated API and feature flag vendors behind typed facades", async () => { const api = new FakeGeneratedApiAdapter("2026-07", { list: () => [{ id: "one" }], }); expect( await api.execute>({ operationId: "list", contractVersion: "2026-07", }), ).toEqual({ ok: true, value: [{ id: "one" }] }); expect( ( await api.execute({ operationId: "list", contractVersion: "old", }) ).ok, ).toBe(false); const flags = new FakeFeatureFlagAdapter<{ checkout: boolean }>({ checkout: true, }); expect( await flags.evaluate({ key: "checkout", fallback: false, maxAgeMs: 1_000, }), ).toEqual({ ok: true, value: true }); }); it("discards cancelled worker results and de-duplicates multi-tab events", async () => { const worker = new FakeWorkerTaskAdapter((value) => value * 2); const controller = new AbortController(); worker.cancel("cancelled"); expect( ( await worker.run({ taskId: "cancelled", generation: 1, payload: 2, signal: controller.signal, }) ).ok, ).toBe(false); const tabs = new FakeMultiTabAdapter<{ refreshed: boolean }>(); const observed: string[] = []; const cleanup = tabs.subscribe({ sourceId: "tab-b", onEvent(result) { if (result.ok) observed.push(result.value.eventId); }, }); expect( tabs.publish({ eventId: "one", sourceId: "tab-a", version: 1, payload: { refreshed: true }, }).ok, ).toBe(true); expect( tabs.publish({ eventId: "one", sourceId: "tab-a", version: 1, payload: { refreshed: true }, }).ok, ).toBe(false); expect(observed).toEqual(["one"]); cleanup(); tabs.close(); }); it("separates browser permission, local workflow and large-data behavior", async () => { const permissions = new FakeBrowserPermissionAdapter({ notification: "denied", }); expect( await permissions.request({ capability: "notification" }), ).toEqual({ ok: true, value: "denied" }); expect( ( await permissions.request({ capability: "clipboard-read", }) ).ok, ).toBe(false); const workflow = new FakeClientWorkflowAdapter( { step: 0 }, (state, event: "next") => ({ step: event === "next" ? state.step + 1 : state.step, }), ); workflow.dispatch("next"); expect(workflow.snapshot()).toEqual({ step: 1 }); workflow.reset(); expect(workflow.snapshot()).toEqual({ step: 0 }); const data = new FakeLargeDataUiAdapter<{ id: string; name: string }>(); data.replace([{ id: "one", name: "row" }], 2); expect(data.window({ offset: 0, limit: 1, generation: 1 }).ok).toBe(false); expect(data.window({ offset: 0, limit: 1, generation: 2 })).toEqual({ ok: true, value: [{ id: "one", name: "row" }], }); }); it("enforces analytics consent, redaction and bounded queues", () => { const adapter = new RecordingAnalyticsAdapter(1); expect( adapter.record({ kind: "analytics", eventId: "page-viewed", consent: "denied", attributes: {}, }).ok, ).toBe(false); expect( adapter.record({ kind: "error", eventId: "render-failed", consent: "not-required", attributes: { routeId: "HOME", authToken: "must-not-survive" }, }).ok, ).toBe(true); expect(adapter.records[0]?.attributes).toEqual({ routeId: "HOME" }); expect( adapter.record({ kind: "error", eventId: "second", consent: "not-required", attributes: {}, }).ok, ).toBe(false); }); it("provides fail-closed unavailable adapters for every capability", async () => { const adapters = createUnavailableAdapters(); const controller = new AbortController(); const results = await Promise.all([ adapters.realtime.heartbeat(), adapters.offline.open({ schemaVersion: 1 }), adapters.serviceWorker.unregister(), adapters.fileTransfer.download({ resourceId: "one", signal: controller.signal, onProgress() {}, }), adapters.generatedApi.execute({ operationId: "one", contractVersion: "one", }), adapters.featureFlag.evaluate({ key: "one", fallback: false, maxAgeMs: 0, }), adapters.worker.run({ taskId: "one", generation: 1, payload: null, signal: controller.signal, }), adapters.browserPermission.request({ capability: "notification" }), adapters.analytics.flush(), ]); expect(results.every((result) => !result.ok)).toBe(true); expect(adapters.multiTab.publish({ eventId: "one", sourceId: "one", version: 1, payload: null, }).ok).toBe(false); expect(adapters.clientWorkflow.dispatch(null).ok).toBe(false); expect( adapters.largeDataUi.window({ offset: 0, limit: 1, generation: 1 }).ok, ).toBe(false); }); });