Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
async def test_json_websocket_consumer():
"""
Tests that JsonWebsocketConsumer is implemented correctly.
"""
results = {}
class TestConsumer(JsonWebsocketConsumer):
def connect(self):
self.accept()
def receive_json(self, data=None):
results["received"] = data
self.send_json(data)
# Open a connection
communicator = WebsocketCommunicator(TestConsumer, "/testws/")
connected, _ = await communicator.connect()
assert connected
# Test sending
await communicator.send_json_to({"hello": "world"})
response = await communicator.receive_json_from()
assert response == {"hello": "world"}
assert results["received"] == {"hello": "world"}
# Test sending bytes breaks it
await communicator.send_to(bytes_data=b"w\0\0\0")
with pytest.raises(ValueError):
await communicator.wait()
async def test_websocket_application():
"""
Tests that the WebSocket communicator class works with the
URLRoute application.
"""
application = URLRouter([url(r"^testws/(?P\w+)/$", KwargsWebSocketApp)])
communicator = WebsocketCommunicator(application, "/testws/test/")
connected, subprotocol = await communicator.connect()
# Test connection
assert connected
assert subprotocol is None
message = await communicator.receive_from()
assert message == "test"
await communicator.disconnect()
async def test_notification_subscribe_empty(fake_user):
communicator = WebsocketCommunicator(asgi.application, "/ws/notify/")
try:
# force login with fake user
communicator.scope["user"] = fake_user
# websocket will allow connection
connected, subprotocol = await communicator.connect()
assert connected
# initial message will have messages and unread count
response = await communicator.receive_json_from()
assert "messages" in response
assert "unread" in response
assert response["messages"] == []
assert response["unread"] == 0
except Exception as e:
raise AssertionError() from e
finally:
await communicator.disconnect()
async def test_connection_scope(path):
"""
Tests ASGI specification for the the connection scope.
"""
communicator = WebsocketCommunicator(ConnectionScopeValidator, path)
connected, _ = await communicator.connect()
assert connected
await communicator.disconnect()
connected, subprotocol = await communicator.connect()
assert not connected
assert subprotocol == 1000
await communicator.disconnect()
# User ID in token doesn't match route
unauthorized_jwt = await async_get_jwt(sub='4686c616-fadf-4261-a2c2-6aaa504a1ae4')
communicator = await get_communicator(unauthorized_jwt)
connected, subprotocol = await communicator.connect()
assert not connected
assert subprotocol == 1000
await communicator.disconnect()
# Invalid protocols
valid_jwt = await async_get_jwt()
communicator = WebsocketCommunicator(application, f"ws/{USER_ID}/notifications",
subprotocols=[f"base64.wat.{valid_jwt}", "base64.authentication.wat"])
connected, subprotocol = await communicator.connect()
assert not connected
assert subprotocol == 1000
await communicator.disconnect()
async def test_error_cases():
"""Test that server responds correctly when errors happen.
Check that server responds with message of type `data` when there
is a syntax error in the request or the exception in a resolver
was raised. Check that server responds with message of type `error`
when there was an exceptional situation, for example, field `query`
of `payload` is missing or field `type` has a wrong value.
"""
# Channels communicator to test WebSocket consumers.
comm = ch_testing.WebsocketCommunicator(
application=my_app, path="graphql/", subprotocols=["graphql-ws"]
)
print("Establish & initialize the connection.")
await comm.connect(timeout=TIMEOUT)
await comm.send_json_to({"type": "connection_init", "payload": ""})
resp = await comm.receive_json_from(timeout=TIMEOUT)
assert resp["type"] == "connection_ack"
print("Check that query syntax error leads to the `error` response.")
uniq_id = str(uuid.uuid4().hex)
await comm.send_json_to(
{
"id": uniq_id,
"type": "wrong_type__(ツ)_/¯",
"payload": {"variables": {}, "operationName": "MyOperationName"},
raise GraphQLError("Reject connection")
application = channels.routing.ProtocolTypeRouter(
{
"websocket": channels.routing.URLRouter(
[
django.urls.path(
"graphql-connection-error/", MyGraphqlWsConsumerConnectionError
)
]
)
}
)
# Channels communicator to test WebSocket consumers.
comm = ch_testing.WebsocketCommunicator(
application=application,
path="graphql-connection-error/",
subprotocols=["graphql-ws"],
)
print("Try to initialize the connection.")
await comm.connect(timeout=TIMEOUT)
await comm.send_json_to({"type": "connection_init", "payload": ""})
resp = await comm.receive_json_from(timeout=TIMEOUT)
assert resp["type"] == "connection_error"
assert resp["payload"]["message"] == "Reject connection"
resp = await comm.receive_output(timeout=TIMEOUT)
assert resp["type"] == "websocket.close"
assert resp["code"] == 4000
print("Disconnect and wait the application to finish gracefully.")
"TEST_CONFIG": {"expiry": 100500,},
},
}
layer = channel_layers.make_test_backend(DEFAULT_CHANNEL_LAYER)
class TestConsumer(AsyncAPIConsumer):
async def accept(self):
await TestConsumer.user_change.subscribe(self)
await super().accept()
@model_observer(get_user_model())
async def user_change(self, message, **kwargs):
await self.send_json(message)
communicator1 = WebsocketCommunicator(TestConsumer, "/testws/")
connected, _ = await communicator1.connect()
assert connected
communicator2 = WebsocketCommunicator(TestConsumer, "/testws/")
connected, _ = await communicator2.connect()
assert connected
user = await database_sync_to_async(get_user_model().objects.create)(
username="test", email="test@example.com"
)
response = await communicator1.receive_json_from()
async def test_notification_incoming(settings):
# make sure the WS URL gets published. Note this solves the problem when this test is run,
# but not when all tests are run for the whole repo
settings.EDD_USE_PROTOTYPE_IMPORT = True
communicator = WebsocketCommunicator(asgi.application, "/ws/import/")
try:
# force login with fake user
user = factory.UserFactory.build()
communicator.scope["user"] = user
# set up back-end broker for sending messages
ws = backend.ImportWsBroker(user)
# websocket will allow connection
connected, subprotocol = await communicator.connect()
assert connected
# send a message from the back end
await ws.async_notify(
"Test message", tags=["import-status-update"], payload={"key": 12345}
)
async def test_consumer_schema_execution():
communicator = WebsocketCommunicator(GraphqlSubscriptionConsumer, "/graphql/")
connected, subprotocol = await communicator.connect()
assert connected
s = SomeModel()
await sync_to_async(s.save)()
await communicator.receive_nothing(timeout=1)