1import { describe, it, expect, beforeEach, vi } from "vitest";23const store: Record<string, unknown> = {};45vi.stubGlobal("chrome", {6 storage: {7 local: {8 get: vi.fn(async (key: string) => ({ [key]: store[key] })),9 set: vi.fn(async (entries: Record<string, unknown>) => {10 Object.assign(store, entries);11 }),12 },13 },14});1516const { claimProNudge, snoozeProNudge, silenceProNudge } = await import("./pro-nudge");1718const DAY = 24 * 60 * 60 * 1000;19const T0 = 1_800_000_000_000;2021describe("pro-nudge", () => {22 beforeEach(() => {23 Object.keys(store).forEach((k) => delete store[k]);24 });2526 it("does not show on first sight, only after a grace period", async () => {27 expect(await claimProNudge(T0)).toBe(false);28 expect(await claimProNudge(T0 + 13 * DAY)).toBe(false);29 expect(await claimProNudge(T0 + 14 * DAY)).toBe(true);30 });3132 it("shows at most once per cadence window even if never dismissed", async () => {33 await claimProNudge(T0);34 expect(await claimProNudge(T0 + 14 * DAY)).toBe(true);35 expect(await claimProNudge(T0 + 15 * DAY)).toBe(false);36 expect(await claimProNudge(T0 + 44 * DAY)).toBe(true);37 });3839 it("stays hidden for 90 days after snoozing", async () => {40 await claimProNudge(T0);41 await claimProNudge(T0 + 14 * DAY);42 await snoozeProNudge(T0 + 14 * DAY);43 expect(await claimProNudge(T0 + 103 * DAY)).toBe(false);44 expect(await claimProNudge(T0 + 104 * DAY)).toBe(true);45 });4647 it("never shows again after silencing", async () => {48 await claimProNudge(T0);49 await silenceProNudge();50 expect(await claimProNudge(T0 + 10_000 * DAY)).toBe(false);51 });5253 it("treats unreadable storage as not due", async () => {54 vi.mocked(chrome.storage.local.get).mockRejectedValueOnce(new Error("unavailable"));55 expect(await claimProNudge(T0 + 1_000 * DAY)).toBe(false);56 });57});