Files
alfred/tests/application/test_search_show.py
T
2026-05-26 21:45:11 +02:00

102 lines
3.2 KiB
Python

"""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")