1import { beforeEach, describe, expect, it } from "vitest";2import {3 clearPendingSyncAlerts,4 getPendingSyncAlerts,5 recordSyncAlerts,6} from "./sync-alerts";78function makeStorageStub() {9 const local = new Map<string, unknown>();10 (globalThis as unknown as { chrome: unknown }).chrome = {11 storage: {12 local: {13 async get(key?: string | string[] | null) {14 if (key == null) {15 const all: Record<string, unknown> = {};16 for (const [k, v] of local) all[k] = v;17 return all;18 }19 const keys = Array.isArray(key) ? key : [key];20 const out: Record<string, unknown> = {};21 for (const k of keys) if (local.has(k)) out[k] = local.get(k);22 return out;23 },24 async set(values: Record<string, unknown>) {25 for (const [k, v] of Object.entries(values)) local.set(k, v);26 },27 async remove(key: string | string[]) {28 for (const k of Array.isArray(key) ? key : [key]) local.delete(k);29 },30 },31 },32 };33}3435describe("sync alerts", () => {36 beforeEach(() => makeStorageStub());3738 it("records security alerts and caps oversized device names", async () => {39 await recordSyncAlerts([40 { type: "DEVICE_REVOKED", entryId: "", entryTitle: "", deviceName: "R".repeat(100), timestamp: 1 },41 ]);42 const [a] = await getPendingSyncAlerts();43 expect(a.deviceName).toBe("R".repeat(64));44 });4546 it("drops non-alert records", async () => {47 await recordSyncAlerts([48 { type: "ROUTINE_SYNC", entryId: "", entryTitle: "", deviceName: "x", timestamp: 1 } as never,49 ]);50 expect(await getPendingSyncAlerts()).toEqual([]);51 });5253 it("clear empties the queue", async () => {54 await recordSyncAlerts([55 { type: "DEVICE_KEY_ROTATED", entryId: "", entryTitle: "", deviceName: "k", timestamp: 1 },56 ]);57 await clearPendingSyncAlerts();58 expect(await getPendingSyncAlerts()).toEqual([]);59 });60});