From 6c461ed55fa36231a41570141dbba11fd8eeb7be Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Mon, 7 Apr 2025 12:30:54 -0400 Subject: [PATCH] [tests] Simplify view tests to not mess with time --- tests/scrobbles_tests/conftest.py | 12 ++- tests/scrobbles_tests/test_views.py | 142 ++++++++++++++++++++++------ vrobbler/apps/scrobbles/models.py | 7 +- 3 files changed, 125 insertions(+), 36 deletions(-) diff --git a/tests/scrobbles_tests/conftest.py b/tests/scrobbles_tests/conftest.py index 9725ec4..488393d 100644 --- a/tests/scrobbles_tests/conftest.py +++ b/tests/scrobbles_tests/conftest.py @@ -4,8 +4,9 @@ import pytest from django.contrib.auth import get_user_model from rest_framework.authtoken.models import Token -from scrobbles.models import Scrobble from boardgames.models import BoardGame +from music.models import Track, Artist +from scrobbles.models import Scrobble User = get_user_model() @@ -27,6 +28,15 @@ def boardgame_scrobble(): ) +@pytest.fixture +def test_track(): + Track.objects.create( + title="Emotion", + artist=Artist.objects.create(name="Carly Rae Jepsen"), + run_time_seconds=60, + ) + + class MopidyRequest: name = "Same in the End" artist = "Sublime" diff --git a/tests/scrobbles_tests/test_views.py b/tests/scrobbles_tests/test_views.py index df35218..86290e6 100644 --- a/tests/scrobbles_tests/test_views.py +++ b/tests/scrobbles_tests/test_views.py @@ -76,9 +76,26 @@ def test_scrobble_mopidy_track( assert scrobble.media_obj.title == "Same in the End" -@pytest.mark.skip(reason="Allmusic API is unstable") +# @pytest.mark.skip(reason="Allmusic API is unstable") @pytest.mark.django_db +@patch("music.utils.lookup_artist_from_mb", return_value={}) +@patch( + "music.utils.lookup_album_dict_from_mb", + return_value={"year": "1999", "mb_group_id": 1}, +) +@patch("music.utils.lookup_track_from_mb", return_value={}) +@patch("music.models.lookup_artist_from_tadb", return_value={}) +@patch("music.models.lookup_album_from_tadb", return_value={"year": "1999"}) +@patch("music.models.Album.fetch_artwork", return_value=None) +@patch("music.models.Album.scrape_allmusic", return_value=None) def test_scrobble_mopidy_same_track_different_album( + mock_lookup_artist, + mock_lookup_album, + mock_lookup_track, + mock_lookup_artist_tadb, + mock_lookup_album_tadb, + mock_fetch_artwork, + mock_scrape_allmusic, client, mopidy_track, mopidy_track_diff_album_request_data, @@ -177,38 +194,101 @@ def test_scrobble_jellyfin_track( assert scrobble.media_obj.__class__ == Track assert scrobble.media_obj.title == "Emotion" - with time_machine.travel(datetime(2024, 1, 14, 12, 0, 58)): - jellyfin_track.request_data["UtcTimestamp"] = timezone.now().strftime( - "%Y-%m-%d %H:%M:%S" - ) - response = client.post( - url, - jellyfin_track.request_json, - content_type="application/json", - headers=headers, - ) - assert response.status_code == 200 - assert response.data == {"scrobble_id": 1} +@pytest.mark.django_db +@patch("music.utils.lookup_artist_from_mb", return_value={}) +@patch( + "music.utils.lookup_album_dict_from_mb", + return_value={"year": "1999", "mb_group_id": 1}, +) +@patch("music.utils.lookup_track_from_mb", return_value={}) +@patch("music.models.lookup_artist_from_tadb", return_value={}) +@patch("music.models.lookup_album_from_tadb", return_value={"year": "1999"}) +@patch("music.models.Album.fetch_artwork", return_value=None) +@patch("music.models.Album.scrape_allmusic", return_value=None) +def test_scrobble_jellyfin_track_update( + mock_lookup_artist, + mock_lookup_album, + mock_lookup_track, + mock_lookup_artist_tadb, + mock_lookup_album_tadb, + mock_fetch_artwork, + mock_scrape_allmusic, + test_track, + client, + jellyfin_track, + valid_auth_token, +): + Scrobble.objects.create( + timestamp=timezone.now() - timedelta(minutes=0.5), + track=Track.objects.first(), + user_id=1, + ) + url = reverse("scrobbles:jellyfin-webhook") + headers = {"Authorization": f"Token {valid_auth_token}"} - scrobble = Scrobble.objects.get(id=1) - assert scrobble.media_obj.__class__ == Track - assert scrobble.media_obj.title == "Emotion" + jellyfin_track.request_data["UtcTimestamp"] = timezone.now().strftime( + "%Y-%m-%d %H:%M:%S" + ) + response = client.post( + url, + jellyfin_track.request_json, + content_type="application/json", + headers=headers, + ) - with time_machine.travel(datetime(2024, 1, 14, 12, 1, 10)): - jellyfin_track.request_data["UtcTimestamp"] = timezone.now().strftime( - "%Y-%m-%d %H:%M:%S" - ) - response = client.post( - url, - jellyfin_track.request_json, - content_type="application/json", - headers=headers, - ) + assert response.status_code == 200 + assert response.data == {"scrobble_id": 1} - assert response.status_code == 200 - assert response.data == {"scrobble_id": 2} + scrobble = Scrobble.objects.get(id=1) + assert scrobble.media_obj.__class__ == Track + assert scrobble.media_obj.title == "Emotion" - scrobble = Scrobble.objects.get(id=1) - assert scrobble.media_obj.__class__ == Track - assert scrobble.media_obj.title == "Emotion" + +@pytest.mark.django_db +@patch("music.utils.lookup_artist_from_mb", return_value={}) +@patch( + "music.utils.lookup_album_dict_from_mb", + return_value={"year": "1999", "mb_group_id": 1}, +) +@patch("music.utils.lookup_track_from_mb", return_value={}) +@patch("music.models.lookup_artist_from_tadb", return_value={}) +@patch("music.models.lookup_album_from_tadb", return_value={"year": "1999"}) +@patch("music.models.Album.fetch_artwork", return_value=None) +@patch("music.models.Album.scrape_allmusic", return_value=None) +def test_scrobble_jellyfin_track_create_new( + mock_lookup_artist, + mock_lookup_album, + mock_lookup_track, + mock_lookup_artist_tadb, + mock_lookup_album_tadb, + mock_fetch_artwork, + mock_scrape_allmusic, + test_track, + client, + jellyfin_track, + valid_auth_token, +): + url = reverse("scrobbles:jellyfin-webhook") + headers = {"Authorization": f"Token {valid_auth_token}"} + Scrobble.objects.create( + timestamp=timezone.now() - timedelta(minutes=1), + track=Track.objects.first(), + user_id=1, + ) + jellyfin_track.request_data["UtcTimestamp"] = timezone.now().strftime( + "%Y-%m-%d %H:%M:%S" + ) + response = client.post( + url, + jellyfin_track.request_json, + content_type="application/json", + headers=headers, + ) + + assert response.status_code == 200 + assert response.data == {"scrobble_id": 2} + + scrobble = Scrobble.objects.get(id=1) + assert scrobble.media_obj.__class__ == Track + assert scrobble.media_obj.title == "Emotion" diff --git a/vrobbler/apps/scrobbles/models.py b/vrobbler/apps/scrobbles/models.py index a99f852..87f14b6 100644 --- a/vrobbler/apps/scrobbles/models.py +++ b/vrobbler/apps/scrobbles/models.py @@ -1034,7 +1034,6 @@ class Scrobble(TimeStampedModel): "scrobble_data": scrobble_data, }, ) - scrobble_data["playback_status"] = scrobble_data.pop("status", None) # If it's marked as stopped, send it through our update mechanism, which will complete it if scrobble and ( @@ -1140,9 +1139,9 @@ class Scrobble(TimeStampedModel): if existing_locations := location.in_proximity(named=True): existing_location = existing_locations.first() ts = int(pendulum.now().timestamp()) - scrobble.log[ts] = ( - f"Location {location.id} too close to this scrobble" - ) + scrobble.log[ + ts + ] = f"Location {location.id} too close to this scrobble" scrobble.save(update_fields=["log"]) logger.info( f"[scrobbling] finished - found existing named location",