""" A series has a director credit in the detail modal too. `media_meta_resp.director` was filled from the credits crew's `job == "Director"`, which is a movie shape. TMDB's aggregate `tv_credits` crew is routinely empty and never carries that job, so every show answered with `director: null` and the detail modal simply dropped the line — reported as "I can't see the director of a series". What TMDB models for a show, and what its own page shows, is `created_by` on the show details. Several creators is ordinary, so they join into one line. """ import pytest from meshbay_node.transport.webrtc_server import WebRTCPeerSession pytestmark = pytest.mark.asyncio class FakeTmdbClient: """Details and credits, with no language fallback to get in the way.""" def __init__(self, details: dict, credits: dict | None = None): self._details = details self._credits = credits or {"cast": [], "crew": []} async def movie_details(self, tmdb_id, language=None): return self._details async def tv_details(self, tmdb_id, language=None): return self._details async def movie_credits(self, tmdb_id): return self._credits async def tv_credits(self, tmdb_id): return self._credits def _details(**extra): """Enough fields that the English per-field fallback never fires.""" return {"name": "Some Show", "overview": "A synopsis.", "poster_path": "/p.jpg", "genres": [{"name": "Drama"}], "first_air_date": "1993-09-10", **extra} async def test_a_show_reports_its_creator_as_the_director(): client = FakeTmdbClient(_details(created_by=[{"name": "A Creator"}])) meta = await WebRTCPeerSession._tmdb_build_meta(client, "4087", "tv", {"id": 4087}) assert meta["director"] == "A Creator" async def test_several_creators_read_as_one_line(): client = FakeTmdbClient(_details( created_by=[{"name": "A Creator"}, {"name": "Another Creator"}])) meta = await WebRTCPeerSession._tmdb_build_meta(client, "4087", "tv", {"id": 4087}) assert meta["director"] == "A Creator, Another Creator" @pytest.mark.parametrize("created_by", [None, [], [{"name": ""}], [{}]]) async def test_a_show_with_no_creator_credit_stays_none(created_by): """None, not "" — the modal drops the line rather than printing a label with nothing after it.""" client = FakeTmdbClient(_details(created_by=created_by)) meta = await WebRTCPeerSession._tmdb_build_meta(client, "4087", "tv", {"id": 4087}) assert meta["director"] is None async def test_an_empty_tv_crew_no_longer_decides_the_answer(): """The old shape, kept as a regression: a show whose aggregate crew has a Director entry is still described by its creators, and one whose crew is empty — the usual case — is no longer left blank.""" client = FakeTmdbClient( _details(created_by=[{"name": "A Creator"}]), credits={"cast": [], "crew": [{"job": "Director", "name": "An Episode Director"}]}) meta = await WebRTCPeerSession._tmdb_build_meta(client, "4087", "tv", {"id": 4087}) assert meta["director"] == "A Creator" async def test_a_movie_still_takes_its_director_from_the_crew(): """`created_by` does not exist on a movie; nothing about that path moves.""" client = FakeTmdbClient( {"title": "Some Film", "overview": "A synopsis.", "poster_path": "/p.jpg", "genres": [{"name": "Thriller"}], "release_date": "2014-02-01"}, credits={"cast": [{"name": "A Performer", "character": "Someone"}], "crew": [{"job": "Editor", "name": "An Editor"}, {"job": "Director", "name": "A Director"}]}) meta = await WebRTCPeerSession._tmdb_build_meta(client, "418517", "movie", {"id": 418517}) assert meta["director"] == "A Director" assert meta["cast"] == [{"name": "A Performer", "character": "Someone"}]