/** * Skip-to-next-episode reporting tests. * * Regression: pressing "skip to next episode" left the outgoing episode with a * mid-episode resume position, so it showed a partial progress bar and offered * to resume. A manual skip means the user is done with that episode — it must * be recorded as fully watched. * * TRACES: UR-059, UR-025 | DR-088 */ import { describe, it, expect, beforeEach, vi } from "vitest"; const markAsPlayed = vi.fn(async (_itemId: string) => undefined); const reportPlaybackStopped = vi.fn(async (_itemId: string, _positionSeconds: number) => undefined); vi.mock("./playbackReporting", () => ({ markAsPlayed: (itemId: string) => markAsPlayed(itemId), reportPlaybackStopped: (itemId: string, positionSeconds: number) => reportPlaybackStopped(itemId, positionSeconds), })); import { shouldSuppressStopReport, markSkipped, reportSkippedEpisode, resetSkipState, } from "./skipReporting"; describe("skip reporting", () => { beforeEach(() => { vi.clearAllMocks(); resetSkipState(); }); describe("reportSkippedEpisode", () => { it("marks the skipped episode as fully played", async () => { await reportSkippedEpisode("ep-1"); expect(markAsPlayed).toHaveBeenCalledWith("ep-1"); }); it("does not stamp the mid-episode position as a resume point", async () => { await reportSkippedEpisode("ep-1"); expect(reportPlaybackStopped).not.toHaveBeenCalled(); }); it("ignores a null item id", async () => { await reportSkippedEpisode(null); expect(markAsPlayed).not.toHaveBeenCalled(); }); }); describe("shouldSuppressStopReport", () => { it("suppresses the unmount stop report for the skipped episode", async () => { await reportSkippedEpisode("ep-1"); // VideoPlayer.onDestroy fires after navigation with the mid-episode time. expect(shouldSuppressStopReport("ep-1")).toBe(true); }); it("only suppresses the episode that was actually skipped", async () => { await reportSkippedEpisode("ep-1"); expect(shouldSuppressStopReport("ep-2")).toBe(false); }); it("suppresses only once, so a later real stop still reports", async () => { await reportSkippedEpisode("ep-1"); expect(shouldSuppressStopReport("ep-1")).toBe(true); expect(shouldSuppressStopReport("ep-1")).toBe(false); }); it("does not suppress when nothing was skipped", () => { expect(shouldSuppressStopReport("ep-1")).toBe(false); }); it("does not suppress a null item id", () => { markSkipped("ep-1"); expect(shouldSuppressStopReport(null)).toBe(false); }); }); });