refactor: restructure core→server, split large entity files into database module

- Move src/core/ → src/server/
- Split SerieList.py (531 lines) and series.py (414 lines) into src/server/database/
- Add database/models.py for SQLAlchemy models
- Update all test imports to reflect new structure
- Remove deprecated test files (test_serie_class.py, test_serie_folder_with_year.py)
This commit is contained in:
2026-06-04 21:11:53 +02:00
parent 09d454d4c0
commit 5526ab884a
76 changed files with 1186 additions and 3574 deletions

View File

@@ -7,13 +7,13 @@ from unittest.mock import MagicMock, Mock, patch
import pytest
import requests
from src.core.providers.aniworld_provider import AniworldLoader
from src.server.providers.aniworld_provider import AniworldLoader
@pytest.fixture
def loader():
"""Create AniworldLoader with mocked session to prevent real HTTP calls."""
with patch("src.core.providers.aniworld_provider.UserAgent") as mock_ua:
with patch("src.server.providers.aniworld_provider.UserAgent") as mock_ua:
mock_ua.return_value.random = "MockUserAgent/1.0"
instance = AniworldLoader()
instance.session = MagicMock()
@@ -390,7 +390,7 @@ class TestAniworldProviderParsing:
class TestAniworldSeasonEpisodeCount:
"""Test season and episode count retrieval."""
@patch("src.core.providers.aniworld_provider.requests.get")
@patch("src.server.providers.aniworld_provider.requests.get")
def test_get_season_episode_count(self, mock_get, loader):
"""get_season_episode_count should return correct counts."""
# Main page with 2 seasons
@@ -421,7 +421,7 @@ class TestAniworldSeasonEpisodeCount:
result = loader.get_season_episode_count("naruto")
assert result == {1: 3, 2: 2}
@patch("src.core.providers.aniworld_provider.requests.get")
@patch("src.server.providers.aniworld_provider.requests.get")
def test_get_season_episode_count_no_seasons(self, mock_get, loader):
"""get_season_episode_count should return empty dict when no seasons."""
html = "<html><body></body></html>"
@@ -616,7 +616,7 @@ class TestAniworldDownloadFailover:
return ydl
with patch(
"src.core.providers.aniworld_provider.YoutubeDL",
"src.server.providers.aniworld_provider.YoutubeDL",
side_effect=fake_ytdl,
):
result = patched_loader.download(
@@ -649,7 +649,7 @@ class TestAniworldDownloadFailover:
return ydl
with patch(
"src.core.providers.aniworld_provider.YoutubeDL",
"src.server.providers.aniworld_provider.YoutubeDL",
side_effect=fake_ytdl,
):
result = patched_loader.download(
@@ -670,7 +670,7 @@ class TestAniworldDownloadFailover:
patched_loader._try_direct_stream.side_effect = write_direct
with patch(
"src.core.providers.aniworld_provider.YoutubeDL"
"src.server.providers.aniworld_provider.YoutubeDL"
) as mock_ydl:
result = patched_loader.download(
str(tmp_path), "Anime", 1, 1, "k", "German Dub"
@@ -682,7 +682,7 @@ class TestAniworldDownloadFailover:
self, patched_loader, tmp_path, caplog
):
with patch(
"src.core.providers.aniworld_provider.YoutubeDL",
"src.server.providers.aniworld_provider.YoutubeDL",
side_effect=Exception("HTTP 404"),
):
result = patched_loader.download(
@@ -728,7 +728,7 @@ class TestDecodeHtmlContent:
def test_decodes_utf8_content(self):
"""Should correctly decode UTF-8 content."""
from src.core.providers.aniworld_provider import _decode_html_content
from src.server.providers.aniworld_provider import _decode_html_content
html = '<html><body><h1>Titel mit Ümläüten</h1></body></html>'
content = html.encode('utf-8')
result = _decode_html_content(content)
@@ -736,7 +736,7 @@ class TestDecodeHtmlContent:
def test_decodes_latin1_content(self):
"""Should correctly decode Latin-1 content when chardet detects it."""
from src.core.providers.aniworld_provider import _decode_html_content
from src.server.providers.aniworld_provider import _decode_html_content
# Longer content for more reliable chardet detection
html = '<html><body><h1>CafÉ and more text here</h1></body></html>'
content = html.encode('latin-1')
@@ -745,13 +745,13 @@ class TestDecodeHtmlContent:
def test_replaces_invalid_bytes(self):
"""Should replace invalid bytes with replacement character."""
from src.core.providers.aniworld_provider import _decode_html_content
from src.server.providers.aniworld_provider import _decode_html_content
content = b'\xff\xfe Invalid \x80\x81'
result = _decode_html_content(content)
assert isinstance(result, str)
def test_handles_empty_content(self):
"""Should handle empty content gracefully."""
from src.core.providers.aniworld_provider import _decode_html_content
from src.server.providers.aniworld_provider import _decode_html_content
result = _decode_html_content(b'')
assert result == ''