100 lines
4.3 KiB
Python
100 lines
4.3 KiB
Python
"""Round-trip tests — domain → sidecar → YAML → sidecar → domain.
|
|
|
|
These tests are the contract guarantee that the v2 sidecar is a
|
|
lossless cache for everything the spec claims it stores. Any field
|
|
introduced in the future must come with a round-trip test that
|
|
covers it; otherwise we can silently drop it on read.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import yaml
|
|
|
|
from alfred.infrastructure.persistence_TO_CHECK.dot_alfred.v2.bridge import (
|
|
movie_release_from_sidecar,
|
|
movie_release_to_sidecar,
|
|
series_release_from_sidecar,
|
|
series_release_to_sidecar,
|
|
)
|
|
from alfred.infrastructure.persistence_TO_CHECK.dot_alfred.v2.sidecar_release import (
|
|
SCHEMA_VERSION,
|
|
MovieReleaseSidecar,
|
|
SeriesReleaseSidecar,
|
|
)
|
|
|
|
|
|
class TestSeriesReleaseRoundTrip:
|
|
def test_domain_to_sidecar_preserves_top_level(self, foundation_release):
|
|
sidecar = series_release_to_sidecar(foundation_release)
|
|
assert sidecar.schema_version == SCHEMA_VERSION
|
|
assert sidecar.tmdb_id == 84958
|
|
assert sidecar.imdb_id == "tt0804484"
|
|
assert len(sidecar.releases) == 2
|
|
|
|
def test_full_loop_domain_to_domain_is_equal(self, foundation_release):
|
|
sidecar = series_release_to_sidecar(foundation_release)
|
|
restored = series_release_from_sidecar(sidecar)
|
|
assert restored == foundation_release
|
|
|
|
def test_full_loop_through_yaml_is_equal(self, foundation_release):
|
|
sidecar = series_release_to_sidecar(foundation_release)
|
|
text = yaml.safe_dump(sidecar.model_dump(mode="json"))
|
|
reloaded = SeriesReleaseSidecar.model_validate(yaml.safe_load(text))
|
|
restored = series_release_from_sidecar(reloaded)
|
|
assert restored == foundation_release
|
|
|
|
def test_multi_episode_file_round_trips(self, foundation_release):
|
|
sidecar = series_release_to_sidecar(foundation_release)
|
|
s02 = sidecar.releases[1]
|
|
multi = s02.episodes[1]
|
|
assert multi.start == 2 and multi.end == 3
|
|
restored = series_release_from_sidecar(sidecar)
|
|
restored_multi = restored.seasons[1].episodes[1]
|
|
assert restored_multi.episodes.start.value == 2
|
|
assert restored_multi.episodes.end.value == 3
|
|
|
|
def test_sdh_flag_round_trips(self, foundation_release):
|
|
sidecar = series_release_to_sidecar(foundation_release)
|
|
restored = series_release_from_sidecar(sidecar)
|
|
sdh_track = restored.seasons[0].episodes[0].tracks.subtitle_tracks[1]
|
|
assert sdh_track.is_sdh is True
|
|
|
|
def test_no_imdb_id_round_trips_as_none(self, foundation_release):
|
|
# Replace the imdb_id with None and verify it survives the loop.
|
|
from dataclasses import replace
|
|
no_imdb = replace(foundation_release, imdb_id=None)
|
|
sidecar = series_release_to_sidecar(no_imdb)
|
|
assert sidecar.imdb_id is None
|
|
restored = series_release_from_sidecar(sidecar)
|
|
assert restored.imdb_id is None
|
|
|
|
|
|
class TestMovieReleaseRoundTrip:
|
|
def test_domain_to_sidecar_preserves_top_level(self, inception_release):
|
|
sidecar = movie_release_to_sidecar(inception_release)
|
|
assert sidecar.schema_version == SCHEMA_VERSION
|
|
assert sidecar.tmdb_id == 27205
|
|
assert sidecar.imdb_id == "tt1375666"
|
|
assert sidecar.folder == "Inception.2010.1080p.BluRay.x264-GROUP"
|
|
|
|
def test_full_loop_through_yaml_is_equal(self, inception_release):
|
|
sidecar = movie_release_to_sidecar(inception_release)
|
|
text = yaml.safe_dump(sidecar.model_dump(mode="json"))
|
|
reloaded = MovieReleaseSidecar.model_validate(yaml.safe_load(text))
|
|
restored = movie_release_from_sidecar(reloaded)
|
|
assert restored == inception_release
|
|
|
|
def test_forced_subtitle_flag_round_trips(self, inception_release):
|
|
sidecar = movie_release_to_sidecar(inception_release)
|
|
restored = movie_release_from_sidecar(sidecar)
|
|
forced = restored.tracks.subtitle_tracks[1]
|
|
assert forced.is_forced is True
|
|
assert forced.language == "fre"
|
|
|
|
def test_added_at_round_trips_through_yaml(self, inception_release):
|
|
sidecar = movie_release_to_sidecar(inception_release)
|
|
text = yaml.safe_dump(sidecar.model_dump(mode="json"))
|
|
reloaded = MovieReleaseSidecar.model_validate(yaml.safe_load(text))
|
|
restored = movie_release_from_sidecar(reloaded)
|
|
assert restored.added_at == inception_release.added_at
|