sig-select sprint: SigReservation model + sig_reserve view (OK/NVM hold); full sig-select.js rewrite with stage preview, WS hover cursors, reservation lock (must NVM before OK-ing another card — enforced server-side 409 + JS guard); sizeSigModal() + sizeSigCard() in room.js (JS-based card sizing avoids libsass cqw/cqh limitation); stat block hidden until OK pressed; mobile touch: dismiss stage on outside-grid tap when unfocused; 17 IT + Jasmine specs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -164,3 +164,98 @@ class CursorMoveConsumerTest(TransactionTestCase):
|
||||
|
||||
await pc_comm.disconnect()
|
||||
await bc_comm.disconnect()
|
||||
|
||||
|
||||
@tag('channels')
|
||||
@override_settings(CHANNEL_LAYERS=TEST_CHANNEL_LAYERS)
|
||||
class SigHoverConsumerTest(TransactionTestCase):
|
||||
"""sig_hover messages sent by a client are forwarded within the polarity group only."""
|
||||
|
||||
async def _make_communicator(self, user, room):
|
||||
client = Client()
|
||||
await database_sync_to_async(client.force_login)(user)
|
||||
session_key = await database_sync_to_async(lambda: client.session.session_key)()
|
||||
comm = WebsocketCommunicator(
|
||||
application,
|
||||
f"/ws/room/{room.id}/",
|
||||
headers=[(b"cookie", f"sessionid={session_key}".encode())],
|
||||
)
|
||||
connected, _ = await comm.connect()
|
||||
self.assertTrue(connected)
|
||||
return comm
|
||||
|
||||
async def test_sig_hover_forwarded_to_polarity_group(self):
|
||||
pc_user = await database_sync_to_async(User.objects.create)(email="pc@test.io")
|
||||
nc_user = await database_sync_to_async(User.objects.create)(email="nc@test.io")
|
||||
room = await database_sync_to_async(Room.objects.create)(name="T", owner=pc_user)
|
||||
await database_sync_to_async(TableSeat.objects.create)(
|
||||
room=room, gamer=pc_user, slot_number=1, role="PC"
|
||||
)
|
||||
await database_sync_to_async(TableSeat.objects.create)(
|
||||
room=room, gamer=nc_user, slot_number=2, role="NC"
|
||||
)
|
||||
|
||||
pc_comm = await self._make_communicator(pc_user, room)
|
||||
nc_comm = await self._make_communicator(nc_user, room)
|
||||
|
||||
await pc_comm.send_json_to({
|
||||
"type": "sig_hover", "card_id": "abc-123", "role": "PC", "active": True
|
||||
})
|
||||
|
||||
msg = await nc_comm.receive_json_from(timeout=2)
|
||||
self.assertEqual(msg["type"], "sig_hover")
|
||||
self.assertEqual(msg["card_id"], "abc-123")
|
||||
self.assertEqual(msg["role"], "PC")
|
||||
self.assertTrue(msg["active"])
|
||||
|
||||
await pc_comm.disconnect()
|
||||
await nc_comm.disconnect()
|
||||
|
||||
async def test_sig_hover_not_forwarded_to_other_polarity(self):
|
||||
pc_user = await database_sync_to_async(User.objects.create)(email="pc@test.io")
|
||||
bc_user = await database_sync_to_async(User.objects.create)(email="bc@test.io")
|
||||
room = await database_sync_to_async(Room.objects.create)(name="T", owner=pc_user)
|
||||
await database_sync_to_async(TableSeat.objects.create)(
|
||||
room=room, gamer=pc_user, slot_number=1, role="PC"
|
||||
)
|
||||
await database_sync_to_async(TableSeat.objects.create)(
|
||||
room=room, gamer=bc_user, slot_number=2, role="BC"
|
||||
)
|
||||
|
||||
pc_comm = await self._make_communicator(pc_user, room)
|
||||
bc_comm = await self._make_communicator(bc_user, room)
|
||||
|
||||
await pc_comm.send_json_to({
|
||||
"type": "sig_hover", "card_id": "abc-123", "role": "PC", "active": True
|
||||
})
|
||||
|
||||
self.assertTrue(await bc_comm.receive_nothing(timeout=1))
|
||||
|
||||
await pc_comm.disconnect()
|
||||
await bc_comm.disconnect()
|
||||
|
||||
async def test_sig_reserved_broadcast_received_by_polarity_group(self):
|
||||
pc_user = await database_sync_to_async(User.objects.create)(email="pc@test.io")
|
||||
nc_user = await database_sync_to_async(User.objects.create)(email="nc@test.io")
|
||||
room = await database_sync_to_async(Room.objects.create)(name="T", owner=pc_user)
|
||||
await database_sync_to_async(TableSeat.objects.create)(
|
||||
room=room, gamer=pc_user, slot_number=1, role="PC"
|
||||
)
|
||||
await database_sync_to_async(TableSeat.objects.create)(
|
||||
room=room, gamer=nc_user, slot_number=2, role="NC"
|
||||
)
|
||||
|
||||
nc_comm = await self._make_communicator(nc_user, room)
|
||||
|
||||
channel_layer = get_channel_layer()
|
||||
await channel_layer.group_send(
|
||||
f"cursors_{room.id}_levity",
|
||||
{"type": "sig_reserved", "card_id": "card-xyz", "role": "PC", "reserved": True},
|
||||
)
|
||||
|
||||
msg = await nc_comm.receive_json_from(timeout=2)
|
||||
self.assertEqual(msg["type"], "sig_reserved")
|
||||
self.assertEqual(msg["card_id"], "card-xyz")
|
||||
self.assertTrue(msg["reserved"])
|
||||
|
||||
await nc_comm.disconnect()
|
||||
|
||||
Reference in New Issue
Block a user