PICK SEA: modal w. Celtic Cross layout + spread select; PICK SKY swaps to PICK SEA after sky save — TDD
- _role_select_context: at SKY_SELECT, compute sky_confirmed (confirmed Character exists for seat) + user_polarity - room.html: PICK SEA btn + _sea_overlay.html when sky_confirmed; PICK SKY + natus overlay otherwise - _sea_overlay.html: transparent cards col (6-position cross, Sig at center) left; priUser form col (spread select) right; NVM cancel; JS open/close via html.sea-open - _natus.scss: .sea-* rules mirror natus layout w. reversed columns; crossing slot rotated; dotted empty slots; sig slot solid; width/max-width replaces min() to avoid rem+vw unit mix - select defaults: "Celtic Cross, Waite-Smith" for levity (PC/NC/SC); "Celtic Cross, Escape Velocity" for gravity (EC/AC/BC) Code architected by Disco DeDisco <discodedisco@outlook.com> Git commit message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,7 @@ from django.utils import timezone
|
||||
from apps.drama.models import GameEvent
|
||||
from apps.lyric.models import Token, User
|
||||
from apps.epic.models import (
|
||||
DeckVariant, GateSlot, Room, RoomInvite, SigReservation, TableSeat, TarotCard,
|
||||
Character, DeckVariant, GateSlot, Room, RoomInvite, SigReservation, TableSeat, TarotCard,
|
||||
)
|
||||
|
||||
|
||||
@@ -1652,6 +1652,69 @@ class PickSkyRenderingTest(TestCase):
|
||||
self.assertContains(response, 'style="display:none"')
|
||||
|
||||
|
||||
# ── SEA_SELECT rendering ──────────────────────────────────────────────────────
|
||||
|
||||
class PickSeaRenderingTest(TestCase):
|
||||
"""At SKY_SELECT, a confirmed Character swaps PICK SKY → PICK SEA + sea overlay."""
|
||||
|
||||
def setUp(self):
|
||||
self.room, self.gamers, self.earthman, _ = _full_sig_setUp(self)
|
||||
self.room.table_status = Room.SKY_SELECT
|
||||
self.room.save()
|
||||
self.sig_card = TarotCard.objects.get(
|
||||
deck_variant=self.earthman, arcana="MIDDLE", suit="BRANDS", number=11
|
||||
)
|
||||
self.pc_seat = TableSeat.objects.get(room=self.room, role="PC")
|
||||
self.pc_seat.significator = self.sig_card
|
||||
self.pc_seat.save()
|
||||
self.url = reverse("epic:room", kwargs={"room_id": self.room.id})
|
||||
|
||||
def _confirm_sky(self, seat=None):
|
||||
target = seat or self.pc_seat
|
||||
return Character.objects.create(seat=target, confirmed_at=timezone.now())
|
||||
|
||||
def test_sky_confirmed_false_when_no_character(self):
|
||||
response = self.client.get(self.url)
|
||||
self.assertFalse(response.context["sky_confirmed"])
|
||||
|
||||
def test_sky_confirmed_true_when_character_confirmed(self):
|
||||
self._confirm_sky()
|
||||
response = self.client.get(self.url)
|
||||
self.assertTrue(response.context["sky_confirmed"])
|
||||
|
||||
def test_pick_sea_btn_shown_when_sky_confirmed(self):
|
||||
self._confirm_sky()
|
||||
response = self.client.get(self.url)
|
||||
self.assertContains(response, "id_pick_sea_btn")
|
||||
|
||||
def test_pick_sky_btn_shown_when_sky_not_confirmed(self):
|
||||
response = self.client.get(self.url)
|
||||
self.assertContains(response, "id_pick_sky_btn")
|
||||
|
||||
def test_sea_overlay_included_when_sky_confirmed(self):
|
||||
self._confirm_sky()
|
||||
response = self.client.get(self.url)
|
||||
self.assertContains(response, "id_sea_overlay")
|
||||
|
||||
def test_sea_overlay_select_defaults_to_waite_smith_for_levity(self):
|
||||
self._confirm_sky()
|
||||
response = self.client.get(self.url)
|
||||
self.assertContains(response, "Celtic Cross, Waite-Smith")
|
||||
|
||||
def test_sea_overlay_select_defaults_to_escape_velocity_for_gravity(self):
|
||||
ec_gamer = self.gamers[2] # EC — gravity
|
||||
self.client.force_login(ec_gamer)
|
||||
ec_seat = TableSeat.objects.get(room=self.room, role="EC")
|
||||
self._confirm_sky(seat=ec_seat)
|
||||
response = self.client.get(self.url)
|
||||
self.assertContains(response, "Celtic Cross, Escape Velocity")
|
||||
|
||||
def test_user_polarity_in_context_at_sky_select(self):
|
||||
response = self.client.get(self.url)
|
||||
self.assertIn("user_polarity", response.context)
|
||||
self.assertEqual(response.context["user_polarity"], "levity") # PC is levity
|
||||
|
||||
|
||||
# ── select_role GET redirect ──────────────────────────────────────────────────
|
||||
|
||||
class SelectRoleGetRedirectTest(TestCase):
|
||||
|
||||
@@ -342,6 +342,24 @@ def _role_select_context(room, user):
|
||||
ctx["sig_cards"] = gravity_sig_cards(room)
|
||||
else:
|
||||
ctx["sig_cards"] = []
|
||||
|
||||
if room.table_status == Room.SKY_SELECT:
|
||||
user_role = _canonical_seat.role if _canonical_seat else None
|
||||
user_polarity = None
|
||||
if user_role in _LEVITY_ROLES:
|
||||
user_polarity = 'levity'
|
||||
elif user_role in _GRAVITY_ROLES:
|
||||
user_polarity = 'gravity'
|
||||
ctx["user_polarity"] = user_polarity
|
||||
sky_confirmed = bool(
|
||||
_canonical_seat and Character.objects.filter(
|
||||
seat=_canonical_seat,
|
||||
confirmed_at__isnull=False,
|
||||
retired_at__isnull=True,
|
||||
).exists()
|
||||
)
|
||||
ctx["sky_confirmed"] = sky_confirmed
|
||||
|
||||
return ctx
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user