test(player): hold the session stop and the kept-point rule to the server

- The client's resume thresholds equal the server's (read from both sources).
- The session stop's URL matches the route the server serves it on.
- The player stops its server session by its item and its own id on an unload and on close,
  and keeps it when the page only goes into the back/forward cache.
This commit is contained in:
2026-10-07 23:16:38 +02:00
parent 392099770a
commit dd6a666ad1
5 changed files with 108 additions and 5 deletions
@@ -731,3 +731,38 @@ it("a session answer that lands while the next item's detail is still loading is
await tick();
expect(video().getAttribute("src")).not.toBe("/media/B");
});
describe("the server session the player no longer wants", () => {
const hlsA = { mode: "hls", url: "/hls/A/index.m3u8", start_s: 0, id: "sid-A" } as Awaited<
ReturnType<typeof api.plexSession>
>;
it("is stopped by its item and its own id when the page is unloaded", async () => {
const stop = vi.spyOn(api, "plexStopSession").mockImplementation(() => {});
mount({ details: { A: item("A") }, sessions: { A: () => Promise.resolve(hlsA) } });
await waitFor(() => expect(video()?.getAttribute("src")).toBe("/hls/A/index.m3u8"));
act(
() => void window.dispatchEvent(Object.assign(new Event("pagehide"), { persisted: false })),
);
expect(stop).toHaveBeenCalledWith("A", "sid-A");
});
it("is stopped the same way when the player closes", async () => {
const stop = vi.spyOn(api, "plexStopSession").mockImplementation(() => {});
const { unmount } = mount({
details: { A: item("A") },
sessions: { A: () => Promise.resolve(hlsA) },
});
await waitFor(() => expect(video()?.getAttribute("src")).toBe("/hls/A/index.m3u8"));
unmount();
expect(stop).toHaveBeenCalledWith("A", "sid-A");
});
it("is kept when the page only goes into the back/forward cache", async () => {
const stop = vi.spyOn(api, "plexStopSession").mockImplementation(() => {});
mount({ details: { A: item("A") }, sessions: { A: () => Promise.resolve(hlsA) } });
await waitFor(() => expect(video()?.getAttribute("src")).toBe("/hls/A/index.m3u8"));
act(() => void window.dispatchEvent(Object.assign(new Event("pagehide"), { persisted: true })));
expect(stop).not.toHaveBeenCalled();
});
});