22 test files set `app.dependency_overrides[...]` by hand and tore down with a blanket `.clear()` in a `finally`, which wipes every override rather than the test's own and stops fixtures composing. They now take the `override_dep` fixture (helpers get it passed in), whose teardown restores each key's prior value; no clear() carried meaning between two phases of a test. A convention test fails any test file that writes `dependency_overrides` directly.
150 lines
5.8 KiB
Python
150 lines
5.8 KiB
Python
"""E5 S6: HU-overlay language serving. When ?lang=hu, the unified library, facets, genre filter and
|
|
detail endpoints serve the Hungarian `*_hu` columns (falling back to EN where a row has no HU twin);
|
|
?lang=en (the default) serves English. Also covers the imdb_rating IMDb-only / audience-score split.
|
|
DB lane (`db` fixture) — skipped without Postgres.
|
|
"""
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
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
|
|
|
|
|
|
def _seed(db):
|
|
"""One EN movie library with a single movie that has both EN and HU metadata, plus a second movie
|
|
that is EN-only (no HU twin) to prove the coalesce fallback."""
|
|
lib = PlexLibrary(plex_key="1", title="Movies", kind="movie", enabled=True)
|
|
db.add(lib)
|
|
db.flush()
|
|
m1 = PlexItem(
|
|
rating_key="m1",
|
|
library_id=lib.id,
|
|
kind="movie",
|
|
title="English Title",
|
|
title_hu="Magyar Cím",
|
|
summary="English summary.",
|
|
summary_hu="Magyar összefoglaló.",
|
|
genres=["Drama"],
|
|
genres_hu=["Dráma"],
|
|
rating=6.5,
|
|
imdb_rating=None,
|
|
year=2001,
|
|
added_at=datetime(2024, 1, 1, tzinfo=timezone.utc),
|
|
people_enriched_at=datetime(
|
|
2024, 1, 1, tzinfo=timezone.utc
|
|
), # serve from row, skip live enrich
|
|
)
|
|
m2 = PlexItem(
|
|
rating_key="m2",
|
|
library_id=lib.id,
|
|
kind="movie",
|
|
title="EN Only",
|
|
genres=["Comedy"], # no HU twin
|
|
year=2002,
|
|
added_at=datetime(2024, 1, 2, tzinfo=timezone.utc),
|
|
people_enriched_at=datetime(2024, 1, 2, tzinfo=timezone.utc),
|
|
)
|
|
db.add_all([m1, m2])
|
|
user = User(email="plexlang@example.com")
|
|
db.add(user)
|
|
db.commit()
|
|
return user
|
|
|
|
|
|
def _get(db, user, monkeypatch, override_dep, path):
|
|
monkeypatch.setattr(
|
|
state, "_configured_cache", True
|
|
) # the request gate 503s an unconfigured app
|
|
override_dep(get_db, lambda: db)
|
|
override_dep(current_user, lambda: user)
|
|
client = TestClient(app) # no context manager: skip lifespan
|
|
return client.get(path)
|
|
|
|
|
|
def _titles(resp):
|
|
return {i["title"] for i in resp.json()["items"]}
|
|
|
|
|
|
def test_library_serves_active_language_titles(db, monkeypatch, override_dep):
|
|
user = _seed(db)
|
|
hu = _get(db, user, monkeypatch, override_dep, "/api/plex/library?scope=movie&lang=hu")
|
|
en = _get(db, user, monkeypatch, override_dep, "/api/plex/library?scope=movie&lang=en")
|
|
# HU serves the twin's Hungarian title; the EN-only row falls back to its English title.
|
|
assert _titles(hu) == {"Magyar Cím", "EN Only"}
|
|
assert _titles(en) == {"English Title", "EN Only"}
|
|
|
|
|
|
def test_facets_vocabulary_is_language_specific(db, monkeypatch, override_dep):
|
|
user = _seed(db)
|
|
hu = _get(db, user, monkeypatch, override_dep, "/api/plex/facets?scope=movie&lang=hu")
|
|
en = _get(db, user, monkeypatch, override_dep, "/api/plex/facets?scope=movie&lang=en")
|
|
hu_genres = {g["value"] for g in hu.json()["genres"]}
|
|
en_genres = {g["value"] for g in en.json()["genres"]}
|
|
assert "Dráma" in hu_genres and "Drama" not in hu_genres
|
|
assert "Drama" in en_genres and "Dráma" not in en_genres
|
|
|
|
|
|
def test_genre_filter_matches_active_language_vocabulary(db, monkeypatch, override_dep):
|
|
user = _seed(db)
|
|
# The HU genre chip filters the HU column; the same string against the EN column matches nothing.
|
|
hit = _get(
|
|
db, user, monkeypatch, override_dep, "/api/plex/library?scope=movie&lang=hu&genres=Dráma"
|
|
)
|
|
miss = _get(
|
|
db, user, monkeypatch, override_dep, "/api/plex/library?scope=movie&lang=en&genres=Dráma"
|
|
)
|
|
assert _titles(hit) == {"Magyar Cím"}
|
|
assert miss.json()["items"] == []
|
|
|
|
|
|
def test_item_detail_language_and_rating_split(db, monkeypatch, override_dep):
|
|
user = _seed(db)
|
|
resp = _get(db, user, monkeypatch, override_dep, "/api/plex/item/m1?lang=hu")
|
|
body = resp.json()
|
|
assert body["title"] == "Magyar Cím"
|
|
assert body["summary"] == "Magyar összefoglaló."
|
|
# imdb_rating is IMDb-only (None here); the audience score is served separately as `rating`.
|
|
assert body["imdb_rating"] is None
|
|
assert body["rating"] == 6.5
|
|
|
|
|
|
def test_hu_search_still_finds_en_only_titles(db, monkeypatch, override_dep):
|
|
user = _seed(db)
|
|
# m2 ("EN Only") has no HU twin, so search_vector_hu carries no title tokens for it. HU-mode search
|
|
# must still match it via the EN vector (vector_match's union) — findable by its English title.
|
|
resp = _get(db, user, monkeypatch, override_dep, "/api/plex/library?scope=movie&lang=hu&q=Only")
|
|
assert "EN Only" in _titles(resp)
|
|
|
|
|
|
def test_rating_filter_prefers_imdb_over_audience(db, monkeypatch, override_dep):
|
|
lib = PlexLibrary(plex_key="1", title="Movies", kind="movie", enabled=True)
|
|
db.add(lib)
|
|
db.flush()
|
|
# imdb 8.0 but audience 4.0 → a rating_min of 7 must MATCH (filter the displayed best score,
|
|
# IMDb preferred), where filtering the raw audience column (4.0) would wrongly exclude it.
|
|
db.add(
|
|
PlexItem(
|
|
rating_key="r1",
|
|
library_id=lib.id,
|
|
kind="movie",
|
|
title="High IMDb",
|
|
imdb_rating=8.0,
|
|
rating=4.0,
|
|
year=2001,
|
|
added_at=datetime(2024, 1, 1, tzinfo=timezone.utc),
|
|
people_enriched_at=datetime(2024, 1, 1, tzinfo=timezone.utc),
|
|
)
|
|
)
|
|
user = User(email="rating@example.com")
|
|
db.add(user)
|
|
db.commit()
|
|
hit = _get(db, user, monkeypatch, override_dep, "/api/plex/library?scope=movie&rating_min=7")
|
|
assert "High IMDb" in _titles(hit)
|
|
miss = _get(db, user, monkeypatch, override_dep, "/api/plex/library?scope=movie&rating_min=9")
|
|
assert "High IMDb" not in _titles(miss)
|