daphne added to dependencies; still reliant on uvicorn, as the former is now used solely as a channels testing req'ment; new consumer model in apps.epic.consumers to handle _gatekeeper partial functionality, permitting access to room once token costs met; new .routing urlpattern to accomodate; new tests.integrated.test_consumer IT cases ensure this functionality

This commit is contained in:
Disco DeDisco
2026-03-16 18:44:06 -04:00
parent 462155f07b
commit c9defa5a81
5 changed files with 65 additions and 2 deletions

View File

@@ -7,6 +7,7 @@ channels-redis
charset-normalizer==3.4.4 charset-normalizer==3.4.4
coverage coverage
cssselect==1.3.0 cssselect==1.3.0
daphne
dj-database-url dj-database-url
Django==6.0 Django==6.0
django-compressor django-compressor

View File

@@ -2,6 +2,7 @@ celery
channels channels
channels-redis channels-redis
cssselect==1.3.0 cssselect==1.3.0
daphne
Django==6.0 Django==6.0
dj-database-url dj-database-url
django-compressor django-compressor

View File

@@ -1 +1,18 @@
# RoomConsumer goes here from channels.generic.websocket import AsyncJsonWebsocketConsumer
class RoomConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
self.room_slug = self.scope["url_route"]["kwargs"]["room_slug"]
self.group_name = f"room_{self.room_slug}"
await self.channel_layer.group_add(self.group_name, self.channel_name)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(self.group_name, self.channel_name)
async def receive_json(self, content):
pass # handlers added as events introduced
async def gate_update(self, event):
await self.send_json(event)

View File

@@ -1 +1,8 @@
websocket_urlpatterns = [] from django.urls import path
from . import consumers
websocket_urlpatterns = [
path('ws/room/<slug:room_slug>/', consumers.RoomConsumer.as_asgi()),
]

View File

@@ -0,0 +1,37 @@
from channels.testing.websocket import WebsocketCommunicator
from channels.layers import get_channel_layer
from django.test import SimpleTestCase, override_settings
from core.asgi import application
TEST_CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer",
}
}
@override_settings(CHANNEL_LAYERS=TEST_CHANNEL_LAYERS)
class RoomConsumerTest(SimpleTestCase):
async def test_can_connect_and_disconnect(self):
communicator = WebsocketCommunicator(application, "/ws/room/test-room/")
connected, _ = await communicator.connect()
self.assertTrue(connected)
await communicator.disconnect()
async def test_receives_gate_update_broadcast(self):
communicator = WebsocketCommunicator(application, "/ws/room/test-room/")
await communicator.connect()
channel_layer = get_channel_layer()
await channel_layer.group_send(
"room_test-room",
{"type": "gate_update", "gate_state": "some_state"},
)
response = await communicator.receive_json_from()
self.assertEqual(response["type"], "gate_update")
self.assertEqual(response["gate_state"], "some_state")
await communicator.disconnect()