Import existing LinTunes project
Snapshot of the existing codebase before working through the TASKS.md backlog. Real library data (data/) and the iTunes import fixture (itunes-test-library/) are gitignored. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
118
tests/test_file_importer.py
Normal file
118
tests/test_file_importer.py
Normal file
@ -0,0 +1,118 @@
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from lintunes import tagging
|
||||
from lintunes.models import Library
|
||||
from lintunes.library_manager import LibraryManager
|
||||
from lintunes.importers import file_importer
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def manager(qapp, tmp_path):
|
||||
return LibraryManager(Library(), tmp_path / "data")
|
||||
|
||||
|
||||
class TestOrganizedDestination:
|
||||
def test_artist_album_layout(self):
|
||||
dest = file_importer.organized_destination(
|
||||
Path("/music"), {"artist": "The Band", "album": "Hits"}, "song.mp3")
|
||||
assert dest == Path("/music/The Band/Hits/song.mp3")
|
||||
|
||||
def test_album_artist_preferred(self):
|
||||
dest = file_importer.organized_destination(
|
||||
Path("/music"),
|
||||
{"artist": "Feat Guy", "album_artist": "Main Act", "album": "LP"},
|
||||
"song.mp3")
|
||||
assert dest == Path("/music/Main Act/LP/song.mp3")
|
||||
|
||||
def test_missing_tags(self):
|
||||
dest = file_importer.organized_destination(Path("/music"), {}, "song.mp3")
|
||||
assert dest == Path("/music/Unknown Artist/Unknown Album/song.mp3")
|
||||
|
||||
def test_sanitizes_separators(self):
|
||||
dest = file_importer.organized_destination(
|
||||
Path("/music"), {"artist": "AC/DC", "album": "Back: In Black?"},
|
||||
"song.mp3")
|
||||
assert dest == Path("/music/AC_DC/Back_ In Black_/song.mp3")
|
||||
|
||||
|
||||
class TestImportFile:
|
||||
def test_copies_and_adds_track(self, manager, mp3_file, tmp_path):
|
||||
tagging.write_tags(mp3_file, {"name": "My Song", "artist": "Artist X",
|
||||
"album": "Album Y"})
|
||||
music_dir = tmp_path / "music"
|
||||
track = file_importer.import_file(mp3_file, music_dir, manager)
|
||||
|
||||
assert track is not None
|
||||
expected = music_dir / "Artist X" / "Album Y" / "test.mp3"
|
||||
assert Path(track.location) == expected
|
||||
assert expected.exists()
|
||||
assert track.name == "My Song"
|
||||
assert track.date_added
|
||||
assert track.track_id in manager.library.tracks
|
||||
|
||||
def test_reimport_same_file_is_deduped(self, manager, mp3_file, tmp_path):
|
||||
music_dir = tmp_path / "music"
|
||||
track1 = file_importer.import_file(mp3_file, music_dir, manager)
|
||||
track2 = file_importer.import_file(mp3_file, music_dir, manager)
|
||||
assert track1.track_id == track2.track_id
|
||||
assert len(manager.library.tracks) == 1
|
||||
|
||||
def test_name_collision_gets_suffix(self, manager, mp3_file, tmp_path):
|
||||
music_dir = tmp_path / "music"
|
||||
dest = music_dir / "Unknown Artist" / "Unknown Album" / "test.mp3"
|
||||
dest.parent.mkdir(parents=True)
|
||||
dest.write_bytes(b"placeholder different file")
|
||||
track = file_importer.import_file(mp3_file, music_dir, manager)
|
||||
assert Path(track.location) == dest.with_stem("test 1")
|
||||
|
||||
def test_rejects_non_audio(self, manager, tmp_path):
|
||||
text = tmp_path / "notes.txt"
|
||||
text.write_text("hello")
|
||||
assert file_importer.import_file(text, tmp_path / "music", manager) is None
|
||||
|
||||
def test_import_paths_adds_to_playlist(self, manager, mp3_file, tmp_path):
|
||||
playlist = manager.create_playlist("Drops")
|
||||
imported = file_importer.import_paths(
|
||||
[mp3_file], tmp_path / "music", manager, playlist.persistent_id)
|
||||
assert len(imported) == 1
|
||||
assert playlist.track_ids == [imported[0].track_id]
|
||||
|
||||
|
||||
class TestLibraryManager:
|
||||
def test_playlist_crud_and_persistence(self, manager):
|
||||
folder = manager.create_folder("F")
|
||||
playlist = manager.create_playlist("P", folder.persistent_id)
|
||||
manager.rename_playlist(playlist.persistent_id, "P2")
|
||||
assert manager.library.playlists[playlist.persistent_id].name == "P2"
|
||||
manager.flush()
|
||||
path = manager.data_dir / "playlists" / f"{playlist.persistent_id}.json"
|
||||
assert path.exists()
|
||||
manager.delete_playlist(folder.persistent_id) # recursive
|
||||
assert manager.library.playlists == {}
|
||||
manager.flush()
|
||||
assert not path.exists()
|
||||
|
||||
def test_move_tracks_in_playlist(self, manager):
|
||||
from lintunes.models import Track
|
||||
for i in range(1, 6):
|
||||
manager.add_track(Track(track_id=i, name=f"t{i}"))
|
||||
playlist = manager.create_playlist("P")
|
||||
manager.add_tracks_to_playlist(playlist.persistent_id, [1, 2, 3, 4, 5])
|
||||
|
||||
# Move rows 0,1 (tracks 1,2) so the block starts at manual row 4
|
||||
manager.move_tracks_in_playlist(playlist.persistent_id, [0, 1], 4)
|
||||
assert playlist.track_ids == [3, 4, 1, 2, 5]
|
||||
|
||||
# Move last row (track 5) to the top
|
||||
manager.move_tracks_in_playlist(playlist.persistent_id, [4], 0)
|
||||
assert playlist.track_ids == [5, 3, 4, 1, 2]
|
||||
|
||||
def test_record_play(self, manager):
|
||||
from lintunes.models import Track
|
||||
manager.add_track(Track(track_id=7, name="x", play_count=3))
|
||||
manager.record_play(7)
|
||||
track = manager.library.tracks[7]
|
||||
assert track.play_count == 4
|
||||
assert track.play_date_utc is not None
|
||||
Reference in New Issue
Block a user