"""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) == []