fix(plex): S5b review — preserve enriched cast_names across full syncs
Address the /code-review high finding on S5b: gating the info-page cast enrich on `people_enriched_at is None` removed the old per-view regrow of `cast_names`, so a routine full sync that reset it to the listing top-20 (`_apply_facet_fields`) — while never clearing people_enriched_at — left it permanently truncated, silently dropping cast past the top ~20 from the S4 person-page filter. Root fix: `_apply_facet_fields` now only takes the listing's cast for a NOT-yet-enriched row; an enriched row keeps its fuller stored cast (people_text still rebuilt from the updated directors + the preserved cast). Makes the people_enriched_at flag the endpoints/backfill trust actually reliable. Tests: cast_names preserved for an enriched row vs applied for a fresh one; show_detail lazy-fill persists imdb/full_cast on first view. Full suite green.
This commit is contained in:
@@ -20,7 +20,7 @@ from app.db import get_db
|
||||
from app.main import app
|
||||
from app.models import PlexItem, PlexLibrary, PlexShow, User
|
||||
from app.plex import detail
|
||||
from app.plex.sync import _enrich_people_batch
|
||||
from app.plex.sync import _apply_facet_fields, _enrich_people_batch
|
||||
|
||||
# A full Plex metadata dict: an explicit IMDb Rating entry (must win over audienceRating), an IMDb Guid,
|
||||
# a tagline, and a two-person cast (one with a CDN headshot → proxied, one without → thumb None).
|
||||
@@ -101,6 +101,31 @@ class _StubClient:
|
||||
return self._meta
|
||||
|
||||
|
||||
def test_apply_facet_fields_preserves_enriched_cast_names():
|
||||
"""A full sync must NOT downgrade an already-enriched full cast back to the listing top-20 — since
|
||||
sync never clears people_enriched_at, nothing would regrow it and the person-page filter would lose
|
||||
the names past the listing cap (regression guard for E5 S5b's enrich gating)."""
|
||||
# The cheap listing's top few cast + the (always-present) director.
|
||||
thin = {"Role": [{"tag": "Al Pacino"}, {"tag": "James Caan"}], "Director": [{"tag": "Francis Ford Coppola"}]}
|
||||
|
||||
# Not-yet-enriched row: the listing cast IS applied.
|
||||
fresh = SimpleNamespace(people_enriched_at=None, directors=None, cast_names=None)
|
||||
_apply_facet_fields(fresh, thin)
|
||||
assert fresh.cast_names == ["Al Pacino", "James Caan"]
|
||||
|
||||
# Enriched row: the fuller stored cast is KEPT, not overwritten by the thin listing.
|
||||
from datetime import datetime, timezone
|
||||
enriched = SimpleNamespace(
|
||||
people_enriched_at=datetime.now(timezone.utc),
|
||||
directors=["Francis Ford Coppola"],
|
||||
cast_names=["Marlon Brando", "Al Pacino", "James Caan", "Diane Keaton"],
|
||||
)
|
||||
_apply_facet_fields(enriched, thin)
|
||||
assert enriched.cast_names == ["Marlon Brando", "Al Pacino", "James Caan", "Diane Keaton"]
|
||||
# people_text is rebuilt from the (updated) directors + the PRESERVED full cast.
|
||||
assert "Diane Keaton" in enriched.people_text and "Francis Ford Coppola" in enriched.people_text
|
||||
|
||||
|
||||
def test_enrich_people_batch_persists_detail(db):
|
||||
lib = PlexLibrary(plex_key="1", title="Movies", kind="movie", enabled=True)
|
||||
db.add(lib)
|
||||
@@ -251,3 +276,26 @@ def test_show_detail_serves_from_row(db, monkeypatch):
|
||||
assert body["imdb_url"] == "https://www.imdb.com/title/tt0903747/"
|
||||
assert [c["name"] for c in body["cast"]] == ["Bryan Cranston"]
|
||||
assert resp.json()["related"] == []
|
||||
|
||||
|
||||
def test_show_detail_lazy_fills_when_unenriched(db, monkeypatch):
|
||||
"""A not-yet-enriched show is filled from the live meta on first view (imdb/full_cast persisted +
|
||||
stamped) so subsequent views serve from the row."""
|
||||
lib = PlexLibrary(plex_key="2", title="Shows", kind="show", enabled=True)
|
||||
db.add(lib)
|
||||
db.flush()
|
||||
show = PlexShow(rating_key="s1", library_id=lib.id, title="A Show")
|
||||
db.add(show)
|
||||
db.commit()
|
||||
user = _user(db, "showfill@example.com")
|
||||
db.commit()
|
||||
|
||||
# _show_enrichment returns (live meta, no related) → the fill branch runs.
|
||||
monkeypatch.setattr(browse, "_show_enrichment", lambda db_, rk: (RICH_META, []))
|
||||
resp = _get(db, user, monkeypatch, "/api/plex/show/s1")
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert resp.json()["show"]["imdb_id"] == "tt0068646"
|
||||
db.refresh(show)
|
||||
assert show.imdb_id == "tt0068646" # persisted for next time
|
||||
assert show.people_enriched_at is not None
|
||||
assert [c["name"] for c in show.full_cast] == ["Marlon Brando", "Al Pacino"]
|
||||
|
||||
Reference in New Issue
Block a user