import { describe, expect, it } from "@effect/vitest"; import * as Effect from "effect/Effect"; import { CONNECTION_CATALOG_KEY, LEGACY_CONNECTIONS_KEY, makeCatalogStore, type SecureCatalogStorage, } from "./catalog-store"; function makeStorage(initial: Readonly>) { const values = new Map(Object.entries(initial)); const deleted: Array = []; const storage: SecureCatalogStorage = { getItem: (key) => Effect.sync(() => values.get(key) ?? null), setItem: (key, value) => Effect.sync(() => { values.set(key, value); }), deleteItem: (key) => Effect.sync(() => { deleted.push(key); values.delete(key); }), }; return { deleted, storage, values }; } describe("mobile connection catalog storage", () => { it.effect("recovers from a corrupt current catalog", () => Effect.gen(function* () { const memory = makeStorage({ [CONNECTION_CATALOG_KEY]: "{not-json", }); const catalog = yield* makeCatalogStore(memory.storage); expect((yield* catalog.read).targets).toEqual([]); expect(memory.deleted).toEqual([CONNECTION_CATALOG_KEY]); }), ); it.effect("replaces and removes a corrupt legacy catalog", () => Effect.gen(function* () { const memory = makeStorage({ [LEGACY_CONNECTIONS_KEY]: JSON.stringify({ connections: [{ invalid: true }] }), }); const catalog = yield* makeCatalogStore(memory.storage); expect((yield* catalog.read).targets).toEqual([]); expect(memory.deleted).toEqual([LEGACY_CONNECTIONS_KEY]); expect(memory.values.has(CONNECTION_CATALOG_KEY)).toBe(true); }), ); it.effect("falls back to valid legacy data when the current catalog is corrupt", () => Effect.gen(function* () { const memory = makeStorage({ [CONNECTION_CATALOG_KEY]: "{not-json", [LEGACY_CONNECTIONS_KEY]: JSON.stringify({ connections: [ { environmentId: "legacy-environment", environmentLabel: "Legacy", pairingUrl: "https://legacy.example.test/pair", displayUrl: "https://legacy.example.test", httpBaseUrl: "https://legacy.example.test", wsBaseUrl: "wss://legacy.example.test", bearerToken: "legacy-token", authenticationMethod: "bearer", }, ], }), }); const catalog = yield* makeCatalogStore(memory.storage); expect((yield* catalog.read).targets).toHaveLength(1); expect(memory.deleted).toEqual([CONNECTION_CATALOG_KEY, LEGACY_CONNECTIONS_KEY]); yield* catalog.update((document) => document); expect(memory.values.has(CONNECTION_CATALOG_KEY)).toBe(true); expect(memory.values.has(LEGACY_CONNECTIONS_KEY)).toBe(false); }), ); });