Files
Curator/tests/test_subtitles.py
T

171 lines
6.1 KiB
Python

"""Tests for external subtitle sidecars (src.core.subtitles)."""
import pytest
from src.core.subtitles import (
SubtitleFile,
attach_subtitle,
find_subtitles,
rename_subtitles_with,
subtitle_filename,
)
def _video(tmp_path, name="Matrix (1999) [tmdbid-603].mkv"):
v = tmp_path / name
v.write_bytes(b"x")
return v
class TestSubtitleFilename:
def test_bare_no_language(self):
assert subtitle_filename("Matrix (1999)", ".srt") == "Matrix (1999).srt"
def test_with_language(self):
assert (
subtitle_filename("Matrix (1999)", ".srt", "cs") == "Matrix (1999).cs.srt"
)
def test_with_language_and_flag(self):
assert (
subtitle_filename("Matrix (1999)", ".srt", "cs", "forced")
== "Matrix (1999).cs.forced.srt"
)
def test_uppercase_input_is_lowered(self):
assert (
subtitle_filename("Matrix (1999)", ".SRT", "CS", "FORCED")
== "Matrix (1999).cs.forced.srt"
)
class TestFindSubtitles:
def test_finds_bare_language_and_flagged(self, tmp_path):
video = _video(tmp_path)
(tmp_path / "Matrix (1999) [tmdbid-603].srt").write_bytes(b"x")
(tmp_path / "Matrix (1999) [tmdbid-603].cs.srt").write_bytes(b"x")
(tmp_path / "Matrix (1999) [tmdbid-603].en.forced.srt").write_bytes(b"x")
found = {s.path.name: s for s in find_subtitles(video)}
assert set(found) == {
"Matrix (1999) [tmdbid-603].srt",
"Matrix (1999) [tmdbid-603].cs.srt",
"Matrix (1999) [tmdbid-603].en.forced.srt",
}
assert found["Matrix (1999) [tmdbid-603].srt"].language is None
assert found["Matrix (1999) [tmdbid-603].cs.srt"].language == "cs"
assert found["Matrix (1999) [tmdbid-603].en.forced.srt"].language == "en"
assert found["Matrix (1999) [tmdbid-603].en.forced.srt"].flag == "forced"
def test_ignores_unrelated_and_overlapping_stem(self, tmp_path):
video = _video(tmp_path, "Matrix.mkv")
(tmp_path / "Matrix Reloaded.srt").write_bytes(b"x") # overlapping prefix
(tmp_path / "Matrix.nfo").write_bytes(b"x") # not a subtitle ext
(tmp_path / "poster.jpg").write_bytes(b"x")
assert find_subtitles(video) == []
def test_ignores_other_movies_subtitle(self, tmp_path):
video = _video(tmp_path, "Matrix.mkv")
(tmp_path / "Other Movie.cs.srt").write_bytes(b"x")
assert find_subtitles(video) == []
def test_missing_folder_is_empty(self, tmp_path):
assert find_subtitles(tmp_path / "nope" / "video.mkv") == []
def test_label_property(self):
assert SubtitleFile(path=None, language="cs").label == "cs"
assert (
SubtitleFile(path=None, language="cs", flag="forced").label == "cs (forced)"
)
assert SubtitleFile(path=None).label == "?"
class TestAttachSubtitle:
def test_copies_and_names_to_match_video(self, tmp_path):
video = _video(tmp_path)
source = tmp_path / "downloaded.srt"
source.write_bytes(b"subtitle content")
target = attach_subtitle(video, source, language="cs")
assert target == tmp_path / "Matrix (1999) [tmdbid-603].cs.srt"
assert target.read_bytes() == b"subtitle content"
assert source.exists() # copy, not move
def test_move_removes_source(self, tmp_path):
video = _video(tmp_path)
source = tmp_path / "downloaded.srt"
source.write_bytes(b"x")
target = attach_subtitle(video, source, language="en", move=True)
assert target.exists()
assert not source.exists()
def test_overwrites_same_language_slot(self, tmp_path):
video = _video(tmp_path)
old = tmp_path / "Matrix (1999) [tmdbid-603].cs.srt"
old.write_bytes(b"old")
source = tmp_path / "new.srt"
source.write_bytes(b"new")
target = attach_subtitle(video, source, language="cs")
assert target == old
assert target.read_bytes() == b"new"
def test_rejects_unsupported_extension(self, tmp_path):
video = _video(tmp_path)
source = tmp_path / "notes.txt"
source.write_bytes(b"x")
with pytest.raises(ValueError):
attach_subtitle(video, source)
class TestRenameSubtitlesWith:
def test_moves_every_sidecar_preserving_lang_and_flag(self, tmp_path):
old_video = _video(tmp_path, "Matrix.mkv")
(tmp_path / "Matrix.srt").write_bytes(b"x")
(tmp_path / "Matrix.cs.srt").write_bytes(b"x")
(tmp_path / "Matrix.en.forced.srt").write_bytes(b"x")
new_video = tmp_path / "Matrix (1999) [tmdbid-603].mkv"
moved = rename_subtitles_with(old_video, new_video)
names = {p.name for p in moved}
assert names == {
"Matrix (1999) [tmdbid-603].srt",
"Matrix (1999) [tmdbid-603].cs.srt",
"Matrix (1999) [tmdbid-603].en.forced.srt",
}
for name in names:
assert (tmp_path / name).exists()
assert not (tmp_path / "Matrix.srt").exists()
def test_moves_across_folders(self, tmp_path):
old_dir = tmp_path / "Filmy"
old_dir.mkdir()
old_video = old_dir / "Matrix.mkv"
old_video.write_bytes(b"x")
(old_dir / "Matrix.cs.srt").write_bytes(b"x")
new_dir = tmp_path / "Kids"
new_dir.mkdir()
new_video = new_dir / "Matrix (1999).mkv"
moved = rename_subtitles_with(old_video, new_video)
assert moved == [new_dir / "Matrix (1999).cs.srt"]
assert (new_dir / "Matrix (1999).cs.srt").exists()
assert not (old_dir / "Matrix.cs.srt").exists()
def test_noop_when_path_unchanged(self, tmp_path):
video = _video(tmp_path, "Matrix.mkv")
(tmp_path / "Matrix.cs.srt").write_bytes(b"x")
assert rename_subtitles_with(video, video) == []
assert (tmp_path / "Matrix.cs.srt").exists()
def test_no_subtitles_is_noop(self, tmp_path):
old_video = _video(tmp_path, "Matrix.mkv")
new_video = tmp_path / "Matrix (1999).mkv"
assert rename_subtitles_with(old_video, new_video) == []