1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
"""
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"}]
|