diff --git a/src/apps/gameboard/tests/integrated/test_views.py b/src/apps/gameboard/tests/integrated/test_views.py index da04e6f..4726b6a 100644 --- a/src/apps/gameboard/tests/integrated/test_views.py +++ b/src/apps/gameboard/tests/integrated/test_views.py @@ -726,3 +726,74 @@ class MySeaSpreadFormTemplateTest(TestCase): self.assertIn('id="id_sea_del"', html) self.assertIn("sea-reversal-hint", html) self.assertIn("25% reversals", html) + + +class MySeaDeckDataViewTest(TestCase): + """Sprint 5 iter 4a — view-level deck-data contract. `my_sea` view + embeds a shuffled deck (levity + gravity halves, current user's + significator excluded, reversal pre-rolled at ~25%) as JSON via + the `sea_deck_data` context key + `{{ ...|json_script }}` filter + in the template.""" + + def setUp(self): + from apps.epic.models import personal_sig_cards + self.user = User.objects.create(email="deck@test.io") + self.client.force_login(self.user) + self.target = personal_sig_cards(self.user)[0] + self.user.significator = self.target + self.user.save(update_fields=["significator"]) + + def test_context_sea_deck_data_has_two_polarity_halves(self): + response = self.client.get(reverse("my_sea")) + deck = response.context["sea_deck_data"] + self.assertIn("levity", deck) + self.assertIn("gravity", deck) + self.assertIsInstance(deck["levity"], list) + self.assertIsInstance(deck["gravity"], list) + + def test_deck_data_excludes_user_significator(self): + response = self.client.get(reverse("my_sea")) + deck = response.context["sea_deck_data"] + all_ids = ( + {c["id"] for c in deck["levity"]} + | {c["id"] for c in deck["gravity"]} + ) + self.assertNotIn(self.target.id, all_ids) + + def test_deck_data_halves_are_disjoint(self): + response = self.client.get(reverse("my_sea")) + deck = response.context["sea_deck_data"] + levity_ids = {c["id"] for c in deck["levity"]} + gravity_ids = {c["id"] for c in deck["gravity"]} + self.assertEqual(levity_ids & gravity_ids, set()) + + def test_deck_data_cards_carry_corner_rank_suit_icon_and_reversed(self): + # Card dict shape mirrors the gameroom `sea_deck` endpoint so + # iter 4b's persistence/render path can reuse the JSON contract. + response = self.client.get(reverse("my_sea")) + deck = response.context["sea_deck_data"] + any_card = (deck["levity"] + deck["gravity"])[0] + for key in ("id", "corner_rank", "suit_icon", "reversed"): + with self.subTest(key=key): + self.assertIn(key, any_card) + self.assertIsInstance(any_card["reversed"], bool) + + def test_template_embeds_deck_as_json_script(self): + # Embed mechanism: `{{ sea_deck_data|json_script:"id_my_sea_deck" }}` + # gives a `