[charts] Clean up, add tests and signals
This commit is contained in:
268
vrobbler/apps/charts/tests/test_utils.py
Normal file
268
vrobbler/apps/charts/tests/test_utils.py
Normal file
@ -0,0 +1,268 @@
|
||||
import datetime
|
||||
|
||||
import pytest
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.utils import timezone
|
||||
|
||||
from charts.models import ChartRecord
|
||||
from charts.utils import build_charts
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user(db):
|
||||
return User.objects.create_user(username="charttester", password="testpass123")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def scrobble_data(user, db):
|
||||
from scrobbles.models import Scrobble
|
||||
from music.models import Track, Artist, Album
|
||||
|
||||
artist = Artist.objects.create(name="Test Artist")
|
||||
album = Album.objects.create(name="Test Album", album_artist=artist)
|
||||
track = Track.objects.create(title="Test Track", artist=artist, album=album)
|
||||
|
||||
return {
|
||||
"user": user,
|
||||
"track": track,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_build_daily_charts_creates_daily_record(user, scrobble_data):
|
||||
from scrobbles.models import Scrobble
|
||||
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=scrobble_data["track"],
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 10, 0)),
|
||||
)
|
||||
|
||||
build_charts(user, year=2024, month=3, day=15)
|
||||
|
||||
daily = ChartRecord.objects.filter(
|
||||
user=user,
|
||||
year=2024,
|
||||
month=3,
|
||||
day=15,
|
||||
week__isnull=True,
|
||||
track__isnull=False,
|
||||
)
|
||||
assert daily.exists()
|
||||
assert daily.first().track == scrobble_data["track"]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_build_monthly_charts_creates_monthly_record(user, scrobble_data):
|
||||
from scrobbles.models import Scrobble
|
||||
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=scrobble_data["track"],
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 10, 0)),
|
||||
)
|
||||
|
||||
build_charts(user, year=2024, month=3)
|
||||
|
||||
monthly = ChartRecord.objects.filter(
|
||||
user=user,
|
||||
year=2024,
|
||||
month=3,
|
||||
week__isnull=True,
|
||||
day__isnull=True,
|
||||
track__isnull=False,
|
||||
)
|
||||
assert monthly.exists()
|
||||
assert monthly.first().track == scrobble_data["track"]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_build_weekly_charts_creates_weekly_record(user, scrobble_data):
|
||||
from scrobbles.models import Scrobble
|
||||
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=scrobble_data["track"],
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 10, 0)),
|
||||
)
|
||||
|
||||
build_charts(user, year=2024, week=11)
|
||||
|
||||
weekly = ChartRecord.objects.filter(
|
||||
user=user,
|
||||
year=2024,
|
||||
week=11,
|
||||
month__isnull=True,
|
||||
day__isnull=True,
|
||||
track__isnull=False,
|
||||
)
|
||||
assert weekly.exists()
|
||||
assert weekly.first().track == scrobble_data["track"]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_build_yearly_charts_creates_yearly_record(user, scrobble_data):
|
||||
from scrobbles.models import Scrobble
|
||||
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=scrobble_data["track"],
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 10, 0)),
|
||||
)
|
||||
|
||||
build_charts(user, year=2024)
|
||||
|
||||
yearly = ChartRecord.objects.filter(
|
||||
user=user,
|
||||
year=2024,
|
||||
month__isnull=True,
|
||||
week__isnull=True,
|
||||
day__isnull=True,
|
||||
track__isnull=False,
|
||||
)
|
||||
assert yearly.exists()
|
||||
assert yearly.first().track == scrobble_data["track"]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_build_charts_ranks_by_count(user, scrobble_data):
|
||||
from scrobbles.models import Scrobble
|
||||
from music.models import Track, Artist
|
||||
|
||||
track1 = scrobble_data["track"]
|
||||
track2 = Track.objects.create(
|
||||
title="Test Track 2",
|
||||
artist=track1.artist,
|
||||
album=track1.album,
|
||||
)
|
||||
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=track1,
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 10, 0)),
|
||||
)
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=track1,
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 11, 0)),
|
||||
)
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=track2,
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 12, 0)),
|
||||
)
|
||||
|
||||
build_charts(user, year=2024, month=3, day=15)
|
||||
|
||||
daily = ChartRecord.objects.filter(
|
||||
user=user,
|
||||
year=2024,
|
||||
month=3,
|
||||
day=15,
|
||||
track__isnull=False,
|
||||
).order_by("rank")
|
||||
|
||||
assert daily.count() == 2
|
||||
assert daily[0].track == track1
|
||||
assert daily[0].rank == 1
|
||||
assert daily[0].count == 2
|
||||
assert daily[1].track == track2
|
||||
assert daily[1].rank == 2
|
||||
assert daily[1].count == 1
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_build_daily_charts_deletes_existing_daily_record(user, scrobble_data):
|
||||
from scrobbles.models import Scrobble
|
||||
from music.models import Track, Artist
|
||||
|
||||
track1 = scrobble_data["track"]
|
||||
track2 = Track.objects.create(
|
||||
title="Test Track 2",
|
||||
artist=track1.artist,
|
||||
album=track1.album,
|
||||
)
|
||||
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=track1,
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 10, 0)),
|
||||
)
|
||||
|
||||
build_charts(user, year=2024, month=3, day=15)
|
||||
assert ChartRecord.objects.filter(
|
||||
user=user, year=2024, month=3, day=15, track=track1
|
||||
).exists()
|
||||
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=track2,
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 11, 0)),
|
||||
)
|
||||
|
||||
build_charts(user, year=2024, month=3, day=15)
|
||||
|
||||
daily = ChartRecord.objects.filter(
|
||||
user=user,
|
||||
year=2024,
|
||||
month=3,
|
||||
day=15,
|
||||
track__isnull=False,
|
||||
)
|
||||
assert daily.count() == 2
|
||||
assert daily.filter(track=track1).exists()
|
||||
assert daily.filter(track=track2).exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_build_monthly_charts_deletes_existing_monthly_record(user, scrobble_data):
|
||||
from scrobbles.models import Scrobble
|
||||
from music.models import Track, Artist
|
||||
|
||||
track1 = scrobble_data["track"]
|
||||
track2 = Track.objects.create(
|
||||
title="Test Track 2",
|
||||
artist=track1.artist,
|
||||
album=track1.album,
|
||||
)
|
||||
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=track1,
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 15, 10, 0)),
|
||||
)
|
||||
|
||||
build_charts(user, year=2024, month=3)
|
||||
|
||||
ChartRecord.objects.filter(user=user, year=2024, month=3, track=track1).delete()
|
||||
|
||||
Scrobble.objects.create(
|
||||
user=user,
|
||||
track=track2,
|
||||
played_to_completion=True,
|
||||
timestamp=timezone.make_aware(datetime.datetime(2024, 3, 16, 11, 0)),
|
||||
)
|
||||
|
||||
build_charts(user, year=2024, month=3)
|
||||
|
||||
monthly = ChartRecord.objects.filter(
|
||||
user=user,
|
||||
year=2024,
|
||||
month=3,
|
||||
week__isnull=True,
|
||||
day__isnull=True,
|
||||
track__isnull=False,
|
||||
)
|
||||
assert monthly.count() == 2
|
||||
@ -76,9 +76,9 @@ def build_charts(
|
||||
]
|
||||
|
||||
period_filter = Q(year=year)
|
||||
if day:
|
||||
if day and month:
|
||||
period_filter = (
|
||||
period_filter & Q(day=day) & Q(week__isnull=True) & Q(month__isnull=True)
|
||||
period_filter & Q(day=day) & Q(month=month) & Q(week__isnull=True)
|
||||
)
|
||||
elif week:
|
||||
period_filter = (
|
||||
@ -88,6 +88,13 @@ def build_charts(
|
||||
period_filter = (
|
||||
period_filter & Q(month=month) & Q(week__isnull=True) & Q(day__isnull=True)
|
||||
)
|
||||
else:
|
||||
period_filter = (
|
||||
period_filter
|
||||
& Q(month__isnull=True)
|
||||
& Q(week__isnull=True)
|
||||
& Q(day__isnull=True)
|
||||
)
|
||||
|
||||
ChartRecord.objects.filter(period_filter, user=user).delete()
|
||||
|
||||
@ -311,6 +318,7 @@ def build_daily_charts(
|
||||
build_charts(
|
||||
user=user,
|
||||
year=year,
|
||||
month=month,
|
||||
day=day,
|
||||
media_types=media_types,
|
||||
)
|
||||
@ -322,9 +330,7 @@ def build_charts_since(user, media_types: Optional[list] = None) -> None:
|
||||
Scrobble = apps.get_model("scrobbles", "Scrobble")
|
||||
|
||||
latest_daily = (
|
||||
ChartRecord.objects.filter(
|
||||
user=user, day__isnull=False, month__isnull=True
|
||||
)
|
||||
ChartRecord.objects.filter(user=user, day__isnull=False)
|
||||
.order_by("-year", "-month", "-day")
|
||||
.first()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user