sync-alerts.test.ts

2.5 KB · raw

1import { beforeEach, describe, expect, it } from "vitest";2import {3  clearPendingSyncAlerts,4  dismissPendingSyncAlerts,5  getPendingSyncAlerts,6  recordSyncAlerts,7} from "./sync-alerts";89function makeStorageStub() {10  const local = new Map<string, unknown>();11  (globalThis as unknown as { chrome: unknown }).chrome = {12    storage: {13      local: {14        async get(key?: string | string[] | null) {15          if (key == null) {16            const all: Record<string, unknown> = {};17            for (const [k, v] of local) all[k] = v;18            return all;19          }20          const keys = Array.isArray(key) ? key : [key];21          const out: Record<string, unknown> = {};22          for (const k of keys) if (local.has(k)) out[k] = local.get(k);23          return out;24        },25        async set(values: Record<string, unknown>) {26          for (const [k, v] of Object.entries(values)) local.set(k, v);27        },28        async remove(key: string | string[]) {29          for (const k of Array.isArray(key) ? key : [key]) local.delete(k);30        },31      },32    },33  };34}3536describe("sync alerts", () => {37  beforeEach(() => makeStorageStub());3839  it("records security alerts and caps oversized device names", async () => {40    await recordSyncAlerts([41      { type: "DEVICE_REVOKED", entryId: "", entryTitle: "", deviceName: "R".repeat(100), timestamp: 1 },42    ]);43    const [a] = await getPendingSyncAlerts();44    expect(a.deviceName).toBe("R".repeat(64));45  });4647  it("drops non-alert records", async () => {48    await recordSyncAlerts([49      { type: "ROUTINE_SYNC", entryId: "", entryTitle: "", deviceName: "x", timestamp: 1 } as never,50    ]);51    expect(await getPendingSyncAlerts()).toEqual([]);52  });5354  it("clear empties the queue", async () => {55    await recordSyncAlerts([56      { type: "DEVICE_KEY_ROTATED", entryId: "", entryTitle: "", deviceName: "k", timestamp: 1 },57    ]);58    await clearPendingSyncAlerts();59    expect(await getPendingSyncAlerts()).toEqual([]);60  });61  it("dismisses one alert group without losing another", async () => {62    await recordSyncAlerts([63      { type: "DEVICE_KEY_ROTATED", entryId: "", entryTitle: "", deviceName: "k", timestamp: 1 },64      { type: "DEVICE_REVOKED", entryId: "", entryTitle: "", deviceName: "r", timestamp: 2 },65    ]);66    await dismissPendingSyncAlerts("DEVICE_KEY_ROTATED");67    expect(await getPendingSyncAlerts()).toEqual([68      { type: "DEVICE_REVOKED", entryId: "", entryTitle: "", deviceName: "r", timestamp: 2 },69    ]);70  });71});