"""The subtitle routes must refuse a session the rest of the app refuses. They used to sit behind `_require_session`, the cookie-only gate the poster proxies use — a signed cookie was enough, with none of `current_user`'s checks (is_active, is_suspended, the session epoch that "log out everywhere" bumps). Fine for a poster; not for a route that starts reads of the media library. Found by the 2026-09 bug-hunt deep-review; the gate itself pre-dates that round. """ from fastapi.testclient import TestClient import app.auth as auth import app.state as app_state from app.db import get_db from app.main import app from app.plex import subtitles from app.routes.plex import playback class _NoPool: def __init__(self) -> None: self.jobs: list = [] def submit(self, fn, *args) -> None: self.jobs.append((fn, args)) def test_a_suspended_account_cannot_drive_the_subtitle_extractor( db, make_user, override_dep, monkeypatch, tmp_path ): user = make_user(is_suspended=True) override_dep(get_db, db.info["request"]) monkeypatch.setattr(app_state, "_configured_cache", True) # A validly SIGNED cookie for that account — which is all the old gate looked at. for mod in (auth, playback): monkeypatch.setattr(mod, "resolved_user_id", lambda request: (user.id, True)) monkeypatch.setattr(subtitles, "CACHE_DIR", tmp_path) pool = _NoPool() monkeypatch.setattr(subtitles, "_WIN_POOL", pool) monkeypatch.setattr(subtitles, "_FULL_POOL", pool) subtitles.reset_state() client = TestClient(app) assert client.get("/api/plex/subtitle/98614/0/status?at=600").status_code == 401 assert client.get("/api/plex/subtitle/98614/0").status_code == 401 assert pool.jobs == [], "a refused session still scheduled an extraction"