79 lines
2.6 KiB
JavaScript
79 lines
2.6 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { createBrowserStorageAdapter } from "../../src/adapters/storage/browser-storage-adapter.js";
|
|
import {
|
|
STORAGE_REGISTRY,
|
|
buildPhysicalKey,
|
|
defineStorageKey,
|
|
} from "../../src/contracts/storage-keys.js";
|
|
|
|
function createStorage({ quota = false } = {}) {
|
|
const values = new Map();
|
|
return {
|
|
getItem: (key) => values.get(key) ?? null,
|
|
setItem: (key, value) => {
|
|
if (quota) throw new DOMException("full", "QuotaExceededError");
|
|
values.set(key, value);
|
|
},
|
|
removeItem: (key) => values.delete(key),
|
|
clear: () => values.clear(),
|
|
key: () => null,
|
|
get length() {
|
|
return values.size;
|
|
},
|
|
};
|
|
}
|
|
|
|
describe("storage registry", () => {
|
|
it("builds namespace and schema-versioned physical keys", () => {
|
|
expect(buildPhysicalKey("preference", 2, "theme")).toBe(
|
|
"ca-frontend:preference:v2:theme",
|
|
);
|
|
expect(STORAGE_REGISTRY.COLOR_SCHEME.physicalKey).toContain(":v1:");
|
|
});
|
|
|
|
it("rejects token or secret persistence registrations", () => {
|
|
expect(() =>
|
|
defineStorageKey({
|
|
logicalName: "TOKEN",
|
|
scope: "auth",
|
|
name: "token",
|
|
backend: "localStorage",
|
|
classification: "sensitive-forbidden",
|
|
schemaVersion: 1,
|
|
ttl: null,
|
|
migration: "discard",
|
|
quotaFallback: "feature-disable",
|
|
}),
|
|
).toThrow("Sensitive client storage registration is forbidden");
|
|
});
|
|
|
|
it("round-trips public preferences through the adapter", () => {
|
|
const localStorage = createStorage();
|
|
const adapter = createBrowserStorageAdapter({ localStorage });
|
|
expect(adapter.write("COLOR_SCHEME", "dark")).toEqual({ ok: true });
|
|
expect(adapter.read("COLOR_SCHEME")).toEqual({ ok: true, value: "dark" });
|
|
});
|
|
|
|
it("falls back to memory when preference storage quota is exceeded", () => {
|
|
const localStorage = createStorage({ quota: true });
|
|
const adapter = createBrowserStorageAdapter({ localStorage });
|
|
expect(adapter.write("COLOR_SCHEME", "dark")).toMatchObject({
|
|
ok: false,
|
|
fallback: "memory",
|
|
error: { kind: "STORAGE_QUOTA_EXCEEDED" },
|
|
});
|
|
expect(adapter.read("COLOR_SCHEME")).toEqual({ ok: true, value: "dark" });
|
|
});
|
|
|
|
it("discards data from a previous schema version", () => {
|
|
const localStorage = createStorage();
|
|
localStorage.setItem(
|
|
STORAGE_REGISTRY.COLOR_SCHEME.physicalKey,
|
|
JSON.stringify({ schemaVersion: 0, value: "dark" }),
|
|
);
|
|
const adapter = createBrowserStorageAdapter({ localStorage });
|
|
expect(adapter.read("COLOR_SCHEME")).toEqual({ ok: true, value: undefined });
|
|
});
|
|
});
|