Sea Select FLIP: source the card-back from the seat's deck, not equipped_deck — TDD
The sea-stage FLIP no-op'd in the gameroom because `_sea_stage.html` rendered the back-img from `request.user.equipped_deck.back_image_url` — but `select_role` NULLS OUT the user's equipped_deck once it's contributed to the room's seats (views.py:1148), so in the Sea Select phase the deck was None → no back-img element → sea.js's FLIP handler short-circuits on the missing `.sig-stage-card-back-img` sibling. (my_sea worked: solo, no contribution.) - `_sea_stage.html` now renders the back-img from a `sea_back_image_url` ctx var instead of `request.user.equipped_deck` - gameroom: `_role_select_context` sets it from the SEAT's contributed deck (`_canonical_seat.deck_variant`, when it has card images) - my_sea: the my_sea view sets it from the user's own equipped deck - ITs: image seat-deck renders `.sig-stage-card-back-img`; text seat-deck omits it Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4162,19 +4162,24 @@ class PickSeaUnifiedFeltTest(TestCase):
|
||||
content = self.client.get(self.url).content.decode()
|
||||
self.assertIn("room-menu-sea", content)
|
||||
|
||||
def test_sea_stage_renders_back_img_for_image_deck(self):
|
||||
"""The sea-stage FLIP reveals the card back. The back-img now renders for
|
||||
ANY image-equipped deck WITH a back image (polarized or not) — dropping
|
||||
the old `not is_polarized` gate — so the Gravity/Levity draw can show a
|
||||
polarity-tinted back (user-spec 2026-06-07)."""
|
||||
def test_sea_stage_renders_back_img_from_seat_deck(self):
|
||||
"""The sea-stage FLIP reveals the card back. The back-img is sourced from
|
||||
the SEAT's contributed deck (NOT request.user.equipped_deck, which
|
||||
select_role nulls out → the back silently never rendered + FLIP no-op'd)
|
||||
and renders for any image-equipped deck w. a back (user-flagged
|
||||
2026-06-07)."""
|
||||
minch = DeckVariant.objects.get(slug="minchiate-fiorentine-1860-1890")
|
||||
founder = self.gamers[0]
|
||||
founder.unlocked_decks.add(minch)
|
||||
founder.equipped_deck = minch
|
||||
founder.save(update_fields=["equipped_deck"])
|
||||
self.pc_seat.deck_variant = minch
|
||||
self.pc_seat.save(update_fields=["deck_variant"])
|
||||
content = self.client.get(self.url).content.decode()
|
||||
self.assertIn("sig-stage-card-back-img", content)
|
||||
|
||||
def test_sea_stage_no_back_img_for_text_seat_deck(self):
|
||||
"""Earthman (text-mode, no card images) → no back-img element (FLIP is a
|
||||
no-op for text decks, by design)."""
|
||||
content = self.client.get(self.url).content.decode()
|
||||
self.assertNotIn("sig-stage-card-back-img", content)
|
||||
|
||||
def test_always_two_deck_stacks_gravity_and_levity(self):
|
||||
"""Unlike my_sea / Sig Select, the room Sea Select ALWAYS shows BOTH the
|
||||
Gravity + Levity stacks — the gamer draws from either populated half
|
||||
|
||||
@@ -680,6 +680,15 @@ def _role_select_context(room, user, seat_param=None):
|
||||
)
|
||||
# 6-card Celtic Cross is complete at 6 placed cards.
|
||||
ctx["hand_complete"] = len(_sea_hand) >= 6
|
||||
# Sea-stage FLIP card-back — sourced from the SEAT's contributed deck,
|
||||
# NOT request.user.equipped_deck (which `select_role` nulls out once
|
||||
# the deck is contributed to the room → the back-img silently never
|
||||
# rendered in the gameroom + FLIP no-op'd). User-flagged 2026-06-07.
|
||||
_back_deck = _canonical_seat.deck_variant if _canonical_seat else None
|
||||
ctx["sea_back_image_url"] = (
|
||||
_back_deck.back_image_url
|
||||
if (_back_deck and _back_deck.has_card_images) else ""
|
||||
)
|
||||
|
||||
return ctx
|
||||
|
||||
|
||||
@@ -372,6 +372,14 @@ def my_sea(request):
|
||||
"significator_reversed": sig_reversed,
|
||||
"default_spread": default_spread,
|
||||
"reversals_pct": 25,
|
||||
# Sea-stage FLIP card-back — my_sea is solo (no deck contribution), so the
|
||||
# user's OWN equipped deck is the right source (the gameroom uses the
|
||||
# seat's contributed deck instead; see _sea_stage.html).
|
||||
"sea_back_image_url": (
|
||||
request.user.equipped_deck.back_image_url
|
||||
if (request.user.equipped_deck and request.user.equipped_deck.has_card_images)
|
||||
else ""
|
||||
),
|
||||
"sea_deck_data": (
|
||||
_my_sea_deck_data(request.user, exclude_id=sig_card.id if sig_card else None)
|
||||
if user_has_sig else {"levity": [], "gravity": []}
|
||||
|
||||
@@ -43,20 +43,19 @@
|
||||
</div>
|
||||
{% comment %}
|
||||
back-img + FLIP btn. FLIP reveals the card back. Renders for ANY
|
||||
image-equipped deck that has a back image — INCLUDING polarized decks
|
||||
image-equipped deck w. a back image — INCLUDING polarized decks
|
||||
(user-spec 2026-06-07): the Sea Select phase tints the back per the
|
||||
drawn card's polarity (`.sea-stage--gravity` / `--levity`, see
|
||||
`_card-deck.scss`), so the same back-art reads distinctly for the two
|
||||
stacks (was previously gated to non-polarized decks, where it never
|
||||
rendered for the room's Gravity/Levity draw). The FLIP btn renders
|
||||
unconditionally; sea.js's handler no-ops when no back-img sibling
|
||||
exists (text decks). Multi-user gameroom limitation: the src is the
|
||||
VIEWER's deck-back — correct for the sea (each gamer draws their own),
|
||||
parked for the general multi-user case.
|
||||
stacks. `sea_back_image_url` is set by each caller from the RIGHT
|
||||
deck: the gameroom uses the SEAT's contributed deck (NOT
|
||||
request.user.equipped_deck, which select_role nulls out → the back
|
||||
silently never rendered + FLIP no-op'd); my_sea uses the user's
|
||||
equipped deck. FLIP btn renders unconditionally; sea.js's handler
|
||||
no-ops when no back-img sibling exists (text decks).
|
||||
{% endcomment %}
|
||||
{% if request.user.is_authenticated and request.user.equipped_deck.has_card_images and request.user.equipped_deck.back_image_url %}
|
||||
<img class="sig-stage-card-back-img" alt=""
|
||||
src="{{ request.user.equipped_deck.back_image_url }}">
|
||||
{% if sea_back_image_url %}
|
||||
<img class="sig-stage-card-back-img" alt="" src="{{ sea_back_image_url }}">
|
||||
{% endif %}
|
||||
<button class="btn btn-reveal sea-stage-flip-btn" type="button" aria-label="Flip card">FLIP</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user