feat: write all required NFO tags on creation

This commit is contained in:
2026-02-22 11:07:19 +01:00
parent 228964e928
commit e1abf90c81
7 changed files with 592 additions and 208 deletions

View File

@@ -7,6 +7,7 @@ import pytest
from src.core.services.nfo_service import NFOService
from src.core.services.tmdb_client import TMDBAPIError
from src.core.utils.nfo_mapper import _extract_fsk_rating, tmdb_to_nfo_model
@pytest.fixture
@@ -86,22 +87,22 @@ class TestFSKRatingExtraction:
def test_extract_fsk_rating_de(self, nfo_service, mock_content_ratings_de):
"""Test extraction of German FSK rating."""
fsk = nfo_service._extract_fsk_rating(mock_content_ratings_de)
fsk = _extract_fsk_rating(mock_content_ratings_de)
assert fsk == "FSK 16"
def test_extract_fsk_rating_no_de(self, nfo_service, mock_content_ratings_no_de):
"""Test extraction when no German rating available."""
fsk = nfo_service._extract_fsk_rating(mock_content_ratings_no_de)
fsk = _extract_fsk_rating(mock_content_ratings_no_de)
assert fsk is None
def test_extract_fsk_rating_empty(self, nfo_service):
"""Test extraction with empty content ratings."""
fsk = nfo_service._extract_fsk_rating({})
fsk = _extract_fsk_rating({})
assert fsk is None
def test_extract_fsk_rating_none(self, nfo_service):
"""Test extraction with None input."""
fsk = nfo_service._extract_fsk_rating(None)
fsk = _extract_fsk_rating(None)
assert fsk is None
def test_extract_fsk_all_values(self, nfo_service):
@@ -118,7 +119,7 @@ class TestFSKRatingExtraction:
content_ratings = {
"results": [{"iso_3166_1": "DE", "rating": rating_value}]
}
fsk = nfo_service._extract_fsk_rating(content_ratings)
fsk = _extract_fsk_rating(content_ratings)
assert fsk == expected_fsk
def test_extract_fsk_already_formatted(self, nfo_service):
@@ -126,7 +127,7 @@ class TestFSKRatingExtraction:
content_ratings = {
"results": [{"iso_3166_1": "DE", "rating": "FSK 12"}]
}
fsk = nfo_service._extract_fsk_rating(content_ratings)
fsk = _extract_fsk_rating(content_ratings)
assert fsk == "FSK 12"
def test_extract_fsk_partial_match(self, nfo_service):
@@ -134,7 +135,7 @@ class TestFSKRatingExtraction:
content_ratings = {
"results": [{"iso_3166_1": "DE", "rating": "Ab 16 Jahren"}]
}
fsk = nfo_service._extract_fsk_rating(content_ratings)
fsk = _extract_fsk_rating(content_ratings)
assert fsk == "FSK 16"
def test_extract_fsk_unmapped_value(self, nfo_service):
@@ -142,7 +143,7 @@ class TestFSKRatingExtraction:
content_ratings = {
"results": [{"iso_3166_1": "DE", "rating": "Unknown"}]
}
fsk = nfo_service._extract_fsk_rating(content_ratings)
fsk = _extract_fsk_rating(content_ratings)
assert fsk is None
@@ -213,12 +214,15 @@ class TestYearExtraction:
class TestTMDBToNFOModel:
"""Test conversion of TMDB data to NFO model."""
@patch.object(NFOService, '_extract_fsk_rating')
@patch('src.core.utils.nfo_mapper._extract_fsk_rating')
def test_tmdb_to_nfo_with_fsk(self, mock_extract_fsk, nfo_service, mock_tmdb_data, mock_content_ratings_de):
"""Test conversion includes FSK rating."""
mock_extract_fsk.return_value = "FSK 16"
nfo_model = nfo_service._tmdb_to_nfo_model(mock_tmdb_data, mock_content_ratings_de)
nfo_model = tmdb_to_nfo_model(
mock_tmdb_data, mock_content_ratings_de,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert nfo_model.title == "Attack on Titan"
assert nfo_model.fsk == "FSK 16"
@@ -227,7 +231,10 @@ class TestTMDBToNFOModel:
def test_tmdb_to_nfo_without_content_ratings(self, nfo_service, mock_tmdb_data):
"""Test conversion without content ratings."""
nfo_model = nfo_service._tmdb_to_nfo_model(mock_tmdb_data, None)
nfo_model = tmdb_to_nfo_model(
mock_tmdb_data, None,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert nfo_model.title == "Attack on Titan"
assert nfo_model.fsk is None
@@ -235,7 +242,10 @@ class TestTMDBToNFOModel:
def test_tmdb_to_nfo_basic_fields(self, nfo_service, mock_tmdb_data):
"""Test that all basic fields are correctly mapped."""
nfo_model = nfo_service._tmdb_to_nfo_model(mock_tmdb_data)
nfo_model = tmdb_to_nfo_model(
mock_tmdb_data, None,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert nfo_model.title == "Attack on Titan"
assert nfo_model.originaltitle == "進撃の巨人"
@@ -247,7 +257,10 @@ class TestTMDBToNFOModel:
def test_tmdb_to_nfo_ids(self, nfo_service, mock_tmdb_data):
"""Test that all IDs are correctly mapped."""
nfo_model = nfo_service._tmdb_to_nfo_model(mock_tmdb_data)
nfo_model = tmdb_to_nfo_model(
mock_tmdb_data, None,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert nfo_model.tmdbid == 1429
assert nfo_model.imdbid == "tt2560140"
@@ -256,7 +269,10 @@ class TestTMDBToNFOModel:
def test_tmdb_to_nfo_genres_studios(self, nfo_service, mock_tmdb_data):
"""Test that genres and studios are correctly mapped."""
nfo_model = nfo_service._tmdb_to_nfo_model(mock_tmdb_data)
nfo_model = tmdb_to_nfo_model(
mock_tmdb_data, None,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert "Animation" in nfo_model.genre
assert "Sci-Fi & Fantasy" in nfo_model.genre
@@ -265,7 +281,10 @@ class TestTMDBToNFOModel:
def test_tmdb_to_nfo_ratings(self, nfo_service, mock_tmdb_data):
"""Test that ratings are correctly mapped."""
nfo_model = nfo_service._tmdb_to_nfo_model(mock_tmdb_data)
nfo_model = tmdb_to_nfo_model(
mock_tmdb_data, None,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert len(nfo_model.ratings) == 1
assert nfo_model.ratings[0].name == "themoviedb"
@@ -274,7 +293,10 @@ class TestTMDBToNFOModel:
def test_tmdb_to_nfo_cast(self, nfo_service, mock_tmdb_data):
"""Test that cast is correctly mapped."""
nfo_model = nfo_service._tmdb_to_nfo_model(mock_tmdb_data)
nfo_model = tmdb_to_nfo_model(
mock_tmdb_data, None,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert len(nfo_model.actors) == 1
assert nfo_model.actors[0].name == "Yuki Kaji"
@@ -969,7 +991,10 @@ class TestTMDBToNFOModelEdgeCases:
"original_name": "Original"
}
nfo_model = nfo_service._tmdb_to_nfo_model(minimal_data)
nfo_model = tmdb_to_nfo_model(
minimal_data, None,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert nfo_model.title == "Series"
assert nfo_model.originaltitle == "Original"
@@ -978,7 +1003,10 @@ class TestTMDBToNFOModelEdgeCases:
def test_tmdb_to_nfo_with_all_cast(self, nfo_service, mock_tmdb_data):
"""Test conversion includes cast members."""
nfo_model = nfo_service._tmdb_to_nfo_model(mock_tmdb_data)
nfo_model = tmdb_to_nfo_model(
mock_tmdb_data, None,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert len(nfo_model.actors) >= 1
assert nfo_model.actors[0].name == "Yuki Kaji"
@@ -986,7 +1014,10 @@ class TestTMDBToNFOModelEdgeCases:
def test_tmdb_to_nfo_multiple_genres(self, nfo_service, mock_tmdb_data):
"""Test conversion with multiple genres."""
nfo_model = nfo_service._tmdb_to_nfo_model(mock_tmdb_data)
nfo_model = tmdb_to_nfo_model(
mock_tmdb_data, None,
nfo_service.tmdb_client.get_image_url, nfo_service.image_size
)
assert "Animation" in nfo_model.genre
assert "Sci-Fi & Fantasy" in nfo_model.genre
@@ -1001,7 +1032,7 @@ class TestExtractFSKRatingEdgeCases:
"results": [{"iso_3166_1": "DE", "rating": "Ab 16 Jahren"}]
}
fsk = nfo_service._extract_fsk_rating(content_ratings)
fsk = _extract_fsk_rating(content_ratings)
assert fsk == "FSK 16"
def test_extract_fsk_multiple_numbers(self, nfo_service):
@@ -1010,7 +1041,7 @@ class TestExtractFSKRatingEdgeCases:
"results": [{"iso_3166_1": "DE", "rating": "Rating 6 or 12"}]
}
fsk = nfo_service._extract_fsk_rating(content_ratings)
fsk = _extract_fsk_rating(content_ratings)
# Should find 12 first in the search order
assert fsk == "FSK 12"
@@ -1018,17 +1049,17 @@ class TestExtractFSKRatingEdgeCases:
"""Test extraction with empty results list."""
content_ratings = {"results": []}
fsk = nfo_service._extract_fsk_rating(content_ratings)
fsk = _extract_fsk_rating(content_ratings)
assert fsk is None
def test_extract_fsk_none_input(self, nfo_service):
"""Test extraction with None input."""
fsk = nfo_service._extract_fsk_rating(None)
fsk = _extract_fsk_rating(None)
assert fsk is None
def test_extract_fsk_missing_results_key(self, nfo_service):
"""Test extraction when results key is missing."""
fsk = nfo_service._extract_fsk_rating({})
fsk = _extract_fsk_rating({})
assert fsk is None