Files
python-tdd/src/apps/drama/tests/integrated/test_models.py

117 lines
5.4 KiB
Python
Raw Normal View History

from django.test import TestCase
from django.db import IntegrityError
from apps.drama.models import GameEvent, ScrollPosition, record
from apps.epic.models import Room
from apps.lyric.models import User
class GameEventModelTest(TestCase):
def setUp(self):
self.user = User.objects.create(email="actor@test.io")
self.room = Room.objects.create(name="Test Room", owner=self.user)
def test_record_creates_game_event(self):
event = record(self.room, GameEvent.SLOT_FILLED, actor=self.user, slot_number=1, token_type="tithe")
self.assertEqual(GameEvent.objects.count(), 1)
self.assertEqual(event.room, self.room)
self.assertEqual(event.actor, self.user)
self.assertEqual(event.verb, GameEvent.SLOT_FILLED)
self.assertEqual(event.data, {"slot_number": 1, "token_type": "tithe"})
def test_record_without_actor(self):
event = record(self.room, GameEvent.ROOM_CREATED)
self.assertIsNone(event.actor)
self.assertEqual(event.verb, GameEvent.ROOM_CREATED)
def test_events_ordered_by_timestamp(self):
record(self.room, GameEvent.ROOM_CREATED)
record(self.room, GameEvent.SLOT_RESERVED, actor=self.user)
record(self.room, GameEvent.SLOT_FILLED, actor=self.user)
verbs = list(GameEvent.objects.values_list("verb", flat=True))
self.assertEqual(verbs, [
GameEvent.ROOM_CREATED,
GameEvent.SLOT_RESERVED,
GameEvent.SLOT_FILLED,
])
def test_str_includes_actor_and_verb(self):
event = record(self.room, GameEvent.ROLE_SELECTED, actor=self.user, role="PC")
self.assertIn("actor@test.io", str(event))
self.assertIn(GameEvent.ROLE_SELECTED, str(event))
# ── to_prose — ROLE_SELECTED ──────────────────────────────────────────
def test_role_selected_prose_uses_ordinal_chair(self):
for role, ordinal in [("PC", "1st"), ("NC", "2nd"), ("EC", "3rd"),
("SC", "4th"), ("AC", "5th"), ("BC", "6th")]:
with self.subTest(role=role):
event = record(self.room, GameEvent.ROLE_SELECTED, actor=self.user,
role=role, role_display="")
self.assertIn(f"assumes {ordinal} Chair", event.to_prose())
def test_role_selected_prose_includes_role_name(self):
event = record(self.room, GameEvent.ROLE_SELECTED, actor=self.user,
role="PC", role_display="Player")
prose = event.to_prose()
self.assertIn("Player", prose)
self.assertIn("yo will start the game", prose)
# ── to_prose — SIG_READY ─────────────────────────────────────────────
def test_sig_ready_prose_embodies_card_with_rank_and_icon(self):
event = record(self.room, GameEvent.SIG_READY, actor=self.user,
card_name="Maid of Brands", corner_rank="M",
suit_icon="fa-wand-sparkles")
prose = event.to_prose()
self.assertIn("embodies as yos Significator the Maid of Brands", prose)
self.assertIn("(M", prose)
self.assertIn("fa-wand-sparkles", prose)
def test_sig_ready_prose_omits_icon_when_none(self):
event = record(self.room, GameEvent.SIG_READY, actor=self.user,
card_name="The Wanderer", corner_rank="0", suit_icon="")
prose = event.to_prose()
self.assertIn("embodies as yos Significator the The Wanderer (0)", prose)
self.assertNotIn("fa-", prose)
def test_sig_ready_prose_degrades_without_corner_rank(self):
# Old events recorded before this change have no corner_rank key
event = record(self.room, GameEvent.SIG_READY, actor=self.user,
card_name="Maid of Brands")
prose = event.to_prose()
self.assertIn("embodies as yos Significator the Maid of Brands", prose)
self.assertNotIn("(", prose)
def test_str_without_actor_shows_system(self):
event = record(self.room, GameEvent.ROLES_REVEALED)
self.assertIn("system", str(event))
class ScrollPositionModelTest(TestCase):
def setUp(self):
self.user = User.objects.create(email="reader@test.io")
self.room = Room.objects.create(name="Test Room", owner=self.user)
def test_can_save_scroll_position(self):
sp = ScrollPosition.objects.create(user=self.user, room=self.room, position=150)
self.assertEqual(ScrollPosition.objects.count(), 1)
self.assertEqual(sp.position, 150)
def test_default_position_is_zero(self):
sp = ScrollPosition.objects.create(user=self.user, room=self.room)
self.assertEqual(sp.position, 0)
def test_unique_per_user_and_room(self):
ScrollPosition.objects.create(user=self.user, room=self.room, position=50)
with self.assertRaises(IntegrityError):
ScrollPosition.objects.create(user=self.user, room=self.room, position=100)
def test_upsert_updates_existing_position(self):
ScrollPosition.objects.create(user=self.user, room=self.room, position=50)
ScrollPosition.objects.update_or_create(
user=self.user, room=self.room,
defaults={"position": 200},
)
self.assertEqual(ScrollPosition.objects.get(user=self.user, room=self.room).position, 200)