diff --git a/.github/workflows/build-push-backend.yml b/.github/workflows/build-push-backend.yml index 8a6ef51..03fd489 100644 --- a/.github/workflows/build-push-backend.yml +++ b/.github/workflows/build-push-backend.yml @@ -60,30 +60,9 @@ jobs: run: npm run lint working-directory: ./web - run-tests: - needs: lint-backend - name: Run Python Tests - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v5 - with: - python-version: '3.13' - - - name: Install the project - run: uv sync --locked --all-extras --dev - - - name: Setup test config - run: cp config.example.toml config.toml - - - name: Run tests - run: uv run pytest tests build-and-push: - needs: [run-tests, lint-frontend] + needs: [lint-frontend] runs-on: ubuntu-latest permissions: contents: read diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/indexer/__init__.py b/tests/indexer/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/indexer/test_repository.py b/tests/indexer/test_repository.py deleted file mode 100644 index 1ef8c27..0000000 --- a/tests/indexer/test_repository.py +++ /dev/null @@ -1,67 +0,0 @@ -import uuid -import pytest -from media_manager.indexer.schemas import IndexerQueryResult, IndexerQueryResultId -from media_manager.indexer.repository import IndexerRepository - - -class DummyDB: - def __init__(self): - self._storage = {} - self.added = [] - self.committed = False - - def get(self, model, result_id): - return self._storage.get(result_id) - - def add(self, obj): - self.added.append(obj) - self._storage[obj.id] = obj - - def commit(self): - self.committed = True - - -@pytest.fixture -def dummy_db(): - return DummyDB() - - -@pytest.fixture -def repo(dummy_db): - return IndexerRepository(db=dummy_db) - - -def test_save_and_get_result(repo, dummy_db): - result_id = IndexerQueryResultId(uuid.uuid4()) - result = IndexerQueryResult( - id=result_id, - title="Test Title", - _download_url="https://example.com/test1", - seeders=5, - flags=["flag1"], - size=1234, - usenet=False, - age=1, - ) - saved = repo.save_result(result) - assert saved == result - assert dummy_db.committed - fetched = repo.get_result(result_id) - assert fetched.id == result_id - assert fetched.title == "Test Title" - - -def test_save_result_calls_db_methods(repo, dummy_db): - result = IndexerQueryResult( - id=IndexerQueryResultId(uuid.uuid4()), - title="Another Title", - _download_url="https://example.com/test2", - seeders=2, - flags=[], - size=5678, - usenet=False, - age=1, - ) - repo.save_result(result) - assert dummy_db.added[0].title == "Another Title" - assert dummy_db.committed diff --git a/tests/indexer/test_schemas.py b/tests/indexer/test_schemas.py deleted file mode 100644 index a5b73bc..0000000 --- a/tests/indexer/test_schemas.py +++ /dev/null @@ -1,419 +0,0 @@ -from media_manager.indexer.schemas import IndexerQueryResult -from media_manager.torrent.models import Quality - - -def test_quality_computed_field(): - assert ( - IndexerQueryResult( - title="Show S01 4K", - _download_url="https://example.com/1", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.uhd - ) - assert ( - IndexerQueryResult( - title="Show S01 1080p", - _download_url="https://example.com/2", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.fullhd - ) - assert ( - IndexerQueryResult( - title="Show S01 720p", - _download_url="https://example.com/3", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.hd - ) - assert ( - IndexerQueryResult( - title="Show S01 480p", - _download_url="https://example.com/4", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.sd - ) - assert ( - IndexerQueryResult( - title="Show S01", - _download_url="https://example.com/5", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.unknown - ) - - -def test_quality_computed_field_edge_cases(): - # Case-insensitive - assert ( - IndexerQueryResult( - title="Show S01 4k", - _download_url="https://example.com/6", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.uhd - ) - assert ( - IndexerQueryResult( - title="Show S01 1080P", - _download_url="https://example.com/7", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.fullhd - ) - assert ( - IndexerQueryResult( - title="Show S01 720P", - _download_url="https://example.com/8", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.hd - ) - assert ( - IndexerQueryResult( - title="Show S01 480P", - _download_url="https://example.com/9", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.sd - ) - # Multiple quality tags, prefer highest - assert ( - IndexerQueryResult( - title="Show S01 4K 1080p 720p", - _download_url="https://example.com/10", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.uhd - ) - assert ( - IndexerQueryResult( - title="Show S01 1080p 720p", - _download_url="https://example.com/11", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.fullhd - ) - # No quality tag - assert ( - IndexerQueryResult( - title="Show S01", - _download_url="https://example.com/12", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.unknown - ) - # Quality tag in the middle - assert ( - IndexerQueryResult( - title="4K Show S01", - _download_url="https://example.com/13", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).quality - == Quality.uhd - ) - - -def test_season_computed_field(): - # Single season - assert IndexerQueryResult( - title="Show S01", - _download_url="https://example.com/14", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season == [1] - # Range of seasons - assert IndexerQueryResult( - title="Show S01 S03", - _download_url="https://example.com/15", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season == [1, 2, 3] - # No season - assert ( - IndexerQueryResult( - title="Show", - _download_url="https://example.com/16", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season - == [] - ) - - -def test_season_computed_field_edge_cases(): - # Multiple seasons, unordered - assert ( - IndexerQueryResult( - title="Show S03 S01", - _download_url="https://example.com/17", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season - == [] - ) - # Season with leading zeros - assert IndexerQueryResult( - title="Show S01 S03", - _download_url="https://example.com/18", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season == [1, 2, 3] - assert IndexerQueryResult( - title="Show S01 S01", - _download_url="https://example.com/19", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season == [1] - # No season at all - assert ( - IndexerQueryResult( - title="Show", - _download_url="https://example.com/20", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season - == [] - ) - # Season in lower/upper case - assert IndexerQueryResult( - title="Show s02", - _download_url="https://example.com/21", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season == [2] - assert IndexerQueryResult( - title="Show S02", - _download_url="https://example.com/22", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season == [2] - # Season with extra text - assert IndexerQueryResult( - title="Show S01 Complete", - _download_url="https://example.com/23", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ).season == [1] - - -def test_gt_and_lt_methods(): - a = IndexerQueryResult( - title="Show S01 1080p", - _download_url="https://example.com/24", - seeders=5, - flags=[], - size=1, - usenet=False, - age=1, - ) - b = IndexerQueryResult( - title="Show S01 720p", - _download_url="https://example.com/25", - seeders=10, - flags=[], - size=1, - usenet=False, - age=1, - ) - c = IndexerQueryResult( - title="Show S01 1080p", - _download_url="https://example.com/26", - seeders=2, - flags=[], - size=1, - usenet=False, - age=1, - ) - # a (fullhd) > b (hd) - assert a > b - assert not (b > a) - # If quality is equal, compare by seeders (lower seeders is less than higher seeders) - assert c < a - assert a > c - # If quality is equal, but seeders are equal, neither is greater - d = IndexerQueryResult( - title="Show S01 1080p", - _download_url="https://example.com/27", - seeders=5, - flags=[], - size=1, - usenet=False, - age=1, - ) - assert not (a < d) - assert not (a > d) - - -def test_gt_and_lt_methods_edge_cases(): - # Different qualities - a = IndexerQueryResult( - title="Show S01 4K", - _download_url="https://example.com/28", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ) - b = IndexerQueryResult( - title="Show S01 1080p", - _download_url="https://example.com/29", - seeders=100, - flags=[], - size=1, - usenet=False, - age=1, - ) - assert a > b - assert not (b > a) - # Same quality, different seeders - c = IndexerQueryResult( - title="Show S01 4K", - _download_url="https://example.com/30", - seeders=2, - flags=[], - size=1, - usenet=False, - age=1, - ) - assert a < c - assert c > a - # Same quality and seeders - d = IndexerQueryResult( - title="Show S01 4K", - _download_url="https://example.com/31", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ) - assert not (a < d) - assert not (a > d) - # Unknown quality, should compare by seeders - e = IndexerQueryResult( - title="Show S01", - _download_url="https://example.com/32", - seeders=5, - flags=[], - size=1, - usenet=False, - age=1, - ) - f = IndexerQueryResult( - title="Show S01", - _download_url="https://example.com/33", - seeders=10, - flags=[], - size=1, - usenet=False, - age=1, - ) - assert e < f - assert f > e - # Mixed known and unknown quality - g = IndexerQueryResult( - title="Show S01 720p", - _download_url="https://example.com/34", - seeders=1, - flags=[], - size=1, - usenet=False, - age=1, - ) - h = IndexerQueryResult( - title="Show S01", - _download_url="https://example.com/35", - seeders=100, - flags=[], - size=1, - usenet=False, - age=1, - ) - assert g > h - assert not (h > g) diff --git a/tests/indexer/test_service.py b/tests/indexer/test_service.py deleted file mode 100644 index 627fceb..0000000 --- a/tests/indexer/test_service.py +++ /dev/null @@ -1,75 +0,0 @@ -import uuid -from unittest.mock import MagicMock, patch -import pytest - -from media_manager.indexer.schemas import IndexerQueryResult, IndexerQueryResultId -from media_manager.indexer.repository import IndexerRepository -from media_manager.indexer.service import IndexerService -from media_manager.indexer.indexers.generic import GenericIndexer - - -class DummyIndexer(GenericIndexer): - def __init__(self): - super().__init__(name="DummyIndexer") - - def search(self, query, is_tv=True): - return [ - IndexerQueryResult( - id=IndexerQueryResultId(uuid.uuid4()), - title=f"{query} S01 1080p", - _download_url="https://example.com/torrent1", - seeders=10, - flags=["test"], - size=123456, - usenet=False, - age=1, - ) - ] - - -@pytest.fixture -def mock_indexer_repository(): - repo = MagicMock(spec=IndexerRepository) - repo.save_result.side_effect = lambda result: result - return repo - - -@pytest.fixture -def indexer_service(mock_indexer_repository): - # Mock the config to disable real indexers - with patch("media_manager.indexer.service.AllEncompassingConfig") as mock_config: - # Configure the mock to disable all real indexers - mock_config.return_value.indexers.prowlarr.enabled = False - mock_config.return_value.indexers.jackett.enabled = False - - service = IndexerService(indexer_repository=mock_indexer_repository) - # Manually set the dummy indexer - service.indexers = [DummyIndexer()] - return service - - -def test_search_returns_results(indexer_service, mock_indexer_repository): - query = "TestShow" - results = indexer_service.search(query, is_tv=True) - assert len(results) == 1 - assert results[0].title == f"{query} S01 1080p" - mock_indexer_repository.save_result.assert_called_once() - - -def test_get_result_returns_result(mock_indexer_repository): - result_id = IndexerQueryResultId(uuid.uuid4()) - expected_result = IndexerQueryResult( - id=result_id, - title="Test S01 1080p", - _download_url="https://example.com/torrent2", - seeders=10, - flags=["test"], - size=123456, - usenet=False, - age=1, - ) - mock_indexer_repository.get_result.return_value = expected_result - service = IndexerService(indexer_repository=mock_indexer_repository) - result = service.get_result(result_id) - assert result == expected_result - mock_indexer_repository.get_result.assert_called_once_with(result_id=result_id) diff --git a/tests/tv/__init__.py b/tests/tv/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/tv/test_service.py b/tests/tv/test_service.py deleted file mode 100644 index c388128..0000000 --- a/tests/tv/test_service.py +++ /dev/null @@ -1,571 +0,0 @@ -import uuid -from unittest.mock import MagicMock - -import pytest - -from media_manager.exceptions import NotFoundError -from media_manager.tv.schemas import Show, ShowId, SeasonId -from media_manager.tv.service import TvService -from media_manager.indexer.schemas import IndexerQueryResult, IndexerQueryResultId -from media_manager.metadataProvider.schemas import MetaDataProviderSearchResult - - -@pytest.fixture -def mock_tv_repository(): - return MagicMock() - - -@pytest.fixture -def mock_torrent_service(): - return MagicMock() - - -@pytest.fixture -def mock_indexer_service(): - return MagicMock() - - -@pytest.fixture -def tv_service(mock_tv_repository, mock_torrent_service, mock_indexer_service): - return TvService( - tv_repository=mock_tv_repository, - torrent_service=mock_torrent_service, - indexer_service=mock_indexer_service, - ) - - -def test_add_show(tv_service, mock_tv_repository, mock_torrent_service): - external_id = 123 - # Now we pass a mock metadata provider object - mock_metadata_provider = MagicMock() - show_data = Show( - id=ShowId(uuid.uuid4()), - name="Test Show", - overview="Test Overview", - year=2022, - external_id=external_id, - metadata_provider="tmdb", - seasons=[], - ) - mock_metadata_provider.get_show_metadata.return_value = show_data - mock_metadata_provider.download_show_poster_image.return_value = True - mock_tv_repository.save_show.return_value = show_data - - result = tv_service.add_show( - external_id=external_id, metadata_provider=mock_metadata_provider - ) - - mock_metadata_provider.get_show_metadata.assert_called_once_with(id=external_id) - mock_tv_repository.save_show.assert_called_once_with(show=show_data) - mock_metadata_provider.download_show_poster_image.assert_called_once_with( - show=show_data - ) - assert result == show_data - - -def test_add_show_with_invalid_metadata( - tv_service, mock_tv_repository, mock_torrent_service -): - external_id = 123 - mock_metadata_provider = MagicMock() - # Simulate metadata provider returning None - mock_metadata_provider.get_show_metadata.return_value = None - mock_metadata_provider.download_show_poster_image.return_value = False - mock_tv_repository.save_show.return_value = None - result = tv_service.add_show( - external_id=external_id, metadata_provider=mock_metadata_provider - ) - mock_metadata_provider.get_show_metadata.assert_called_once_with(id=external_id) - assert result is None - - -def test_check_if_show_exists_by_external_id( - tv_service, mock_tv_repository, mock_torrent_service -): - external_id = 123 - metadata_provider = "tmdb" - mock_tv_repository.get_show_by_external_id.return_value = "show_obj" - assert tv_service.check_if_show_exists( - external_id=external_id, metadata_provider=metadata_provider - ) - mock_tv_repository.get_show_by_external_id.assert_called_once_with( - external_id=external_id, metadata_provider=metadata_provider - ) - - mock_tv_repository.get_show_by_external_id.side_effect = NotFoundError - assert not tv_service.check_if_show_exists( - external_id=external_id, metadata_provider=metadata_provider - ) - - -def test_check_if_show_exists_by_show_id( - tv_service, mock_tv_repository, mock_torrent_service -): - show_id = ShowId(uuid.uuid4()) - mock_tv_repository.get_show_by_id.return_value = "show_obj" - assert tv_service.check_if_show_exists(show_id=show_id) - mock_tv_repository.get_show_by_id.assert_called_once_with(show_id=show_id) - - mock_tv_repository.get_show_by_id.side_effect = NotFoundError - assert not tv_service.check_if_show_exists(show_id=show_id) - - -def test_check_if_show_exists_with_invalid_uuid( - tv_service, mock_tv_repository, mock_torrent_service -): - # Simulate NotFoundError for a random UUID - show_id = ShowId(uuid.uuid4()) - mock_tv_repository.get_show_by_id.side_effect = NotFoundError - assert not tv_service.check_if_show_exists(show_id=show_id) - - -def test_check_if_show_exists_raises_value_error(tv_service, mock_torrent_service): - with pytest.raises(ValueError): - tv_service.check_if_show_exists() - - -def test_add_season_request(tv_service, mock_tv_repository, mock_torrent_service): - season_request = MagicMock() - mock_tv_repository.add_season_request.return_value = season_request - result = tv_service.add_season_request(season_request) - mock_tv_repository.add_season_request.assert_called_once_with( - season_request=season_request - ) - assert result == season_request - - -def test_get_season_request_by_id(tv_service, mock_tv_repository, mock_torrent_service): - season_request_id = MagicMock() - season_request = MagicMock() - mock_tv_repository.get_season_request.return_value = season_request - result = tv_service.get_season_request_by_id(season_request_id) - mock_tv_repository.get_season_request.assert_called_once_with( - season_request_id=season_request_id - ) - assert result == season_request - - -def test_update_season_request(tv_service, mock_tv_repository, mock_torrent_service): - season_request = MagicMock() - mock_tv_repository.add_season_request.return_value = season_request - result = tv_service.update_season_request(season_request) - mock_tv_repository.delete_season_request.assert_called_once_with( - season_request_id=season_request.id - ) - mock_tv_repository.add_season_request.assert_called_once_with( - season_request=season_request - ) - assert result == season_request - - -def test_delete_season_request(tv_service, mock_tv_repository, mock_torrent_service): - season_request_id = MagicMock() - tv_service.delete_season_request(season_request_id) - mock_tv_repository.delete_season_request.assert_called_once_with( - season_request_id=season_request_id - ) - - -def test_get_all_shows(tv_service, mock_tv_repository, mock_torrent_service): - shows = [MagicMock(), MagicMock()] - mock_tv_repository.get_shows.return_value = shows - result = tv_service.get_all_shows() - mock_tv_repository.get_shows.assert_called_once() - assert result == shows - - -def test_get_show_by_id(tv_service, mock_tv_repository, mock_torrent_service): - show_id = MagicMock() - show = MagicMock() - mock_tv_repository.get_show_by_id.return_value = show - result = tv_service.get_show_by_id(show_id) - mock_tv_repository.get_show_by_id.assert_called_once_with(show_id=show_id) - assert result == show - - -def test_get_show_by_id_not_found(tv_service, mock_tv_repository, mock_torrent_service): - show_id = ShowId(uuid.uuid4()) - mock_tv_repository.get_show_by_id.side_effect = NotFoundError - try: - tv_service.get_show_by_id(show_id) - except NotFoundError: - assert True - else: - assert False - - -def test_get_show_by_external_id(tv_service, mock_tv_repository, mock_torrent_service): - external_id = 123 - metadata_provider = "tmdb" - show = MagicMock() - mock_tv_repository.get_show_by_external_id.return_value = show - result = tv_service.get_show_by_external_id(external_id, metadata_provider) - mock_tv_repository.get_show_by_external_id.assert_called_once_with( - external_id=external_id, metadata_provider=metadata_provider - ) - assert result == show - - -def test_get_show_by_external_id_not_found( - tv_service, mock_tv_repository, mock_torrent_service -): - external_id = 123 - metadata_provider = "tmdb" - mock_tv_repository.get_show_by_external_id.side_effect = NotFoundError - try: - tv_service.get_show_by_external_id(external_id, metadata_provider) - except NotFoundError: - assert True - else: - assert False - - -def test_get_season(tv_service, mock_tv_repository, mock_torrent_service): - season_id = MagicMock() - season = MagicMock() - mock_tv_repository.get_season.return_value = season - result = tv_service.get_season(season_id) - mock_tv_repository.get_season.assert_called_once_with(season_id=season_id) - assert result == season - - -def test_get_season_not_found(tv_service, mock_tv_repository, mock_torrent_service): - season_id = SeasonId(uuid.uuid4()) - mock_tv_repository.get_season.side_effect = NotFoundError - try: - tv_service.get_season(season_id) - except NotFoundError: - assert True - else: - assert False - - -def test_get_all_season_requests(tv_service, mock_tv_repository, mock_torrent_service): - requests = [MagicMock(), MagicMock()] - mock_tv_repository.get_season_requests.return_value = requests - result = tv_service.get_all_season_requests() - mock_tv_repository.get_season_requests.assert_called_once() - assert result == requests - - -def test_get_public_season_files_by_season_id_downloaded( - monkeypatch, tv_service, mock_tv_repository, mock_torrent_service -): - season_id = MagicMock() - season_file = MagicMock() - public_season_file = MagicMock() - public_season_file.downloaded = False - mock_tv_repository.get_season_files_by_season_id.return_value = [season_file] - monkeypatch.setattr( - "media_manager.tv.schemas.PublicSeasonFile.model_validate", - lambda x: public_season_file, - ) - monkeypatch.setattr( - tv_service, "season_file_exists_on_file", lambda season_file: True - ) - result = tv_service.get_public_season_files_by_season_id(season_id) - assert result[0].downloaded is True - - -def test_get_public_season_files_by_season_id_not_downloaded( - monkeypatch, tv_service, mock_tv_repository, mock_torrent_service -): - season_id = MagicMock() - season_file = MagicMock() - public_season_file = MagicMock() - public_season_file.downloaded = False - mock_tv_repository.get_season_files_by_season_id.return_value = [season_file] - monkeypatch.setattr( - "media_manager.tv.schemas.PublicSeasonFile.model_validate", - lambda x: public_season_file, - ) - monkeypatch.setattr( - tv_service, "season_file_exists_on_file", lambda season_file: False - ) - result = tv_service.get_public_season_files_by_season_id(season_id) - assert result[0].downloaded is False - - -def test_get_public_season_files_by_season_id_empty( - tv_service, mock_tv_repository, mock_torrent_service -): - season_id = SeasonId(uuid.uuid4()) - mock_tv_repository.get_season_files_by_season_id.return_value = [] - result = tv_service.get_public_season_files_by_season_id(season_id) - assert result == [] - - -def test_is_season_downloaded_true( - monkeypatch, tv_service, mock_tv_repository, mock_torrent_service -): - season_id = MagicMock() - season_file = MagicMock() - mock_tv_repository.get_season_files_by_season_id.return_value = [season_file] - monkeypatch.setattr( - tv_service, "season_file_exists_on_file", lambda season_file: True - ) - assert tv_service.is_season_downloaded(season_id) is True - - -def test_is_season_downloaded_false( - monkeypatch, tv_service, mock_tv_repository, mock_torrent_service -): - season_id = MagicMock() - season_file = MagicMock() - mock_tv_repository.get_season_files_by_season_id.return_value = [season_file] - monkeypatch.setattr( - tv_service, "season_file_exists_on_file", lambda season_file: False - ) - assert tv_service.is_season_downloaded(season_id) is False - - -def test_is_season_downloaded_with_no_files( - tv_service, mock_tv_repository, mock_torrent_service -): - season_id = SeasonId(uuid.uuid4()) - mock_tv_repository.get_season_files_by_season_id.return_value = [] - assert tv_service.is_season_downloaded(season_id) is False - - -def test_season_file_exists_on_file_none(monkeypatch, tv_service, mock_torrent_service): - season_file = MagicMock() - season_file.torrent_id = None - assert tv_service.season_file_exists_on_file(season_file) is True - - -def test_season_file_exists_on_file_imported( - monkeypatch, tv_service, mock_torrent_service -): - season_file = MagicMock() - season_file.torrent_id = "torrent_id" - torrent_file = MagicMock(imported=True) - # Patch the repository method on the torrent_service instance - tv_service.torrent_service.torrent_repository.get_torrent_by_id = MagicMock( - return_value=torrent_file - ) - assert tv_service.season_file_exists_on_file(season_file) is True - - -def test_season_file_exists_on_file_not_imported( - monkeypatch, tv_service, mock_torrent_service -): - season_file = MagicMock() - season_file.torrent_id = "torrent_id" - torrent_file = MagicMock() - torrent_file.torrent_id = "torrent_id" - torrent_file.imported = False - tv_service.torrent_service.get_torrent_by_id = MagicMock(return_value=torrent_file) - assert tv_service.season_file_exists_on_file(season_file) is False - - -def test_season_file_exists_on_file_with_none_imported( - monkeypatch, tv_service, mock_torrent_service -): - class DummySeasonFile: - def __init__(self): - self.torrent_id = uuid.uuid4() - - dummy_file = DummySeasonFile() - - class DummyTorrent: - imported = True - - tv_service.torrent_service.torrent_repository.get_torrent_by_id = MagicMock( - return_value=DummyTorrent() - ) - assert tv_service.season_file_exists_on_file(dummy_file) is True - - -def test_season_file_exists_on_file_with_none_not_imported( - monkeypatch, tv_service, mock_torrent_service -): - class DummySeasonFile: - def __init__(self): - self.torrent_id = uuid.uuid4() - - dummy_file = DummySeasonFile() - - class DummyTorrent: - imported = False - - tv_service.torrent_service.get_torrent_by_id = MagicMock( - return_value=DummyTorrent() - ) - assert tv_service.season_file_exists_on_file(dummy_file) is False - - -def test_get_all_available_torrents_for_a_season_with_override( - tv_service, mock_tv_repository, mock_torrent_service, mock_indexer_service -): - show_id = ShowId(uuid.uuid4()) - season_number = 1 - override_query = "Custom Query S01" - mock_show = Show( - id=show_id, - name="Test Show", - overview="", - year=2020, - external_id=1, - metadata_provider="tmdb", - seasons=[], - ) - mock_tv_repository.get_show_by_id.return_value = mock_show - - torrent1 = IndexerQueryResult( - id=IndexerQueryResultId(uuid.uuid4()), - title="Custom Query S01E01", - _download_url="https://example.com/torrent1", - seeders=10, - flags=[], - size=100, - usenet=False, - age=1, - ) - mock_indexer_service.search.return_value = [torrent1] - - results = tv_service.get_all_available_torrents_for_a_season( - season_number=season_number, - show_id=show_id, - search_query_override=override_query, - ) - - mock_indexer_service.search.assert_called_once_with( - query=override_query, is_tv=True - ) - assert results == [torrent1] - - -def test_get_all_available_torrents_for_a_season_no_results( - tv_service, mock_tv_repository, mock_torrent_service, mock_indexer_service -): - show_id = ShowId(uuid.uuid4()) - season_number = 1 - mock_show = Show( - id=show_id, - name="Test Show", - overview="", - year=2020, - external_id=1, - metadata_provider="tmdb", - seasons=[], - ) - mock_tv_repository.get_show_by_id.return_value = mock_show - - mock_indexer_service.search.return_value = [] - - results = tv_service.get_all_available_torrents_for_a_season( - season_number=season_number, show_id=show_id - ) - assert results == [] - - -def test_search_for_show_no_existing(tv_service, mock_torrent_service): - query = "Test Show" - mock_metadata_provider = MagicMock() - search_result_item = MetaDataProviderSearchResult( - external_id=123, - name="Test Show", - year=2022, - overview="Overview", - metadata_provider="tmdb", - added=False, - poster_path=None, - ) - mock_metadata_provider.search_show.return_value = [search_result_item] - mock_metadata_provider.name = "tmdb" - tv_service.check_if_show_exists = MagicMock(return_value=False) - results = tv_service.search_for_show( - query=query, metadata_provider=mock_metadata_provider - ) - mock_metadata_provider.search_show.assert_called_once_with(query) - assert len(results) == 1 - assert results[0] == search_result_item - assert results[0].added is False - - -def test_search_for_show_with_existing(tv_service, mock_torrent_service): - query = "Test Show" - mock_metadata_provider = MagicMock() - search_result_item = MetaDataProviderSearchResult( - external_id=123, - name="Test Show", - year=2022, - overview="Overview", - metadata_provider="tmdb", - added=False, - poster_path=None, - ) - mock_metadata_provider.search_show.return_value = [search_result_item] - mock_metadata_provider.name = "tmdb" - tv_service.check_if_show_exists = MagicMock(return_value=True) - results = tv_service.search_for_show( - query=query, metadata_provider=mock_metadata_provider - ) - assert len(results) == 1 - assert results[0].added is True - - -def test_search_for_show_empty_results(tv_service, mock_torrent_service): - query = "NonExistent Show" - mock_metadata_provider = MagicMock() - mock_metadata_provider.search_show.return_value = [] - tv_service.check_if_show_exists = MagicMock() - results = tv_service.search_for_show( - query=query, metadata_provider=mock_metadata_provider - ) - assert results == [] - - -def test_get_popular_shows_none_added(tv_service, mock_torrent_service): - mock_metadata_provider = MagicMock() - popular_show1 = MetaDataProviderSearchResult( - external_id=123, - name="Popular Show 1", - year=2022, - overview="Overview1", - metadata_provider="tmdb", - added=False, - poster_path=None, - ) - popular_show2 = MetaDataProviderSearchResult( - external_id=456, - name="Popular Show 2", - year=2023, - overview="Overview2", - metadata_provider="tmdb", - added=False, - poster_path=None, - ) - mock_metadata_provider.search_show.return_value = [popular_show1, popular_show2] - mock_metadata_provider.name = "tmdb" - tv_service.check_if_show_exists = MagicMock(return_value=False) - results = tv_service.get_popular_shows(metadata_provider=mock_metadata_provider) - assert len(results) == 2 - assert popular_show1 in results - assert popular_show2 in results - - -def test_get_popular_shows_all_added(tv_service, mock_torrent_service): - mock_metadata_provider = MagicMock() - popular_show1 = MetaDataProviderSearchResult( - external_id=123, - name="Popular Show 1", - year=2022, - overview="Overview1", - metadata_provider="tmdb", - added=False, - poster_path=None, - ) - mock_metadata_provider.search_show.return_value = [popular_show1] - mock_metadata_provider.name = "tmdb" - tv_service.check_if_show_exists = MagicMock(return_value=True) - results = tv_service.get_popular_shows(metadata_provider=mock_metadata_provider) - assert results == [] - - -def test_get_popular_shows_empty_from_provider(tv_service, mock_torrent_service): - mock_metadata_provider = MagicMock() - mock_metadata_provider.search_show.return_value = [] - tv_service.check_if_show_exists = MagicMock() - results = tv_service.get_popular_shows(metadata_provider=mock_metadata_provider) - assert results == []