/** * Autoplay API tests */ import { describe, it, expect, beforeEach, vi } from "vitest"; import { getAutoplaySettings, setAutoplaySettings, cancelAutoplayCountdown, playNextEpisode, type AutoplaySettings, } from "./autoplay"; import type { PlayItemRequest } from "./bindings"; vi.mock("@tauri-apps/api/core", () => ({ invoke: vi.fn(async (command: string, args?: any) => { if (command === "player_get_autoplay_settings") { return { enabled: true, countdownSeconds: 10, maxEpisodes: 5, }; } if (command === "player_set_autoplay_settings") { return args.settings; } if (command === "player_cancel_autoplay_countdown") { return undefined; } if (command === "player_play_next_episode") { return undefined; } return null; }), })); // setAutoplaySettings sources the user id from the auth store vi.mock("$lib/stores/auth", () => ({ auth: { getUserId: () => "user-1" }, })); // Minimal valid PlayItemRequest for playNextEpisode tests function makeItem(overrides: Partial = {}): PlayItemRequest { return { id: "item-123", title: "Episode 1", streamUrl: "http://example/stream", videoCodec: "h264", needsTranscoding: false, ...overrides, }; } describe("autoplay API", () => { beforeEach(() => { vi.clearAllMocks(); }); describe("getAutoplaySettings", () => { it("should fetch autoplay settings", async () => { const settings = await getAutoplaySettings(); expect(settings).toHaveProperty("enabled"); expect(settings).toHaveProperty("countdownSeconds"); expect(typeof settings.enabled).toBe("boolean"); expect(typeof settings.countdownSeconds).toBe("number"); }); it("should invoke correct backend command", async () => { const { invoke } = await import("@tauri-apps/api/core"); const invokeSpy = vi.mocked(invoke); await getAutoplaySettings(); expect(invokeSpy).toHaveBeenCalledWith("player_get_autoplay_settings"); }); }); describe("setAutoplaySettings", () => { it("should set autoplay settings with enabled true", async () => { const settings: AutoplaySettings = { enabled: true, countdownSeconds: 15, maxEpisodes: 5, }; const result = await setAutoplaySettings(settings); expect(result).toEqual(settings); }); it("should set autoplay settings with enabled false", async () => { const settings: AutoplaySettings = { enabled: false, countdownSeconds: 10, maxEpisodes: 5, }; const result = await setAutoplaySettings(settings); expect(result.enabled).toBe(false); }); it("should invoke correct backend command with settings", async () => { const { invoke } = await import("@tauri-apps/api/core"); const invokeSpy = vi.mocked(invoke); const settings: AutoplaySettings = { enabled: true, countdownSeconds: 20, maxEpisodes: 5, }; await setAutoplaySettings(settings); const call = invokeSpy.mock.calls.find((c) => c[0] === "player_set_autoplay_settings"); expect(call).toBeDefined(); expect(call![1]).toEqual({ userId: "user-1", settings }); }); it("should support different countdown values", async () => { const countdownValues = [5, 10, 15, 30]; for (const countdown of countdownValues) { const settings: AutoplaySettings = { enabled: true, countdownSeconds: countdown, maxEpisodes: 5, }; const result = await setAutoplaySettings(settings); expect(result.countdownSeconds).toBe(countdown); } }); }); describe("cancelAutoplayCountdown", () => { it("should cancel autoplay countdown", async () => { await cancelAutoplayCountdown(); const { invoke } = await import("@tauri-apps/api/core"); const invokeSpy = vi.mocked(invoke); expect(invokeSpy).toHaveBeenCalledWith("player_cancel_autoplay_countdown"); }); }); describe("playNextEpisode", () => { it("should play next episode with item", async () => { const mockItem = makeItem(); await playNextEpisode(mockItem); const { invoke } = await import("@tauri-apps/api/core"); const invokeSpy = vi.mocked(invoke); const call = invokeSpy.mock.calls.find((c) => c[0] === "player_play_next_episode"); expect(call).toBeDefined(); expect(call![1]).toEqual({ item: mockItem }); }); it("should handle different item types", async () => { const items = [ makeItem({ id: "1", title: "Episode 1" }), makeItem({ id: "2", title: "Episode 2" }), makeItem({ id: "3", title: "Episode 3" }), ]; for (const item of items) { await expect(playNextEpisode(item)).resolves.toBeUndefined(); } }); }); describe("autoplay settings structure", () => { it("should have enabled boolean property", async () => { const settings = await getAutoplaySettings(); expect(typeof settings.enabled).toBe("boolean"); }); it("should have countdownSeconds number property", async () => { const settings = await getAutoplaySettings(); expect(typeof settings.countdownSeconds).toBe("number"); expect(settings.countdownSeconds).toBeGreaterThan(0); }); }); });