162 lines
6.0 KiB
Python
162 lines
6.0 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) == []
|