The stop-URL contract passed with the two ids swapped and read the backend from the working directory; nothing called a real beacon's onSettled or its library pass-through; the kept-point rule was held by its constants only.
36 lines
1.8 KiB
TypeScript
36 lines
1.8 KiB
TypeScript
// @vitest-environment jsdom
|
|
import { readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import { afterEach, expect, it, vi } from "vitest";
|
|
import { api } from "../api";
|
|
|
|
// The session stop is a keepalive beacon: nothing answers it on screen, so a URL that no longer
|
|
// matches the server's route fails silently — every transcode the player leaves runs on until the
|
|
// idle reaper. The route is read from the server's source, as the other contract tests do.
|
|
afterEach(() => vi.restoreAllMocks());
|
|
|
|
function serverRoute(): RegExp {
|
|
// Anchored to this file, not the working directory, so the test holds wherever vitest starts.
|
|
const source = readFileSync(
|
|
resolve(__dirname, "../../../../backend/app/routes/plex/playback.py"),
|
|
"utf8",
|
|
);
|
|
const prefix = /APIRouter\(prefix="([^"]+)"/.exec(source)?.[1];
|
|
const path = /@router\.post\("(\/stream\/[^"]*\/stop)"\)/.exec(source)?.[1];
|
|
// If either is missing the route was renamed or moved — re-point this test, the rule stands.
|
|
expect(prefix, "router prefix").toBeDefined();
|
|
expect(path, "the session stop route").toBeDefined();
|
|
// Each path parameter becomes a group of its own NAME: two ids that swapped places still match a
|
|
// pattern of anonymous wildcards, and the server then finds no session to stop.
|
|
const pattern = (prefix! + path!).replace(/\{(\w+)\}/g, "(?<$1>[^/]+)");
|
|
return new RegExp(`^${pattern}$`);
|
|
}
|
|
|
|
it("sends the session stop to the route the server serves it on", () => {
|
|
const fetch = vi.spyOn(globalThis, "fetch").mockResolvedValue(new Response(null));
|
|
api.plexStopSession("12345", "a1b2c3");
|
|
const url = String(fetch.mock.calls[0]![0]);
|
|
expect(url.match(serverRoute())?.groups).toEqual({ rating_key: "12345", session_id: "a1b2c3" });
|
|
expect(fetch.mock.calls[0]![1]).toMatchObject({ method: "POST", keepalive: true });
|
|
});
|