Files
vrobbler/tests/music_tests/test_report_mismatched_metadata.py

146 lines
5.1 KiB
Python

import csv
from unittest.mock import patch
import pytest
from django.contrib.auth import get_user_model
from django.core.management import call_command
from music.models import Album, Artist, Track
from scrobbles.models import Scrobble
def _write_fix_csv(path, track_ids):
with open(path, "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(
[
"track_id",
"track_artist_name",
"track_album_name",
"raw_artist",
"raw_album",
"source",
"mismatch",
]
)
for track_id in track_ids:
writer.writerow([track_id, "", "", "", "", "", ""])
def _scrobble(user, track, raw_data):
return Scrobble.objects.create(
track=track,
media_type="Track",
user=user,
log={"raw_data": raw_data},
)
@pytest.mark.django_db
def test_report_writes_mismatch_csv(tmp_path):
user = get_user_model().objects.create(email="report@example.com")
wrong = Artist.objects.create(name="Wrong Artist")
track = Track.objects.create(title="Song", artist_fk=wrong)
track.artists.add(wrong)
_scrobble(user, track, {"artist": "Right Artist", "musicbrainz_artist_id": "mb-1"})
out = tmp_path / "report.csv"
call_command("report_mismatched_metadata", file_path=str(out))
with open(out) as f:
rows = list(csv.DictReader(f))
assert len(rows) == 1
assert rows[0]["track_id"] == str(track.id)
assert "artist" in rows[0]["mismatch"]
assert rows[0]["raw_artist"] == "Right Artist"
@pytest.mark.django_db
def test_fix_file_commits_resolved_artists(tmp_path):
user = get_user_model().objects.create(email="fix@example.com")
wrong = Artist.objects.create(name="Wrong Artist")
right = Artist.objects.create(name="Right Artist")
track = Track.objects.create(title="Song", artist_fk=wrong)
track.artists.add(wrong)
_scrobble(user, track, {"artist": "Right Artist", "musicbrainz_artist_id": "mb-1"})
fix = tmp_path / "fix.csv"
_write_fix_csv(fix, [track.id])
call_command("report_mismatched_metadata", fix_file=str(fix), commit=True)
track.refresh_from_db()
assert list(track.artists.all().values_list("name", flat=True)) == ["Right Artist"]
assert track.artist_fk.name == "Right Artist"
assert "metadata-fixed" in track.tags.names()
assert not Artist.objects.filter(name="Wrong Artist").exists()
@pytest.mark.django_db
def test_fix_file_dry_run_makes_no_changes(tmp_path):
user = get_user_model().objects.create(email="dry-fix@example.com")
wrong = Artist.objects.create(name="Wrong Artist")
right = Artist.objects.create(name="Right Artist")
track = Track.objects.create(title="Song", artist_fk=wrong)
track.artists.add(wrong)
_scrobble(user, track, {"artist": "Right Artist", "musicbrainz_artist_id": "mb-1"})
fix = tmp_path / "fix.csv"
_write_fix_csv(fix, [track.id])
call_command("report_mismatched_metadata", fix_file=str(fix))
track.refresh_from_db()
assert sorted(track.artists.all().values_list("name", flat=True)) == [
"Wrong Artist"
]
assert not track.tags.filter(name="metadata-fixed").exists()
@pytest.mark.django_db
def test_fix_file_only_touches_listed_tracks(tmp_path):
user = get_user_model().objects.create(email="subset@example.com")
wrong = Artist.objects.create(name="Wrong Artist")
keep = Artist.objects.create(name="Keep Artist")
track_a = Track.objects.create(title="Song A", artist_fk=wrong)
track_a.artists.add(wrong)
track_b = Track.objects.create(title="Song B", artist_fk=wrong)
track_b.artists.add(wrong)
_scrobble(
user, track_a, {"artist": "Right Artist", "musicbrainz_artist_id": "mb-1"}
)
_scrobble(
user, track_b, {"artist": "Right Artist", "musicbrainz_artist_id": "mb-1"}
)
fix = tmp_path / "fix.csv"
_write_fix_csv(fix, [track_a.id])
call_command("report_mismatched_metadata", fix_file=str(fix), commit=True)
track_a.refresh_from_db()
track_b.refresh_from_db()
assert list(track_a.artists.all().values_list("name", flat=True)) == [
"Right Artist"
]
assert sorted(track_b.artists.all().values_list("name", flat=True)) == [
"Wrong Artist"
]
@pytest.mark.django_db
@patch("music.models.Album.find_or_create")
def test_fix_file_fixes_album(mock_album, tmp_path):
user = get_user_model().objects.create(email="album@example.com")
artist = Artist.objects.create(name="Right Artist")
old_album = Album.objects.create(name="Old Album", album_artist=artist)
new_album = Album.objects.create(name="New Album", album_artist=artist)
mock_album.return_value = new_album
track = Track.objects.create(title="Song", artist_fk=artist, album=old_album)
track.artists.add(artist)
_scrobble(user, track, {"Artist": "Right Artist", "Album": "New Album"})
fix = tmp_path / "fix.csv"
_write_fix_csv(fix, [track.id])
call_command("report_mismatched_metadata", fix_file=str(fix), commit=True)
track.refresh_from_db()
assert track.album == new_album
mock_album.assert_called_once_with("New Album", "Right Artist")