Files
ng-eventually/packages/client/test/accounts.test.ts
T
Sylvain Duchesne 88914f50ae refactor(layout): ranger les modules par destin à la migration
Les 25 modules étaient à plat, nommés d'après ce qu'ils font mécaniquement
(`store-registry`, `read-model`, `reach`, `caps`). Rien dans l'arborescence ne
disait lesquels DEVIENDRONT le vrai SDK, lesquels tiennent lieu du travail que
le verifier fera nativement, et lesquels n'existent que parce qu'un wallet est
partagé — trois destins sans rapport.

Quatre dossiers, les deux fichiers d'entrée restant à la racine pour que
l'`exports` du paquet et le code du consommateur ne bougent pas :

- `model/` — le modèle d'adressage de la cible, transcrit : vocabulaire pur,
  pas d'I/O. Survit comme connaissance.
- `surface/` — ce que l'app touche, chaque symbole ayant un pendant cible
  documenté. Supprimé quand l'alias bascule ; le code de l'app est inchangé.
- `emulated-verifier/` — les doublures de ce que le verifier fait nativement :
  possession, dépôt des caps, frontière, non-livraison, traitement des inbox,
  registres de branche, ouverture de repo. **C'est le dossier où diverger du
  modèle est possible.** Le préfixe `emulated-` porte le sens : tient lieu de,
  jamais est — cette bibliothèque ne réside dans aucune couche de la cible,
  elle les référence.
- `shared-wallet/` — n'existe que parce qu'un wallet héberge toutes les
  identités. Aucun pendant, rien sur quoi s'aligner ; sa seule loi est de
  rester invisible depuis `surface/`. S'évapore, remplacé par rien.

`store-registry-api.ts` devient `surface/placement.ts` : il faisait déjà à la
main ce que la frontière de dossier fait structurellement — c'est la meilleure
preuve interne du bien-fondé de ce rangement.

Ce commit ne fait que déplacer et recâbler les imports (src, test, e2e). Les
scissions des modules à cheval suivent.

157 tests unitaires, typecheck src/test/e2e vert.
2026-08-04 12:46:44 +02:00

76 lines
2.4 KiB
TypeScript

import { test, expect } from "bun:test";
import {
IdentityStore,
browserIdentityStore,
ACCOUNT_STORAGE_KEY,
type AccountStorage,
} from "../src/shared-wallet/accounts";
// In-memory fake of the Storage subset — keeps this framework/DOM-agnostic.
function fakeStorage(): AccountStorage & { map: Map<string, string> } {
const map = new Map<string, string>();
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("IdentityStore: set persists a trimmed id, get reads it back", () => {
const s = fakeStorage();
const store = new IdentityStore(s);
expect(store.get()).toBeNull();
expect(store.set(" marie ")).toBe("marie"); // trimmed
expect(store.get()).toBe("marie");
expect(s.map.get(ACCOUNT_STORAGE_KEY)).toBe("marie");
});
test("IdentityStore: a blank id is ignored, keeps the previous value", () => {
const store = new IdentityStore(fakeStorage());
store.set("bob");
expect(store.set(" ")).toBe("bob");
expect(store.get()).toBe("bob");
});
test("IdentityStore: clear removes the id (no throw)", () => {
const store = new IdentityStore(fakeStorage());
store.set("bob");
store.clear();
expect(store.get()).toBeNull();
});
test("IdentityStore: null storage degrades to non-persisting (SSR-safe)", () => {
const store = new IdentityStore(null);
expect(store.get()).toBeNull();
expect(store.set("bob")).toBe("bob"); // returns the value, just doesn't persist
expect(store.get()).toBeNull();
store.clear(); // no throw
});
test("IdentityStore: 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 IdentityStore(throwing);
expect(store.get()).toBeNull(); // read error swallowed → null
expect(() => store.set("bob")).not.toThrow();
expect(() => store.clear()).not.toThrow();
});
test("browserIdentityStore returns a working store (uses global localStorage if present)", () => {
const store = browserIdentityStore("ng-eventually.test.account");
expect(store).toBeInstanceOf(IdentityStore);
// Behaves regardless of environment: set returns the value.
expect(store.set("zoe")).toBe("zoe");
});