1import { beforeEach, describe, expect, it, vi } from "vitest";23type StorageShape = Record<string, unknown>;45describe("background clipboard", () => {6 let storage: StorageShape;7 let clipboardWriteText: ReturnType<typeof vi.fn>;89 beforeEach(async () => {10 vi.resetModules();11 vi.useFakeTimers();12 storage = {};13 clipboardWriteText = vi.fn(async () => undefined);1415 const chromeMock = {16 tabs: {17 query: vi.fn(async () => []),18 },19 scripting: {20 executeScript: vi.fn(async () => []),21 },22 alarms: {23 clear: vi.fn(),24 create: vi.fn(),25 onAlarm: { addListener: vi.fn() },26 },27 idle: {28 setDetectionInterval: vi.fn(),29 onStateChanged: { addListener: vi.fn() },30 },31 storage: {32 local: {33 get: vi.fn(async (key?: string | string[]) => {34 if (!key) return storage;35 if (typeof key === "string") {36 return { [key]: storage[key] };37 }3839 return key.reduce<Record<string, unknown>>((result, entry) => {40 result[entry] = storage[entry];41 return result;42 }, {});43 }),44 set: vi.fn(async (next: Record<string, unknown>) => {45 Object.assign(storage, next);46 }),47 remove: vi.fn(async () => undefined),48 },49 },50 } as unknown as typeof chrome;5152 (globalThis as { chrome?: typeof chrome }).chrome = chromeMock;53 vi.stubGlobal("navigator", {54 clipboard: {55 writeText: clipboardWriteText,56 },57 });5859 const vault = await import("./vault");60 await vault.ensureSettingsLoaded();61 });6263 it("copyToClipboard writes text to the clipboard", async () => {64 const { copyToClipboard } = await import("./clipboard");6566 await copyToClipboard("secret", "Password");6768 expect(clipboardWriteText).toHaveBeenCalledWith("secret");69 });7071 it("copyToClipboard clears the clipboard after clipboardClearSeconds", async () => {72 const vault = await import("./vault");73 const { copyToClipboard } = await import("./clipboard");7475 await vault.updateSettings({ clipboardClearSeconds: 1 });76 await copyToClipboard("secret", "Password");7778 await vi.advanceTimersByTimeAsync(1000);7980 expect(clipboardWriteText).toHaveBeenNthCalledWith(2, "");81 });8283 it("copyToClipboard respects custom clipboardClearSeconds", async () => {84 const vault = await import("./vault");85 const { copyToClipboard } = await import("./clipboard");8687 await vault.updateSettings({ clipboardClearSeconds: 10 });88 await copyToClipboard("secret", "Password");8990 await vi.advanceTimersByTimeAsync(9999);91 expect(clipboardWriteText).toHaveBeenCalledTimes(1);9293 await vi.advanceTimersByTimeAsync(2);94 expect(clipboardWriteText).toHaveBeenNthCalledWith(2, "");95 });9697 it("copyToClipboard defaults to 30 seconds when clipboardClearSeconds is absent", async () => {98 const { copyToClipboard } = await import("./clipboard");99100 await copyToClipboard("secret", "Password");101102 await vi.advanceTimersByTimeAsync(29999);103 expect(clipboardWriteText).toHaveBeenCalledTimes(1);104105 await vi.advanceTimersByTimeAsync(2);106 expect(clipboardWriteText).toHaveBeenNthCalledWith(2, "");107 });108});