Helpers flush and handlers commit — but every test request shared the test's session, so a follow-up GET or an assertion read the flushed write and the suite stayed green over a handler whose commit was missing (production's get_db closes the session: the write is rolled back behind a 200). The db fixture now hands out `db.info["request"]`: the same session, recording each request that ends normally with a flushed, uncommitted write, and failing the test on it at teardown. All 28 get_db overrides use it (a convention test keeps it so); the full suite passes under it, and dropping the commit from add_item turns a playlist test red.
46 lines
1.8 KiB
Python
46 lines
1.8 KiB
Python
"""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"
|