from datetime import datetime import pytz from django.contrib.auth import get_user_model from django.utils import timezone from music.models import Artist, Track from scrobbles.models import Scrobble from vrobbler.apps.scrobbles.utils import ( deduplicate_scrobbles, timestamp_user_tz_to_utc, ) User = get_user_model() def test_timestamp_user_tz_to_utc(): timestamp = timestamp_user_tz_to_utc(1685561082, pytz.timezone("US/Eastern")) assert timestamp == datetime(2023, 5, 31, 23, 24, 42, tzinfo=pytz.utc) def _make_track(): artist = Artist.objects.create(name="Carly Rae Jepsen") return Track.objects.create( title="Emotion", artist_fk=artist, base_run_time_seconds=60, ) def test_deduplicate_scrobbles_removes_exact_duplicates(db): user = User.objects.create(email="dup@example.com") track = _make_track() timestamp = timezone.now().replace(microsecond=0) stop_timestamp = timestamp + timezone.timedelta(seconds=60) for _ in range(3): Scrobble.objects.create( user=user, track=track, media_type="Track", timestamp=timestamp, stop_timestamp=stop_timestamp, ) count = deduplicate_scrobbles(commit=True) assert count == 2 assert Scrobble.objects.filter(user=user, track=track).count() == 1 def test_deduplicate_scrobbles_keeps_different_media(db): user = User.objects.create(email="media@example.com") track = _make_track() other_track = Track.objects.create( title="Other", artist_fk=Artist.objects.create(name="Someone Else"), base_run_time_seconds=60, ) timestamp = timezone.now().replace(microsecond=0) stop_timestamp = timestamp + timezone.timedelta(seconds=60) Scrobble.objects.create( user=user, track=track, media_type="Track", timestamp=timestamp, stop_timestamp=stop_timestamp, ) Scrobble.objects.create( user=user, track=other_track, media_type="Track", timestamp=timestamp, stop_timestamp=stop_timestamp, ) count = deduplicate_scrobbles(commit=True) assert count == 0 assert Scrobble.objects.count() == 2 def test_deduplicate_scrobbles_keeps_different_timestamps(db): user = User.objects.create(email="time@example.com") track = _make_track() timestamp = timezone.now().replace(microsecond=0) stop_timestamp = timestamp + timezone.timedelta(seconds=60) Scrobble.objects.create( user=user, track=track, media_type="Track", timestamp=timestamp, stop_timestamp=stop_timestamp, ) Scrobble.objects.create( user=user, track=track, media_type="Track", timestamp=timestamp + timezone.timedelta(hours=1), stop_timestamp=stop_timestamp + timezone.timedelta(hours=1), ) count = deduplicate_scrobbles(commit=True) assert count == 0 assert Scrobble.objects.count() == 2 def test_deduplicate_scrobbles_dry_run_does_not_delete(db): user = User.objects.create(email="dry@example.com") track = _make_track() timestamp = timezone.now().replace(microsecond=0) stop_timestamp = timestamp + timezone.timedelta(seconds=60) for _ in range(2): Scrobble.objects.create( user=user, track=track, media_type="Track", timestamp=timestamp, stop_timestamp=stop_timestamp, ) count = deduplicate_scrobbles(commit=False) assert count == 1 assert Scrobble.objects.filter(user=user, track=track).count() == 2 def test_deduplicate_scrobbles_filters_by_media_type(db): user = User.objects.create(email="filter@example.com") track = _make_track() timestamp = timezone.now().replace(microsecond=0) stop_timestamp = timestamp + timezone.timedelta(seconds=60) for _ in range(2): Scrobble.objects.create( user=user, track=track, media_type="Track", timestamp=timestamp, stop_timestamp=stop_timestamp, ) count = deduplicate_scrobbles(commit=True, media_type="Video") assert count == 0 assert Scrobble.objects.filter(user=user, track=track).count() == 2