From a85f5b6f449b9733c104008854d564fce4bcdd37 Mon Sep 17 00:00:00 2001 From: Disco DeDisco Date: Fri, 29 May 2026 23:06:19 -0400 Subject: [PATCH] =?UTF-8?q?my-sea=20slot:=20render=20the=205+-char=20numer?= =?UTF-8?q?al=20squeeze=20(--rank-long)=20server-side=20so=20it=20survives?= =?UTF-8?q?=20a=20refresh=20=E2=80=94=20TDD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sea.js's _fillSlot adds .sea-card-slot--rank-long on draw (corner_rank length >= 5) to squeeze long Roman numerals (XVIII, XLVIII, ...) into the slot, but _my_sea_slot.html didn't — so a saved hand stretched the numeral back out on refresh (server render). Add the same length>=5 class server-side. Fixes both the owner picker + the spectator cross (shared partial). +3 ITs (long / short / boundary). Code architected by Disco DeDisco Git commit message Co-Authored-By: Claude Opus 4.8 (1M context) --- .../tests/integrated/test_sea_visit.py | 29 +++++++++++++++++++ .../gameboard/_partials/_my_sea_slot.html | 6 +++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/apps/gameboard/tests/integrated/test_sea_visit.py b/src/apps/gameboard/tests/integrated/test_sea_visit.py index 98d176b..8674fc6 100644 --- a/src/apps/gameboard/tests/integrated/test_sea_visit.py +++ b/src/apps/gameboard/tests/integrated/test_sea_visit.py @@ -459,3 +459,32 @@ class MySeaVoiceContextTest(TestCase): self.client.force_login(self.owner) ctx = self.client.get(reverse("my_sea")).context self.assertFalse(ctx["voice_active"]) + + +class MySeaSlotRankLongTest(TestCase): + """The 5+-char Roman-numeral squeeze (`--rank-long`) is now rendered + server-side in `_my_sea_slot.html`, matching sea.js's `_fillSlot` length>=5 + rule — so a saved hand keeps the narrowed numeral across a refresh instead + of stretching back out (user-reported 2026-05-29).""" + + def _render(self, corner_rank): + from django.template.loader import render_to_string + return render_to_string("apps/gameboard/_partials/_my_sea_slot.html", { + "position": "lay", + "crossing": False, + "saved": { + "card_id": 1, "polarity": "gravity", "reversed": False, + "has_card_images": False, "corner_rank": corner_rank, + "suit_icon": "", "arcana": "", "image_url": "", "name": "", + }, + }) + + def test_long_numeral_gets_rank_long(self): + self.assertIn("sea-card-slot--rank-long", self._render("XLVIII")) + + def test_short_numeral_has_no_rank_long(self): + self.assertNotIn("sea-card-slot--rank-long", self._render("IV")) + + def test_exactly_five_chars_gets_rank_long(self): + # Boundary matches the JS (length >= 5). + self.assertIn("sea-card-slot--rank-long", self._render("XVIII")) diff --git a/src/templates/apps/gameboard/_partials/_my_sea_slot.html b/src/templates/apps/gameboard/_partials/_my_sea_slot.html index a97b0e4..c92bdde 100644 --- a/src/templates/apps/gameboard/_partials/_my_sea_slot.html +++ b/src/templates/apps/gameboard/_partials/_my_sea_slot.html @@ -8,7 +8,11 @@ {# crossing — bool; pass True for the cross slot (gets the #} {# `.sea-card-slot--crossing` modifier in iter-4a HTML) #} {% if saved %} -
= 5) — without it a saved hand stretched the numeral back out #} + {# on refresh (JS-only before, user-reported 2026-05-29). #} +