"""Tests for ``alfred.application.tv_shows.search_show.SearchShowUseCase``. Symmetric to ``test_search_movie.py``. The use case wraps :meth:`TMDBClient.search_shows` and flattens each hit into a :class:`ShowHit` wrapped in a :class:`SearchShowResponse` envelope. """ from __future__ import annotations from unittest.mock import MagicMock import pytest from alfred.application.tv_shows_TO_CHECK.search_show import SearchShowUseCase from alfred.domain.shared_TO_CHECK.value_objects import TmdbId from alfred.infrastructure.api_TO_CHECK.tmdb.dto import TmdbShowSearchResult from alfred.infrastructure.api_TO_CHECK.tmdb.exceptions import ( TMDBAPIError, TMDBConfigurationError, ) @pytest.fixture def client(): return MagicMock() @pytest.fixture def use_case(client): return SearchShowUseCase(client) def _hit(**kw) -> TmdbShowSearchResult: defaults = dict( tmdb_id=TmdbId(84958), name="Foundation", first_air_year=2021, ) defaults.update(kw) return TmdbShowSearchResult(**defaults) class TestSuccess: def test_single_hit_is_flattened(self, client, use_case): client.search_shows.return_value = [_hit()] r = use_case.execute("Foundation") assert r.status == "ok" assert len(r.hits) == 1 h = r.hits[0] assert h.tmdb_id == 84958 assert h.name == "Foundation" assert h.first_air_year == 2021 def test_multiple_hits_preserve_order(self, client, use_case): client.search_shows.return_value = [ _hit(), _hit(tmdb_id=TmdbId(42), name="Fallout"), ] r = use_case.execute("Foundation") assert [h.tmdb_id for h in r.hits] == [84958, 42] def test_hit_without_first_air_year(self, client, use_case): client.search_shows.return_value = [_hit(first_air_year=None)] r = use_case.execute("Foundation") assert r.hits[0].first_air_year is None def test_empty_results_returns_ok_with_no_hits(self, client, use_case): client.search_shows.return_value = [] r = use_case.execute("nothing") assert r.status == "ok" assert r.hits == [] assert r.error is None class TestErrorTranslation: def test_configuration_error(self, client, use_case): client.search_shows.side_effect = TMDBConfigurationError("missing key") r = use_case.execute("x") assert r.status == "error" assert r.error == "configuration_error" def test_api_error(self, client, use_case): client.search_shows.side_effect = TMDBAPIError("500 oops") r = use_case.execute("x") assert r.status == "error" assert r.error == "api_error" assert "500" in r.message def test_validation_error(self, client, use_case): client.search_shows.side_effect = ValueError("query too long") r = use_case.execute("x") assert r.status == "error" assert r.error == "validation_failed" assert "too long" in r.message class TestPassThrough: def test_query_forwarded_verbatim(self, client, use_case): client.search_shows.return_value = [] use_case.execute("Foundation") client.search_shows.assert_called_once_with("Foundation")