"""Unit tests for the TMDb normalizer (app/services/metadata/normalizer.py) — section 13. Uses hand-built payload fragments shaped like real TMDb responses rather than calling the network.""" from __future__ import annotations from datetime import date from app.services.metadata.normalizer import normalize_movie, normalize_person FAKE_MOVIE = { "id": 603, "title": "The Matrix", "original_title": "The Matrix", "overview": "A computer hacker learns...", "tagline": "Welcome to the Real World", "status": "Released", "original_language": "en", "release_date": "1999-03-30", "runtime": 136, "budget": 63000000, "revenue": 463517383, "popularity": 45.5, "vote_average": 8.2, "vote_count": 24000, "adult": False, "imdb_id": "tt0133093", "genres": [{"id": 28, "name": "Action"}, {"id": 878, "name": "Science Fiction"}], "production_companies": [ {"id": 79, "name": "Village Roadshow Pictures", "origin_country": "US"} ], "poster_path": "/poster.jpg", "backdrop_path": "/backdrop.jpg", "belongs_to_collection": {"id": 2344, "name": "The Matrix Collection"}, "credits": { "cast": [ { "id": 6384, "name": "Keanu Reeves", "character": "Neo", "order": 0, "profile_path": "/keanu.jpg", "gender": 2, } ], "crew": [ { "id": 9339, "name": "Lana Wachowski", "department": "Directing", "job": "Director", "gender": 1, } ], }, "images": { "posters": [ {"file_path": "/poster.jpg", "width": 2000, "height": 3000, "aspect_ratio": 0.667, "iso_639_1": "en", "vote_average": 8.1} ], "backdrops": [], "logos": [], }, "videos": { "results": [ { "id": "abc123", "type": "Trailer", "site": "YouTube", "key": "vKQi3bBA1y8", "iso_639_1": "en", "iso_3166_1": "US", "official": True, "published_at": "1999-03-01T00:00:00.000Z", } ] }, "keywords": {"keywords": [{"id": 1, "name": "dystopia"}]}, "alternative_titles": {"titles": [{"title": "Matrix", "iso_3166_1": "US"}]}, "external_ids": {"imdb_id": "tt0133093"}, "recommendations": {"results": [{"id": 604}]}, } FAKE_PERSON = { "id": 6384, "name": "Keanu Reeves", "biography": "Keanu Charles Reeves is a Canadian actor.", "birthday": "1964-09-02", "deathday": None, "place_of_birth": "Beirut, Lebanon", "gender": 2, "known_for_department": "Acting", "popularity": 30.2, "also_known_as": ["Keanu Charles Reeves"], "profile_path": "/keanu.jpg", "images": {"profiles": [{"file_path": "/keanu.jpg", "width": 1000, "height": 1500, "aspect_ratio": 0.667, "iso_639_1": None, "vote_average": 5.0}]}, "external_ids": {"imdb_id": "nm0000206"}, } def test_normalize_movie_maps_core_fields(): movie = normalize_movie(FAKE_MOVIE) assert movie.external_id == "603" assert movie.title == "The Matrix" assert movie.status == "released" assert movie.release_date == date(1999, 3, 30) assert movie.runtime_minutes == 136 assert movie.budget == 63000000 assert movie.adult is False def test_normalize_movie_maps_genres_and_keywords(): movie = normalize_movie(FAKE_MOVIE) assert movie.genres == ["Action", "Science Fiction"] assert movie.keywords == ["dystopia"] assert movie.alternate_titles == ["Matrix"] def test_normalize_movie_maps_cast_and_crew(): movie = normalize_movie(FAKE_MOVIE) assert len(movie.cast) == 1 assert movie.cast[0].external_id == "6384" assert movie.cast[0].department == "Acting" assert movie.cast[0].character == "Neo" assert movie.cast[0].gender == "male" assert len(movie.crew) == 1 assert movie.crew[0].department == "Directing" assert movie.crew[0].job == "Director" assert movie.crew[0].gender == "female" def test_normalize_movie_maps_artwork_and_videos(): movie = normalize_movie(FAKE_MOVIE) poster_types = [a.artwork_type for a in movie.artwork] assert poster_types.count("poster") >= 1 assert all(a.url.startswith("https://image.tmdb.org/t/p/original/") for a in movie.artwork) assert len(movie.videos) == 1 assert movie.videos[0].url == "https://www.youtube.com/watch?v=vKQi3bBA1y8" assert movie.videos[0].is_official is True def test_normalize_movie_external_ids_never_include_tmdb_itself(): # TMDb's own id is handled separately by the ingestion pipeline via # `normalized.external_id`, not folded into `external_ids` (section 3: # Aurora doesn't conflate its own identity with provider identity). movie = normalize_movie(FAKE_MOVIE) assert "tmdb" not in movie.external_ids assert movie.external_ids["imdb"] == "tt0133093" def test_normalize_movie_maps_collection_and_recommendations(): movie = normalize_movie(FAKE_MOVIE) assert movie.collection == ("2344", "The Matrix Collection") assert movie.recommendation_external_ids == ["604"] def test_normalize_movie_handles_missing_optional_sections(): minimal = {"id": 1, "title": "Minimal Movie"} movie = normalize_movie(minimal) assert movie.title == "Minimal Movie" assert movie.genres == [] assert movie.cast == [] assert movie.artwork == [] assert movie.collection is None def test_normalize_person_maps_core_fields(): person = normalize_person(FAKE_PERSON) assert person.external_id == "6384" assert person.name == "Keanu Reeves" assert person.birthday == date(1964, 9, 2) assert person.deathday is None assert person.gender == "male" assert person.external_ids["imdb"] == "nm0000206" assert "Keanu Charles Reeves" in person.aliases def test_normalize_person_profile_artwork_deduplicated(): person = normalize_person(FAKE_PERSON) # profile_path duplicates an entry already in images.profiles; it must # not be inserted twice. paths = [a.provider_asset_id for a in person.artwork] assert paths.count("/keanu.jpg") == 1