196 lines
6.3 KiB
Python
196 lines
6.3 KiB
Python
import pytest
|
|
from django.contrib.auth import get_user_model
|
|
from django.core.cache import cache
|
|
from django.core.cache.utils import make_template_fragment_key
|
|
from django.db import connection
|
|
from django.test.utils import CaptureQueriesContext
|
|
from django.utils import timezone
|
|
from music.models import Artist, Track
|
|
from scrobbles.models import Scrobble
|
|
from tasks.models import Task
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def clear_cache():
|
|
cache.clear()
|
|
yield
|
|
cache.clear()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_home_renders_summary_and_timeline(client):
|
|
user = get_user_model().objects.create_user(
|
|
username="homeuser", password="testpass"
|
|
)
|
|
artist = Artist.objects.create(name="Sublime")
|
|
track = Track.objects.create(title="Same in the End", artist_fk=artist)
|
|
task = Task.objects.create(title="Ship the thing")
|
|
now = timezone.now()
|
|
Scrobble.objects.create(
|
|
user=user,
|
|
track=track,
|
|
media_type="Track",
|
|
timestamp=now,
|
|
played_to_completion=True,
|
|
)
|
|
Scrobble.objects.create(
|
|
user=user,
|
|
task=task,
|
|
media_type="Task",
|
|
timestamp=now - timezone.timedelta(minutes=10),
|
|
)
|
|
client.force_login(user)
|
|
response = client.get("/")
|
|
assert response.status_code == 200
|
|
content = response.content.decode()
|
|
assert "Same in the End" in content
|
|
assert "Ship the thing" in content
|
|
assert "Track" in content
|
|
assert "Task" in content
|
|
assert "Timeline" in content
|
|
assert "Details" in content
|
|
assert "Browse" in content
|
|
assert "media-browser-menu" in content
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_home_does_not_render_empty_types(client):
|
|
user = get_user_model().objects.create_user(
|
|
username="homeuser2", password="testpass"
|
|
)
|
|
task = Task.objects.create(title="Only task")
|
|
now = timezone.now()
|
|
Scrobble.objects.create(user=user, task=task, media_type="Task", timestamp=now)
|
|
client.force_login(user)
|
|
response = client.get("/")
|
|
content = response.content.decode()
|
|
assert "Only task" in content
|
|
assert "No tracks today" not in content
|
|
assert "No food today" not in content
|
|
assert "No videos today" not in content
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_home_type_section_cached_skips_query(client):
|
|
user = get_user_model().objects.create_user(
|
|
username="homecache", password="testpass"
|
|
)
|
|
task = Task.objects.create(title="Cached task")
|
|
now = timezone.now()
|
|
Scrobble.objects.create(user=user, task=task, media_type="Task", timestamp=now)
|
|
client.force_login(user)
|
|
|
|
# First request renders everything (cache cold)
|
|
with CaptureQueriesContext(connection) as cold:
|
|
response = client.get("/")
|
|
assert response.status_code == 200
|
|
assert "Cached task" in response.content.decode()
|
|
|
|
# Second request should serve the type-section fragment from cache and
|
|
# skip its DB query entirely
|
|
with CaptureQueriesContext(connection) as warm:
|
|
response = client.get("/")
|
|
assert response.status_code == 200
|
|
assert "Cached task" in response.content.decode()
|
|
assert len(warm) < len(cold)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_scrobble_save_invalidates_home_fragments(client):
|
|
user = get_user_model().objects.create_user(
|
|
username="invalidate", password="testpass"
|
|
)
|
|
task = Task.objects.create(title="First")
|
|
now = timezone.now()
|
|
scrobble = Scrobble.objects.create(
|
|
user=user, task=task, media_type="Task", timestamp=now
|
|
)
|
|
timeline_key = make_template_fragment_key(
|
|
"home_timeline", [user.id, now.strftime("%Y-%m-%d")]
|
|
)
|
|
type_key = make_template_fragment_key(
|
|
"home_type_section", [user.id, now.strftime("%Y-%m-%d"), "Task"]
|
|
)
|
|
cache.set(timeline_key, "cached")
|
|
cache.set(type_key, "cached")
|
|
assert cache.get(timeline_key) == "cached"
|
|
assert cache.get(type_key) == "cached"
|
|
|
|
Scrobble.objects.create(
|
|
user=user,
|
|
task=Task.objects.create(title="Second"),
|
|
media_type="Task",
|
|
timestamp=timezone.now(),
|
|
)
|
|
assert cache.get(timeline_key) is None
|
|
assert cache.get(type_key) is None
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_scrobble_delete_invalidates_home_fragments(client):
|
|
user = get_user_model().objects.create_user(
|
|
username="invalidedel", password="testpass"
|
|
)
|
|
task = Task.objects.create(title="Doomed")
|
|
now = timezone.now()
|
|
scrobble = Scrobble.objects.create(
|
|
user=user, task=task, media_type="Task", timestamp=now
|
|
)
|
|
timeline_key = make_template_fragment_key(
|
|
"home_timeline", [user.id, now.strftime("%Y-%m-%d")]
|
|
)
|
|
cache.set(timeline_key, "cached")
|
|
assert cache.get(timeline_key) == "cached"
|
|
|
|
scrobble.delete()
|
|
assert cache.get(timeline_key) is None
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_home_week_view_uses_grouped_tables(client):
|
|
user = get_user_model().objects.create_user(
|
|
username="homeweek", password="testpass"
|
|
)
|
|
task = Task.objects.create(title="Week task")
|
|
now = timezone.now()
|
|
Scrobble.objects.create(user=user, task=task, media_type="Task", timestamp=now)
|
|
client.force_login(user)
|
|
response = client.get("/", {"date": "this_week"})
|
|
assert response.status_code == 200
|
|
content = response.content.decode()
|
|
assert "Week task" in content
|
|
assert "Timeline" not in content
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_home_media_badges_colored_initials_by_default(client):
|
|
user = get_user_model().objects.create_user(
|
|
username="badgeinit", password="testpass"
|
|
)
|
|
task = Task.objects.create(title="Badge task")
|
|
Scrobble.objects.create(
|
|
user=user, task=task, media_type="Task", timestamp=timezone.now()
|
|
)
|
|
client.force_login(user)
|
|
content = client.get("/").content.decode()
|
|
assert 'class="badge media-badge' in content
|
|
assert ">T</span>" in content
|
|
assert "\u2705" not in content
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_home_media_badges_use_emojis_when_enabled(client):
|
|
user = get_user_model().objects.create_user(
|
|
username="badgeemoji", password="testpass"
|
|
)
|
|
user.profile.timeline_use_emojis = True
|
|
user.profile.save()
|
|
task = Task.objects.create(title="Emoji task")
|
|
Scrobble.objects.create(
|
|
user=user, task=task, media_type="Task", timestamp=timezone.now()
|
|
)
|
|
client.force_login(user)
|
|
content = client.get("/").content.decode()
|
|
assert "\u2705" in content
|
|
assert ">T</span>" not in content
|