from pathlib import Path import pytest from serato_doctor.crate_parser import ( classify_crate, clean_path, load_crate, parse_crate, parse_crates, path_markers, ) from serato_doctor.models.crate import CrateKind @pytest.mark.parametrize( ("artifact", "expected"), [ ("song.mp漳", "song.mp3"), ("song.m4愠", "song.m4a"), ("song.wa瘠", "song.wav"), ("song.ai映", "song.aif"), ], ) def test_clean_path_repairs_known_extension_artifacts(artifact, expected): assert clean_path(artifact) == expected def test_parse_crate_extracts_references(tmp_path): crate_path = tmp_path / "House.crate" crate_text = ( "header" "Users/sample-user/OneDrive/Jukebox/House/First.mp漳牴k" "metadata" "Users/sample-user/OneDrive/Jukebox/House/Second.m4愠otrk" ) crate_path.write_bytes(crate_text.encode("utf-16-le")) crate = load_crate(crate_path) assert crate.path == crate_path assert [reference.filename for reference in crate.references] == [ "First.mp3", "Second.m4a", ] assert parse_crate(crate_path) == list(crate.references) def test_parse_crate_ignores_record_without_stop_marker(tmp_path): crate_path = Path(tmp_path) / "Incomplete.crate" crate_path.write_bytes( "Users/sample-user/OneDrive/Jukebox/House/Incomplete.mp3".encode( "utf-16-le" ) ) assert parse_crate(crate_path) == [] def test_parse_crate_uses_configured_reference_root(tmp_path): crate_path = tmp_path / "Migrated.crate" crate_path.write_bytes( "Archive/Old Library/House/Track.mp3otrk".encode("utf-16-le") ) references = parse_crate(crate_path, [Path("/Archive/Old Library")]) assert references[0].path == Path("/Archive/Old Library/House/Track.mp3") def test_default_path_markers_do_not_contain_a_username(): assert path_markers([]) == ("Users/", "Volumes/") def test_parse_crates_reuses_configured_roots_for_every_crate(tmp_path): for name in ("First", "Second"): (tmp_path / f"{name}.crate").write_bytes( f"Archive/Jukebox/{name}.mp3otrk".encode("utf-16-le") ) references = parse_crates( tmp_path, (root for root in [Path("/Archive/Jukebox")]) ) assert {reference.filename for reference in references} == { "First.mp3", "Second.mp3", } @pytest.mark.parametrize( ("relative_path", "expected"), [ ("_Serato_/Subcrates/House.crate", CrateKind.STATIC), ("_Serato_/Smartcrates/Warmup.crate", CrateKind.SMART), ("_Serato_/Subcrates/Compatible by key.crate", CrateKind.SMART), ("fixtures/Unknown.crate", CrateKind.UNKNOWN), ], ) def test_classify_crate_uses_provenance_and_known_dynamic_name( tmp_path, relative_path, expected ): assert classify_crate(tmp_path / relative_path) is expected