import { test, expect } from "bun:test"; import { AccountStore, browserAccountStore, normalizeUsername, ACCOUNT_STORAGE_KEY, type AccountStorage, } from "../src/accounts"; // In-memory fake of the Storage subset — keeps this framework/DOM-agnostic. function fakeStorage(): AccountStorage & { map: Map } { const map = new Map(); return { map, getItem: (k) => (map.has(k) ? (map.get(k) as string) : null), setItem: (k, v) => void map.set(k, v), removeItem: (k) => void map.delete(k), }; } test("normalizeUsername: strips leading @, trims, lowercases", () => { expect(normalizeUsername("marie")).toBe("marie"); expect(normalizeUsername("@Marie")).toBe("marie"); expect(normalizeUsername(" @@MARIE ")).toBe("marie"); expect(normalizeUsername(null)).toBe(""); expect(normalizeUsername(undefined)).toBe(""); }); test("AccountStore: login persists a trimmed username, get reads it back", () => { const s = fakeStorage(); const store = new AccountStore(s); expect(store.get()).toBeNull(); expect(store.login(" Marie ")).toBe("Marie"); // trimmed, NOT normalized (display form) expect(store.get()).toBe("Marie"); expect(s.map.get(ACCOUNT_STORAGE_KEY)).toBe("Marie"); }); test("AccountStore: blank login is ignored, keeps the previous value", () => { const store = new AccountStore(fakeStorage()); store.login("bob"); expect(store.login(" ")).toBe("bob"); expect(store.get()).toBe("bob"); }); test("AccountStore: logout clears the username (no throw)", () => { const store = new AccountStore(fakeStorage()); store.login("bob"); store.logout(); expect(store.get()).toBeNull(); }); test("AccountStore: null storage degrades to non-persisting (SSR-safe)", () => { const store = new AccountStore(null); expect(store.get()).toBeNull(); expect(store.login("bob")).toBe("bob"); // returns the value, just doesn't persist expect(store.get()).toBeNull(); store.logout(); // no throw }); test("AccountStore: swallows storage errors on read and write", () => { const throwing: AccountStorage = { getItem: () => { throw new Error("boom"); }, setItem: () => { throw new Error("boom"); }, removeItem: () => { throw new Error("boom"); }, }; const store = new AccountStore(throwing); expect(store.get()).toBeNull(); // read error swallowed → null expect(() => store.login("bob")).not.toThrow(); expect(() => store.logout()).not.toThrow(); }); test("browserAccountStore returns a working store (uses global localStorage if present)", () => { const store = browserAccountStore("ng-eventually.test.account"); expect(store).toBeInstanceOf(AccountStore); // Behaves regardless of environment: login returns the value. expect(store.login("zoe")).toBe("zoe"); });