"""The playback-session route's mode routing. `POST /stream/{rk}/session` is the single switch that decides how an item plays: a browser-native file is served raw (`mode:"direct"`), everything else (re)starts an HLS session — and a `playable="transcode"` item (non-h264: HEVC/VP9/AV1/…) must take that HLS path with the video RE-ENCODED, not stream-copied. That routing replaced a former `HTTP 501`, and the only thing that tells `start_session` to re-encode is the `transcode=` flag this route derives from `it.playable`. The command-builder itself is unit-tested in `test_plex_stream.py`; here we pin the ROUTE decision (no ffmpeg spawned — `start_session` is stubbed to echo the flag it was handed). DB lane (`db` fixture) — skipped when no Postgres is reachable. """ from types import SimpleNamespace from fastapi.testclient import TestClient import app.state as state from app.auth import current_user from app.db import get_db from app.main import app from app.models import PlexItem, PlexLibrary, User from app.plex import paths as plex_paths from app.plex import stream as plex_stream def _item(db, *, playable, rating_key="m1"): lib = PlexLibrary(plex_key="1", title="Movies", kind="movie", enabled=True) db.add(lib) db.flush() it = PlexItem( rating_key=rating_key, library_id=lib.id, kind="movie", title="A Movie", file_path="/media/a.mkv", playable=playable, ) db.add(it) db.commit() return it def _user(db, email="play@example.com"): u = User(email=email) db.add(u) db.flush() return u def _post(db, user, monkeypatch, override_dep, rating_key, *, captured): """Drive the endpoint with ffmpeg stubbed out. `start_session` records the `transcode` flag it was called with into `captured` and returns a stand-in session echoing it back.""" monkeypatch.setattr(state, "_configured_cache", True) # pass the request gate monkeypatch.setattr(plex_stream, "reap_idle", lambda: None) monkeypatch.setattr(plex_paths, "local_media_path", lambda db_, fp: "/local/a.mkv") def fake_start(db_, it, user_id, start, audio, aoff, multi, transcode=False): captured["transcode"] = transcode return SimpleNamespace( id="sid", media_start_s=start, entry="index.m3u8", transcode=transcode, hw=False, tonemap=False, ) monkeypatch.setattr(plex_stream, "start_session", fake_start) override_dep(get_db, db.info["request"]) override_dep(current_user, lambda: user) return TestClient(app).post(f"/api/plex/stream/{rating_key}/session") def test_transcode_item_routes_to_an_hls_reencode_session(db, monkeypatch, override_dep): # A non-h264 item (formerly HTTP 501) now plays: mode=hls, transcode=True threaded to start_session. it = _item(db, playable="transcode") user = _user(db) captured: dict = {} resp = _post(db, user, monkeypatch, override_dep, it.rating_key, captured=captured) assert resp.status_code == 200, resp.text body = resp.json() assert body["mode"] == "hls" assert body["transcode"] is True assert captured["transcode"] is True # start_session was told to re-encode def test_remux_item_stays_a_stream_copy_session(db, monkeypatch, override_dep): # A remux (h264) item takes the SAME HLS path but must NOT re-encode. it = _item(db, playable="remux", rating_key="m2") user = _user(db, "remux@example.com") captured: dict = {} resp = _post(db, user, monkeypatch, override_dep, it.rating_key, captured=captured) assert resp.status_code == 200, resp.text body = resp.json() assert body["mode"] == "hls" assert body["transcode"] is False assert captured["transcode"] is False # The id the player names when it stops the session (POST …/session/{id}/stop). assert body["id"] == "sid" def test_direct_item_never_opens_a_session(db, monkeypatch, override_dep): # A browser-native file is served raw — start_session is never reached, so no transcode decision. it = _item(db, playable="direct", rating_key="m3") user = _user(db, "direct@example.com") captured: dict = {} resp = _post(db, user, monkeypatch, override_dep, it.rating_key, captured=captured) assert resp.status_code == 200, resp.text assert resp.json()["mode"] == "direct" assert "transcode" not in captured # start_session not called