generated from nhcarrigan/template
test: expand frontend unit test coverage to 30%
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
/* eslint-disable @typescript-eslint/init-declarations -- Variables reassigned in beforeEach */
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user