import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { writable } from "svelte/store"; const mockSetEnabled = vi.fn(); const mockSetGlobalVolume = vi.fn(); vi.mock("$lib/notifications", () => ({ soundPlayer: { setEnabled: mockSetEnabled, setGlobalVolume: mockSetGlobalVolume, }, })); // We need to control the config store's emitted values const configWritable = writable({ notifications_enabled: true, notification_volume: 0.7, }); vi.mock("./config", () => ({ configStore: { config: { subscribe: configWritable.subscribe }, }, })); describe("notifications sync store", () => { beforeEach(async () => { vi.resetModules(); mockSetEnabled.mockReset(); mockSetGlobalVolume.mockReset(); configWritable.set({ notifications_enabled: true, notification_volume: 0.7 }); }); afterEach(async () => { // Re-import to clean up any lingering subscriptions const { cleanupNotificationSync } = await import("./notifications"); cleanupNotificationSync(); }); describe("initNotificationSync", () => { it("syncs soundPlayer enabled state from config on init", async () => { const { initNotificationSync } = await import("./notifications"); initNotificationSync(); expect(mockSetEnabled).toHaveBeenCalledWith(true); }); it("syncs soundPlayer volume from config on init", async () => { const { initNotificationSync } = await import("./notifications"); initNotificationSync(); expect(mockSetGlobalVolume).toHaveBeenCalledWith(0.7); }); it("updates soundPlayer when config changes", async () => { const { initNotificationSync } = await import("./notifications"); initNotificationSync(); mockSetEnabled.mockReset(); mockSetGlobalVolume.mockReset(); configWritable.set({ notifications_enabled: false, notification_volume: 0.3 }); expect(mockSetEnabled).toHaveBeenCalledWith(false); expect(mockSetGlobalVolume).toHaveBeenCalledWith(0.3); }); it("does not register a duplicate subscription when called twice", async () => { const { initNotificationSync } = await import("./notifications"); initNotificationSync(); initNotificationSync(); // Both calls should only produce one subscription (one initial sync) expect(mockSetEnabled).toHaveBeenCalledTimes(1); }); }); describe("cleanupNotificationSync", () => { it("stops reacting to config changes after cleanup", async () => { const { initNotificationSync, cleanupNotificationSync } = await import("./notifications"); initNotificationSync(); cleanupNotificationSync(); mockSetEnabled.mockReset(); configWritable.set({ notifications_enabled: false, notification_volume: 0.5 }); expect(mockSetEnabled).not.toHaveBeenCalled(); }); it("is safe to call when not initialised", async () => { const { cleanupNotificationSync } = await import("./notifications"); expect(() => cleanupNotificationSync()).not.toThrow(); }); it("allows re-initialisation after cleanup", async () => { const { initNotificationSync, cleanupNotificationSync } = await import("./notifications"); initNotificationSync(); cleanupNotificationSync(); mockSetEnabled.mockReset(); initNotificationSync(); expect(mockSetEnabled).toHaveBeenCalledTimes(1); }); }); });