async def test_async_views_concurrent_execution(sentry_init, capture_events, settings): import asyncio import time settings.MIDDLEWARE = [] asgi_application.load_middleware(is_async=True) sentry_init(integrations=[DjangoIntegration()], send_default_pii=True) comm = HttpCommunicator(asgi_application, "GET", "/my_async_view") comm2 = HttpCommunicator(asgi_application, "GET", "/my_async_view") loop = asyncio.get_event_loop() start = time.time() r1 = loop.create_task(comm.get_response(timeout=5)) r2 = loop.create_task(comm2.get_response(timeout=5)) (resp1, resp2), _ = await asyncio.wait({r1, r2}) end = time.time() assert resp1.result()["status"] == 200 assert resp2.result()["status"] == 200 assert end - start < 1.5
async def test_muliple_sessions(): """ Create two application instances and test then out of order to verify that separate scopes are used. """ async def inner(scope, receive, send): send(scope["path"]) class SimpleHttpApp(AsyncConsumer): async def http_request(self, event): await database_sync_to_async(self.scope["session"].save)() assert self.scope["method"] == "GET" await self.send({ "type": "http.response.start", "status": 200, "headers": [] }) await self.send({ "type": "http.response.body", "body": self.scope["path"].encode() }) app = SessionMiddlewareStack(SimpleHttpApp.as_asgi()) first_communicator = HttpCommunicator(app, "GET", "/first/") second_communicator = HttpCommunicator(app, "GET", "/second/") second_response = await second_communicator.get_response() assert second_response["body"] == b"/second/" first_response = await first_communicator.get_response() assert first_response["body"] == b"/first/"
async def test_per_scope_consumers(): """ Tests that a distinct consumer is used per scope, with AsyncHttpConsumer as the example consumer class. """ class TestConsumer(AsyncHttpConsumer): def __init__(self): super().__init__() self.time = time.time() async def handle(self, body): body = f"{self.__class__.__name__} {id(self)} {self.time}" await self.send_response( 200, body.encode("utf-8"), headers={b"Content-Type": b"text/plain"}, ) app = TestConsumer.as_asgi() # Open a connection communicator = HttpCommunicator(app, method="GET", path="/test/") response = await communicator.get_response() assert response["status"] == 200 # And another one. communicator = HttpCommunicator(app, method="GET", path="/test2/") second_response = await communicator.get_response() assert second_response["status"] == 200 assert response["body"] != second_response["body"]
async def test_body(): user, order, notify_user = await database_sync_to_async(init_db)() communicator = WebsocketCommunicator( consumers.ChatConsumer, "/ws/customer-service/%d/" % order.id, ) communicator.scope["user"] = user communicator.scope["url_route"] = { "kwargs": { "order_id": order.id } } connected, _ = await communicator.connect() self.assertTrue(connected) await communicator.send_json_to({"type": "heartbeat"}) await communicator.disconnect() communicator = HttpCommunicator( consumers.ChatNotifyConsumer, "GET", "/customer-service/notify/", ) communicator.scope["user"] = notify_user communicator.scope["query_string"] = "nopoll" response = await communicator.get_response() self.assertTrue(response["body"].startswith(b"data: ")) payload = response["body"][6:] data = json.loads(payload.decode("utf8")) self.assertEquals( data, [{ "link": "/customer-service/%d/" % order.id, "text": "%d ([email protected])" % order.id, }], "expecting someone in the room but noone found", ) await asyncio.sleep(10) communicator = HttpCommunicator( consumers.ChatNotifyConsumer, "GET", "/customer-service/notify/", ) communicator.scope["user"] = notify_user communicator.scope["query_string"] = "nopoll" response = await communicator.get_response() self.assertTrue(response["body"].startswith(b"data: ")) payload = response["body"][6:] data = json.loads(payload.decode("utf8")) self.assertEquals( data, [], "expecting noone in the room but someone found", )
async def test_async_http_consumer(): """ Tests that AsyncHttpConsumer is implemented correctly. """ class TestConsumer(AsyncHttpConsumer): async def handle(self, body): data = json.loads(body.decode("utf-8")) await self.send_response( 200, json.dumps({ "value": data["value"] }).encode("utf-8"), headers={b"Content-Type": b"application/json"}, ) app = TestConsumer() # Open a connection communicator = HttpCommunicator( app, method="POST", path="/test/", body=json.dumps({ "value": 42, "anything": False }).encode("utf-8"), ) response = await communicator.get_response() assert response["body"] == b'{"value": 42}' assert response["status"] == 200 assert response["headers"] == [(b"Content-Type", b"application/json")]
async def test_async_middleware_spans(sentry_init, render_span_tree, capture_events, settings): settings.MIDDLEWARE = [ "django.contrib.sessions.middleware.SessionMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "tests.integrations.django.myapp.settings.TestMiddleware", ] asgi_application.load_middleware(is_async=True) sentry_init( integrations=[DjangoIntegration(middleware_spans=True)], traces_sample_rate=1.0, _experiments={"record_sql_params": True}, ) events = capture_events() comm = HttpCommunicator(asgi_application, "GET", "/async_message") response = await comm.get_response() assert response["status"] == 200 await comm.wait() message, transaction = events assert (render_span_tree(transaction) == """\ - op="http.server": description=null - op="django.middleware": description="django.contrib.sessions.middleware.SessionMiddleware.__acall__" - op="django.middleware": description="django.contrib.auth.middleware.AuthenticationMiddleware.__acall__" - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.__acall__" - op="django.middleware": description="tests.integrations.django.myapp.settings.TestMiddleware.__acall__" - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - op="django.view": description="async_message\"""")
async def test_async_http_consumer(): """ Tests that AsyncHttpConsumer is implemented correctly. """ class TestConsumer(AsyncHttpConsumer): async def handle(self, body): self.is_streaming = True await self.send_headers(headers=[ (b"Cache-Control", b"no-cache"), (b"Content-Type", b"text/event-stream"), (b"Transfer-Encoding", b"chunked"), ]) asyncio.get_event_loop().create_task(self.stream()) async def stream(self): for n in range(0, 3): if not self.is_streaming: break payload = "data: %d\n\n" % (n + 1) await self.send_body(payload.encode("utf-8"), more_body=True) await asyncio.sleep(0.2) await self.send_body(b"") async def disconnect(self): self.is_streaming = False # Open a connection communicator = HttpCommunicator(TestConsumer, method="GET", path="/test/", body=b"") response = await communicator.get_response() assert response["body"] == b"data: 1\n\ndata: 2\n\ndata: 3\n\n" assert response["status"] == 200
async def test_sessions(): app = SimpleHttpApp() communicator = HttpCommunicator(SessionMiddlewareStack(app), "GET", "/test/") response = await communicator.get_response() headers = response.get("headers", []) assert len(headers) == 1 name, value = headers[0] assert name == b"Set-Cookie" value = value.decode("utf-8") assert re.compile(r"sessionid=").search(value) is not None assert re.compile(r"expires=").search(value) is not None assert re.compile(r"HttpOnly").search(value) is not None assert re.compile(r"Max-Age").search(value) is not None assert re.compile(r"Path").search(value) is not None samesite = re.compile(r"SameSite=(\w+)").search(value) assert samesite is not None assert samesite.group(1) == "Lax"
async def test_basic(sentry_init, capture_events, application): sentry_init(integrations=[DjangoIntegration()], send_default_pii=True) events = capture_events() comm = HttpCommunicator(application, "GET", "/view-exc?test=query") response = await comm.get_response() assert response["status"] == 500 event, = events exception, = event["exception"]["values"] assert exception["type"] == "ZeroDivisionError" # Test that the ASGI middleware got set up correctly. Right now this needs # to be installed manually (see myapp/asgi.py) assert event["transaction"] == "/view-exc" assert event["request"] == { "cookies": {}, "headers": {}, "method": "GET", "query_string": "test=query", "url": "/view-exc", } capture_message("hi") event = events[-1] assert "request" not in event
async def test_body(): user, order = await database_sync_to_async(init_db)() awaitable_requestor = asyncio.coroutine( MagicMock(return_value=b"SHIPPED")) with patch.object(consumers.OrderTrackerConsumer, "query_remote_server") as mock_requestor: mock_requestor.side_effect = awaitable_requestor communicator = HttpCommunicator( consumers.OrderTrackerConsumer, "GET", "/mobile-api/my-orders/%d/tracker/" % order.id, ) communicator.scope["user"] = user communicator.scope["url_route"] = { "kwargs": { "order_id": order.id } } response = await communicator.get_response() data = response["body"].decode("utf8") mock_requestor.assert_called_once() self.assertEquals(data, "SHIPPED")
async def test_session_samesite_invalid(samesite_invalid): app = SimpleHttpApp() communicator = HttpCommunicator(SessionMiddlewareStack(app), "GET", "/test/") with pytest.raises(AssertionError): await communicator.get_response()
async def test_http_communicator(): """ Tests that the HTTP communicator class works at a basic level. """ communicator = HttpCommunicator(SimpleHttpApp, "GET", "/test/?foo=bar") response = await communicator.get_response() assert response["body"] == b"test response" assert response["status"] == 200
async def test_body(): user, order, cs_user = await database_sync_to_async(init_db)() communicator = WebsocketCommunicator( consumers.ChatConsumer, "/ws/me2ushop/customer-service/%d/" % order.id, ) communicator.scope['user'] = user communicator.scope['url_route'] = { 'kwargs': { 'order_id': order.id } } connected, _ = await communicator.connect() self.assertTrue(connected) await communicator.send_json_to({'type': 'heartbeat'}) await communicator.disconnect() communicator = HttpCommunicator( consumers.ChatNotifyConsumer, 'GET', 'me2ushop/customer-service/notify/') communicator.scope['user'] = cs_user communicator.scope['query_string'] = 'nopoll' response = await communicator.get_response() self.assertTrue(response["body"].startswith(b"data: ")) payload = response['body'][6:] data = json.loads(payload.decode('utf8')) self.assertEquals( data, [{ "link": "/me2ushop/customer-service/%d/" % order.id, "text": "%d ([email protected])" % order.id, }], 'expecting someone in the room but on one found') await asyncio.sleep(10) communicator = HttpCommunicator( consumers.ChatNotifyConsumer, 'GET', 'me2ushop/customer-service/notify/') communicator.scope['user'] = cs_user communicator.scope['query_string'] = 'nopoll' response = await communicator.get_response() self.assertTrue(response["body"].startswith(b"data: ")) payload = response['body'][6:] data = json.loads(payload.decode('utf8')) self.assertEquals( data, [], 'expecting on one in the room but someone found')
async def get(self, path, headers=None, user=None): if user: headers = await self._login(headers, user) communicator = HttpCommunicator(self.app, method='GET', path=path, headers=headers) r = await communicator.get_response() return Response(**r)
async def post(self, path, body=None, headers=None, user=None): if not isinstance(body, bytes): data = body or {} body = dumps(data).encode('utf-8') if user: headers = await self._login(headers, user) communicator = HttpCommunicator(self.app, method='POST', path=path, body=body, headers=headers) r = await communicator.get_response() return Response(**r)
async def test_session_samesite(samesite, settings): app = SimpleHttpApp() communicator = HttpCommunicator(SessionMiddlewareStack(app), "GET", "/test/") response = await communicator.get_response() headers = response.get("headers", []) assert len(headers) == 1 name, value = headers[0] assert name == b"Set-Cookie" value = value.decode("utf-8") samesite = re.compile(r"SameSite=(\w+)").search(value) assert samesite is not None assert samesite.group(1) == settings.SESSION_COOKIE_SAMESITE
async def test_async_views(sentry_init, capture_events, application): sentry_init(integrations=[DjangoIntegration()], send_default_pii=True) events = capture_events() comm = HttpCommunicator(application, "GET", "/async_message") response = await comm.get_response() assert response["status"] == 200 (event, ) = events assert event["transaction"] == "/async_message" assert event["request"] == { "cookies": {}, "headers": {}, "method": "GET", "query_string": None, "url": "/async_message", }
async def test_sessions(): class SimpleHttpApp(AsyncConsumer): """ Barebones HTTP ASGI app for testing. """ async def http_request(self, event): await database_sync_to_async(self.scope["session"].save)() assert self.scope["path"] == "/test/" assert self.scope["method"] == "GET" await self.send({ "type": "http.response.start", "status": 200, "headers": [] }) await self.send({ "type": "http.response.body", "body": b"test response" }) app = SimpleHttpApp() communicator = HttpCommunicator(SessionMiddlewareStack(app), "GET", "/test/") response = await communicator.get_response() headers = response.get("headers", []) assert len(headers) == 1 name, value = headers[0] assert name == b"Set-Cookie" value = value.decode("utf-8") assert re.compile(r"sessionid=").search(value) is not None assert re.compile(r"expires=").search(value) is not None assert re.compile(r"HttpOnly").search(value) is not None assert re.compile(r"Max-Age").search(value) is not None assert re.compile(r"Path").search(value) is not None
async def test_my_consumer(): communicator = HttpCommunicator(NotificationConsumer, "GET", "/test/") response = await communicator.get_response() assert response["body"] == b"test response" assert response["status"] == 200 connected, _ = await communicator.connect() assert connected await communicator.send_json_to({ "model": "as.Appropriate", "id": str(Foo.id), }) assert await communicator.receive_nothing() await update_foo() response = await communicator.receive_json_from() assert response == { # ... whatever you expect } await communicator.disconnect()
async def test_file_uploading(): body = ( b"--BOUNDARY\r\n" + b'Content-Disposition: form-data; name="title"\r\n\r\n' + b"My First Book\r\n" + b"--BOUNDARY\r\n" + b'Content-Disposition: form-data; name="pdf"; filename="book.pdf"\r\n\r\n' + b"FAKEPDFBYTESGOHERE" + b"--BOUNDARY--") headers = { "content-type": b"multipart/form-data; boundary=BOUNDARY", "content-length": str(len(body)).encode("ascii"), } class SimpleHttpApp(AsyncConsumer): """ Barebones HTTP ASGI app for testing. """ async def http_request(self, event): # self.scope["session"].save() assert self.scope["path"] == "/test_upload/" assert self.scope["method"] == "POST" await self.send({ "type": "http.response.start", "status": 201, "headers": [], }) await self.send({ "type": "http.response.body", "body": b'{"result": "great success!"}', }) communicator = HttpCommunicator(SimpleHttpApp, "POST", "/test_upload/", body=body, headers=headers) response = await communicator.get_response() assert response["body"] == b'{"result": "great success!"}' assert response["status"] == 201
async def test_body(): user, order = await database_sync_to_async(init_db)() awaitable_reqestor = asyncio.coroutine( MagicMock(return_value=b"SHIPPED")) with patch.object(consumers.OrderTrackerConsumer, 'query_remote_server') as mock_requestor: mock_requestor.side_effect = awaitable_reqestor communicator = HttpCommunicator( consumers.OrderTrackerConsumer, 'GET', '/mobile-api/my-orders/%d/tracker/' % order.id, ) communicator.scope['user'] = user communicator.scope['url_route'] = { 'kwargs': { 'order_id': order.id } } response = await communicator.get_response() data = response['body'].decode('utf8') mock_requestor.assert_called_once() self.assertEquals(data, 'SHIPPED')
async def test_async_http_consumer_with_channel_layer(): """ Tests that AsyncHttpConsumer is implemented correctly. """ class TestConsumer(AsyncHttpConsumer): """ Abstract consumer that provides a method that handles running a command and getting a response on a device. """ channel_layer_alias = "testlayer" async def handle(self, body): # Add consumer to a known test group that we will use to send events to. await self.channel_layer.group_add("test_group", self.channel_name) await self.send_headers(status=200, headers=[(b"Content-Type", b"application/json")]) async def send_to_long_poll(self, event): received_data = str(event["data"]).encode("utf8") # We just echo what we receive, and close the response. await self.send_body(received_data, more_body=False) channel_layers_setting = { "testlayer": { "BACKEND": "channels.layers.InMemoryChannelLayer" } } with override_settings(CHANNEL_LAYERS=channel_layers_setting): # Open a connection communicator = HttpCommunicator( TestConsumer, method="POST", path="/test/", body=json.dumps({ "value": 42, "anything": False }).encode("utf-8"), ) # We issue the HTTP request await communicator.send_request() # Gets the response start (status and headers) response_start = await communicator.get_response_start(timeout=1) # Make sure that the start of the response looks good so far. assert response_start["status"] == 200 assert response_start["headers"] == [(b"Content-Type", b"application/json")] # Send now a message to the consumer through the channel layer. Using the known test_group. channel_layer = get_channel_layer("testlayer") await channel_layer.group_send( "test_group", { "type": "send.to.long.poll", "data": "hello from channel layer" }, ) # Now we should be able to get the message back on the remaining chunk of body. body = await communicator.get_body_chunk(timeout=1) assert body == b"hello from channel layer"
async def test_my_consumer(): communicator = HttpCommunicator(ChatConsumer, "GET", "/test/") response = await communicator.get_response() assert response["body"] == b"test response" assert response["status"] == 200
async def test_my_consumer(): communicator = HttpCommunicator(TickerConsumer, "GET", "/test/") response = await communicator.get_response() self.assertEqual(response["body"], b"test response") self.assertEqual(response["status"], 200)
async def test_news_collector_consumer(): communicator = HttpCommunicator(NewsCollectorAsyncConsumer, "GET", "/collector/collect_news_async/") response = await communicator.get_response() assert response["status"] == 200
async def test_0090_test_consumer(self): communicator = HttpCommunicator(WSConsumer, 'GET', '/communication/websocket') response = await communicator.get_response() self.assertTrue(response['status'] == 200)