various styling & structural changes to unify site themes; token-drop interaction changes across epic urls & views
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
Disco DeDisco
2026-03-14 02:03:44 -04:00
parent d9feb80b2a
commit f76c6d0fe5
8 changed files with 618 additions and 90 deletions

View File

@@ -1,8 +1,9 @@
from django.test import TestCase
from django.urls import reverse
from django.utils import timezone
from apps.lyric.models import User
from apps.epic.models import Room, RoomInvite
from apps.lyric.models import Token, User
from apps.epic.models import GateSlot, Room, RoomInvite
class RoomCreationViewTest(TestCase):
@@ -76,6 +77,158 @@ class GateStatusViewTest(TestCase):
self.assertContains(response, "gate-modal")
class DropTokenViewTest(TestCase):
def setUp(self):
self.gamer = User.objects.create(email="gamer@test.io")
self.client.force_login(self.gamer)
owner = User.objects.create(email="owner@test.io")
self.room = Room.objects.create(name="Test Room", owner=owner)
def test_drop_token_reserves_lowest_empty_slot(self):
self.client.post(reverse("epic:drop_token", kwargs={"room_id": self.room.id}))
slot = self.room.gate_slots.get(slot_number=1)
self.assertEqual(slot.status, GateSlot.RESERVED)
self.assertEqual(slot.gamer, self.gamer)
def test_drop_token_skips_already_filled_slots(self):
other = User.objects.create(email="other@test.io")
slot1 = self.room.gate_slots.get(slot_number=1)
slot1.gamer = other
slot1.status = GateSlot.FILLED
slot1.save()
self.client.post(reverse("epic:drop_token", kwargs={"room_id": self.room.id}))
slot2 = self.room.gate_slots.get(slot_number=2)
self.assertEqual(slot2.status, GateSlot.RESERVED)
self.assertEqual(slot2.gamer, self.gamer)
def test_drop_token_blocked_when_another_slot_reserved(self):
other = User.objects.create(email="other@test.io")
slot1 = self.room.gate_slots.get(slot_number=1)
slot1.gamer = other
slot1.status = GateSlot.RESERVED
slot1.reserved_at = timezone.now()
slot1.save()
self.client.post(reverse("epic:drop_token", kwargs={"room_id": self.room.id}))
# Slot 2 should remain EMPTY — lock held by other user
slot2 = self.room.gate_slots.get(slot_number=2)
self.assertEqual(slot2.status, GateSlot.EMPTY)
def test_drop_token_blocked_when_user_already_has_filled_slot(self):
slot1 = self.room.gate_slots.get(slot_number=1)
slot1.gamer = self.gamer
slot1.status = GateSlot.FILLED
slot1.save()
self.client.post(reverse("epic:drop_token", kwargs={"room_id": self.room.id}))
slot2 = self.room.gate_slots.get(slot_number=2)
self.assertEqual(slot2.status, GateSlot.EMPTY)
def test_drop_token_sets_reserved_at(self):
self.client.post(reverse("epic:drop_token", kwargs={"room_id": self.room.id}))
slot = self.room.gate_slots.get(slot_number=1)
self.assertIsNotNone(slot.reserved_at)
def test_drop_token_redirects_to_gatekeeper(self):
response = self.client.post(
reverse("epic:drop_token", kwargs={"room_id": self.room.id})
)
self.assertRedirects(
response, reverse("epic:gatekeeper", args=[self.room.id])
)
class ConfirmTokenViewTest(TestCase):
def setUp(self):
self.gamer = User.objects.create(email="gamer@test.io")
self.client.force_login(self.gamer)
owner = User.objects.create(email="owner@test.io")
self.room = Room.objects.create(name="Test Room", owner=owner)
self.slot = self.room.gate_slots.get(slot_number=1)
self.slot.gamer = self.gamer
self.slot.status = GateSlot.RESERVED
self.slot.reserved_at = timezone.now()
self.slot.save()
Token.objects.create(user=self.gamer, token_type=Token.FREE)
def test_confirm_marks_slot_filled(self):
self.client.post(
reverse("epic:confirm_token", kwargs={"room_id": self.room.id})
)
self.slot.refresh_from_db()
self.assertEqual(self.slot.status, GateSlot.FILLED)
def test_confirm_sets_gate_open_when_all_slots_filled(self):
# Fill slots 26 via ORM
for i in range(2, 7):
other = User.objects.create(email=f"g{i}@test.io")
s = self.room.gate_slots.get(slot_number=i)
s.gamer = other
s.status = GateSlot.FILLED
s.save()
self.client.post(
reverse("epic:confirm_token", kwargs={"room_id": self.room.id})
)
self.room.refresh_from_db()
self.assertEqual(self.room.gate_status, Room.OPEN)
def test_confirm_redirects_to_gatekeeper(self):
response = self.client.post(
reverse("epic:confirm_token", kwargs={"room_id": self.room.id})
)
self.assertRedirects(
response, reverse("epic:gatekeeper", args=[self.room.id])
)
def test_confirm_does_nothing_without_reserved_slot(self):
self.slot.status = GateSlot.EMPTY
self.slot.gamer = None
self.slot.save()
self.client.post(
reverse("epic:confirm_token", kwargs={"room_id": self.room.id})
)
self.slot.refresh_from_db()
self.assertEqual(self.slot.status, GateSlot.EMPTY)
class RejectTokenViewTest(TestCase):
def setUp(self):
self.gamer = User.objects.create(email="gamer@test.io")
self.client.force_login(self.gamer)
owner = User.objects.create(email="owner@test.io")
self.room = Room.objects.create(name="Test Room", owner=owner)
self.slot = self.room.gate_slots.get(slot_number=1)
self.slot.gamer = self.gamer
self.slot.status = GateSlot.RESERVED
self.slot.reserved_at = timezone.now()
self.slot.save()
def test_reject_clears_reserved_slot(self):
self.client.post(
reverse("epic:reject_token", kwargs={"room_id": self.room.id})
)
self.slot.refresh_from_db()
self.assertEqual(self.slot.status, GateSlot.EMPTY)
self.assertIsNone(self.slot.gamer)
self.assertIsNone(self.slot.reserved_at)
def test_reject_after_confirm_clears_filled_slot(self):
self.slot.status = GateSlot.FILLED
self.slot.save()
self.client.post(
reverse("epic:reject_token", kwargs={"room_id": self.room.id})
)
self.slot.refresh_from_db()
self.assertEqual(self.slot.status, GateSlot.EMPTY)
self.assertIsNone(self.slot.gamer)
def test_reject_redirects_to_gatekeeper(self):
response = self.client.post(
reverse("epic:reject_token", kwargs={"room_id": self.room.id})
)
self.assertRedirects(
response, reverse("epic:gatekeeper", args=[self.room.id])
)
class RoomActionsViewTest(TestCase):
def setUp(self):
self.owner = User.objects.create(email="owner@test.io")