"""Input validation for the --tmdb / --imdb / --tvdb flags.""" from __future__ import annotations import click import pytest from unshackle.commands.dl import validate_metadata_ids from unshackle.core.api.handlers import validate_download_parameters from unshackle.core.config import config @pytest.fixture(autouse=True) def _default_order(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(config, "metadata_providers", []) def _with_keys(monkeypatch: pytest.MonkeyPatch, **keys: str) -> None: for name in ("tmdb_api_key", "tvdb_api_key", "omdb_api_key", "simkl_client_id"): monkeypatch.setattr(config, name, keys.get(name, "")) # ---------- one ID at a time ---------- @pytest.mark.parametrize( ("tmdb", "imdb", "tvdb"), [(27205, "tt1375666", None), (27205, None, 73871), (None, "tt1375666", 73871), (27205, "tt1375666", 73871)], ) def test_two_ids_are_refused(tmdb: int | None, imdb: str | None, tvdb: int | None) -> None: with pytest.raises(click.UsageError) as exc: validate_metadata_ids(tmdb, imdb, tvdb) assert "cannot be used together" in str(exc.value) def test_no_ids_is_fine() -> None: assert validate_metadata_ids(None, None, None) is None def test_imdb_alone_passes_on_the_keyless_provider(monkeypatch: pytest.MonkeyPatch) -> None: _with_keys(monkeypatch) assert validate_metadata_ids(None, "tt1375666", None) is None # ---------- the ID must have a provider that can resolve it ---------- def test_tmdb_without_its_key_names_the_key(monkeypatch: pytest.MonkeyPatch) -> None: _with_keys(monkeypatch) with pytest.raises(click.UsageError) as exc: validate_metadata_ids(27205, None, None) assert "--tmdb" in str(exc.value) and "tmdb_api_key" in str(exc.value) def test_tvdb_without_its_key_names_the_key(monkeypatch: pytest.MonkeyPatch) -> None: _with_keys(monkeypatch) with pytest.raises(click.UsageError) as exc: validate_metadata_ids(None, None, 73871) assert "--tvdb" in str(exc.value) and "tvdb_api_key" in str(exc.value) def test_tmdb_with_its_key_passes(monkeypatch: pytest.MonkeyPatch) -> None: _with_keys(monkeypatch, tmdb_api_key="k") assert validate_metadata_ids(27205, None, None) is None def test_a_provider_filtered_out_of_the_order_points_at_the_config(monkeypatch: pytest.MonkeyPatch) -> None: _with_keys(monkeypatch, tmdb_api_key="k") monkeypatch.setattr(config, "metadata_providers", ["imdb", "omdb"]) with pytest.raises(click.UsageError) as exc: validate_metadata_ids(27205, None, None) assert "metadata_providers" in str(exc.value) def test_imdb_is_unresolvable_when_the_order_drops_both_of_its_providers(monkeypatch: pytest.MonkeyPatch) -> None: _with_keys(monkeypatch) monkeypatch.setattr(config, "metadata_providers", ["tmdb", "tvdb"]) with pytest.raises(click.UsageError) as exc: validate_metadata_ids(None, "tt1375666", None) assert "metadata_providers" in str(exc.value) assert "imdb" in str(exc.value) and "omdb" in str(exc.value) def test_one_kind_keeping_the_provider_is_enough(monkeypatch: pytest.MonkeyPatch) -> None: """A per-kind order can drop tvdb for movies and keep it for tv, so this must not error.""" _with_keys(monkeypatch, tvdb_api_key="k") monkeypatch.setattr(config, "metadata_providers", {"tv": ["tvdb"], "movie": ["tmdb"]}) assert validate_metadata_ids(None, None, 73871) is None # ---------- the REST path rejects the same combinations ---------- @pytest.mark.parametrize( "payload", [ {"tmdb_id": 27205, "imdb_id": "tt1375666"}, {"tmdb_id": 27205, "tvdb_id": 73871}, {"imdb_id": "tt1375666", "tvdb_id": 73871}, ], ) def test_api_refuses_two_ids(payload: dict) -> None: err = validate_download_parameters(payload) assert err and "multiple external IDs" in err @pytest.mark.parametrize("payload", [{"tmdb_id": 27205}, {"imdb_id": "tt1375666"}, {"tvdb_id": 73871}, {}]) def test_api_accepts_one_id(payload: dict) -> None: assert validate_download_parameters(payload) is None def test_api_still_reports_a_malformed_id_first() -> None: err = validate_download_parameters({"tmdb_id": "12345", "imdb_id": "tt1"}) assert err and "positive integer" in err