From 7930e49701fac5cee7279167f3cdf8896f47b229 Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 19 May 2026 21:25:21 +0200 Subject: [PATCH] fix: prevent duplicate year suffixes in series name and folder creation Apply the same duplicate-year prevention logic to additional code paths: - Serie.name_with_year property: skip adding year suffix if name already ends with it - add_series API endpoint: avoid duplicating year in folder_name_with_year - Add integration test for Serie.name_with_year idempotency - Add API test for add_series endpoint year deduplication Complements the folder_rename_service fix for comprehensive coverage. --- src/core/entities/series.py | 5 ++++- src/server/api/anime.py | 6 +++++- tests/api/test_anime_endpoints.py | 19 +++++++++++++++++++ .../test_series_parsing_edge_cases.py | 14 ++++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/core/entities/series.py b/src/core/entities/series.py index 61ede25..3a743e2 100644 --- a/src/core/entities/series.py +++ b/src/core/entities/series.py @@ -271,7 +271,10 @@ class Serie: 'Dororo (2025)' """ if self._year: - return f"{self._name} ({self._year})" + year_suffix = f" ({self._year})" + if self._name.endswith(year_suffix): + return self._name + return f"{self._name}{year_suffix}" return self._name @property diff --git a/src/server/api/anime.py b/src/server/api/anime.py index 77e35f9..d47e32c 100644 --- a/src/server/api/anime.py +++ b/src/server/api/anime.py @@ -730,7 +730,11 @@ async def add_series( # Create folder name with year if available if year: - folder_name_with_year = f"{name} ({year})" + year_suffix = f" ({year})" + if name.endswith(year_suffix): + folder_name_with_year = name + else: + folder_name_with_year = f"{name}{year_suffix}" else: folder_name_with_year = name diff --git a/tests/api/test_anime_endpoints.py b/tests/api/test_anime_endpoints.py index ffba2d1..e25f84d 100644 --- a/tests/api/test_anime_endpoints.py +++ b/tests/api/test_anime_endpoints.py @@ -334,6 +334,25 @@ async def test_add_series_sanitizes_folder_name(authenticated_client): assert "?" not in folder +@pytest.mark.asyncio +async def test_add_series_does_not_duplicate_year(authenticated_client): + """Test that add_series doesn't duplicate year when name already contains it.""" + response = await authenticated_client.post( + "/api/anime/add", + json={ + "link": "https://aniworld.to/anime/stream/eighty-six", + "name": "86 Eighty Six (2021)" + } + ) + + assert response.status_code == 202 + data = response.json() + + # Folder should contain year only once + folder = data["folder"] + assert folder.count("(2021)") == 1 + + @pytest.mark.asyncio async def test_add_series_returns_missing_episodes(authenticated_client): """Test that add_series returns loading progress info.""" diff --git a/tests/integration/test_series_parsing_edge_cases.py b/tests/integration/test_series_parsing_edge_cases.py index 71d185e..5e55c97 100644 --- a/tests/integration/test_series_parsing_edge_cases.py +++ b/tests/integration/test_series_parsing_edge_cases.py @@ -495,6 +495,20 @@ class TestNameWithYearProperty: assert "(2013)" in sanitized assert "Attack on Titan" in sanitized + def test_name_with_year_does_not_duplicate(self): + """Test that name_with_year doesn't duplicate year.""" + serie = Serie( + key="eighty-six", + name="86 Eighty Six (2021)", + site="aniworld.to", + folder="86 Eighty Six (2021)", + episodeDict={}, + year=2021 + ) + + assert serie.name_with_year == "86 Eighty Six (2021)" + assert serie.name_with_year.count("(2021)") == 1 + class TestEnsureFolderWithYear: """Test Serie.ensure_folder_with_year method."""