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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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()),
|
||||||
|
]
|
||||||
|
|||||||
37
src/apps/epic/tests/integrated/test_consumers.py
Normal file
37
src/apps/epic/tests/integrated/test_consumers.py
Normal 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()
|
||||||
Reference in New Issue
Block a user