class ContactViewTest(TestCase): url = '/cms/contact' def setUp(self): self.factory = AsyncRequestFactory() self.admin = User.objects.create_user(username='******', email='', password='******') self.admin.is_superuser = True self.company = Company.objects.create(name='Company', street='street', number='1', zipcode='12345', city='city') self.contact = Contact.objects.create(username='******', email='', password='******', company=self.company) MailSetting.objects.create(smtp_user='******', smtp_server='localhost', smtp_port=587, smtp_password='******', stmp_use_tls=True) ShopSetting.objects.create(google_recaptcha_publickey='pub', google_recaptcha_privatekey='priv') def test_successful_login(self): request = self.factory.get(ContactViewTest.url) request.user = self.admin response = ContactView.as_view()(request) self.assertEqual(response.status_code, 200) def test_permission_denied_for_loggedin_user(self): request = self.factory.get(ContactViewTest.url) request.user = self.contact self.assertRaises(PermissionDenied) def test_permission_denied_for_anonymous_user(self): request = self.factory.get(ContactViewTest.url) request.user = AnonymousUser() self.assertRaises(PermissionDenied) @skip("Unkown internal http error, to be checked at a later time") def test_post_contact_form(self): request = self.factory.post(ContactViewTest.url, data={ 'name': 'test_user', 'email': '*****@*****.**', 'phone': '088/2654789', 'message': 'This is a message' }) response = ContactView.as_view()(request) self.assertEqual(response.status_code, 200)
class GenericViewTest(TestCase): url = '/cms/home/' def setUp(self): self.factory = AsyncRequestFactory() self.admin = User.objects.create_user(username='******', email='', password='******') self.admin.is_superuser = True self.company = Company.objects.create(name='Company', street='street', number='1', zipcode='12345', city='city') self.contact = Contact.objects.create(username='******', email='', password='******', company=self.company) Page.objects.create(page_id=1, page_name='home') LegalSetting.objects.create(company_name='Test') CacheSetting.objects.create() def test_successful_login(self): request = self.factory.get(GenericViewTest.url) request.LANGUAGE_CODE = 'en' request.user = self.admin response = GenericView.as_view()(request, 'home') self.assertEqual(response.status_code, 200) def test_permission_denied_for_loggedin_user(self): request = self.factory.get(GenericViewTest.url) request.user = self.contact self.assertRaises(PermissionDenied) def test_permission_denied_for_anonymous_user(self): request = self.factory.get(GenericViewTest.url) request.user = AnonymousUser() self.assertRaises(PermissionDenied) def test_page_not_found(self): request = self.factory.get('/cms/not-found') request.LANGUAGE_CODE = 'en' request.user = self.admin response = GenericView.as_view()(request, 'not-found') self.assertEqual(response.status_code, 404)
def setUp(self): self.factory = AsyncRequestFactory() self.admin = User.objects.create_user(username='******', email='', password='******') self.admin.is_superuser = True self.company = Company.objects.create(name='Company', street='street', number='1', zipcode='12345', city='city') self.contact = Contact.objects.create(username='******', email='', password='******', company=self.company)
class AsyncRequestFactoryTest(SimpleTestCase): request_factory = AsyncRequestFactory() async def test_request_factory(self): tests = ( 'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace', ) for method_name in tests: with self.subTest(method=method_name): async def async_generic_view(request): if request.method.lower() != method_name: return HttpResponseNotAllowed(method_name) return HttpResponse(status=200) method = getattr(self.request_factory, method_name) request = method('/somewhere/') response = await async_generic_view(request) self.assertEqual(response.status_code, 200)
class AsyncRequestFactoryTest(SimpleTestCase): request_factory = AsyncRequestFactory() async def test_request_factory(self): tests = ( 'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace', ) for method_name in tests: with self.subTest(method=method_name): async def async_generic_view(request): if request.method.lower() != method_name: return HttpResponseNotAllowed(method_name) return HttpResponse(status=200) method = getattr(self.request_factory, method_name) request = method('/somewhere/') response = await async_generic_view(request) self.assertEqual(response.status_code, 200) async def test_request_factory_data(self): async def async_generic_view(request): return HttpResponse(status=200, content=request.body) request = self.request_factory.post( '/somewhere/', data={'example': 'data'}, content_type='application/json', ) self.assertEqual(request.headers['content-length'], '19') self.assertEqual(request.headers['content-type'], 'application/json') response = await async_generic_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'{"example": "data"}') def test_request_factory_sets_headers(self): request = self.request_factory.get( '/somewhere/', AUTHORIZATION='Bearer faketoken', X_ANOTHER_HEADER='some other value', ) self.assertEqual(request.headers['authorization'], 'Bearer faketoken') self.assertIn('HTTP_AUTHORIZATION', request.META) self.assertEqual(request.headers['x-another-header'], 'some other value') self.assertIn('HTTP_X_ANOTHER_HEADER', request.META) def test_request_factory_query_string(self): request = self.request_factory.get('/somewhere/', {'example': 'data'}) self.assertNotIn('Query-String', request.headers) self.assertEqual(request.GET['example'], 'data')
class AsyncRequestFactoryTest(SimpleTestCase): request_factory = AsyncRequestFactory() async def test_request_factory(self): tests = ( "get", "post", "put", "patch", "delete", "head", "options", "trace", ) for method_name in tests: with self.subTest(method=method_name): async def async_generic_view(request): if request.method.lower() != method_name: return HttpResponseNotAllowed(method_name) return HttpResponse(status=200) method = getattr(self.request_factory, method_name) request = method("/somewhere/") response = await async_generic_view(request) self.assertEqual(response.status_code, 200) async def test_request_factory_data(self): async def async_generic_view(request): return HttpResponse(status=200, content=request.body) request = self.request_factory.post( "/somewhere/", data={"example": "data"}, content_type="application/json", ) self.assertEqual(request.headers["content-length"], "19") self.assertEqual(request.headers["content-type"], "application/json") response = await async_generic_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'{"example": "data"}') def test_request_factory_sets_headers(self): request = self.request_factory.get( "/somewhere/", AUTHORIZATION="Bearer faketoken", X_ANOTHER_HEADER="some other value", ) self.assertEqual(request.headers["authorization"], "Bearer faketoken") self.assertIn("HTTP_AUTHORIZATION", request.META) self.assertEqual(request.headers["x-another-header"], "some other value") self.assertIn("HTTP_X_ANOTHER_HEADER", request.META) def test_request_factory_query_string(self): request = self.request_factory.get("/somewhere/", {"example": "data"}) self.assertNotIn("Query-String", request.headers) self.assertEqual(request.GET["example"], "data")
class CSSSettingsViewTest(TestCase): url = '/cms/css-setting' def setUp(self): self.factory = AsyncRequestFactory() self.admin = User.objects.create_user(username='******', email='', password='******') self.admin.is_superuser = True self.company = Company.objects.create(name='Company', street='street', number='1', zipcode='12345', city='city') self.contact = Contact.objects.create(username='******', email='', password='******', company=self.company) def test_successful_login(self): request = self.factory.get(CSSSettingsViewTest.url) request.user = self.admin response = CSSSettingsView.as_view()(request) self.assertEqual(response.status_code, 200) def test_permission_denied_for_loggedin_user(self): request = self.factory.get(CSSSettingsViewTest.url) request.user = self.contact self.assertRaises(PermissionDenied) def test_permission_denied_for_anonymous_user(self): request = self.factory.get(CSSSettingsViewTest.url) request.user = AnonymousUser() self.assertRaises(PermissionDenied) @skip("Unkown internal http error, to be checked at a later time") def test_post_csssetting_form(self): request = self.factory.post(CSSSettingsViewTest.url + '1', data={}) request.user = self.admin response = CSSSettingsView.as_view()(request) self.assertEqual(response.status_code, 200)
def setUp(self): self.factory = AsyncRequestFactory() self.admin = User.objects.create_user(username='******', email='', password='******') self.admin.is_superuser = True self.company = Company.objects.create(name='Company', street='street', number='1', zipcode='12345', city='city') self.contact = Contact.objects.create(username='******', email='', password='******', company=self.company) Page.objects.create(page_id=1, page_name='home') LegalSetting.objects.create(company_name='Test') CacheSetting.objects.create()
def setUp(self): self.factory = AsyncRequestFactory() self.admin = User.objects.create_user(username='******', email='', password='******') self.admin.is_superuser = True self.company = Company.objects.create(name='Company', street='street', number='1', zipcode='12345', city='city') self.contact = Contact.objects.create(username='******', email='', password='******', company=self.company) initial_state = OrderState.objects.create(initial=True, name="Start") paid_state = OrderState.objects.create(initial=False, name="Paid", is_paid_state=True) sub_item = ProductSubItem.objects.create(price=10, price_on_request=False, name='product') order_open = OrderDetail.objects.create(company=self.contact.company, contact=self.contact, state=initial_state) OrderItem.objects.create(order_detail=order_open, price=10, tax_rate=0.19, product=sub_item, price_wt=11.9, price_discounted=10, price_discounted_wt=11.9) order_paid = OrderDetail.objects.create(company=self.contact.company, contact=self.contact, state=paid_state) OrderItem.objects.create(order_detail=order_paid, price=10, tax_rate=0.19, product=sub_item, price_wt=11.9, price_discounted=10, price_discounted_wt=11.9)
class PrivacyPolicyViewTest(TestCase): url = '/cms/privacy-policy' def setUp(self): self.factory = AsyncRequestFactory() self.admin = User.objects.create_user(username='******', email='', password='******') self.admin.is_superuser = True self.company = Company.objects.create(name='Company', street='street', number='1', zipcode='12345', city='city') self.contact = Contact.objects.create(username='******', email='', password='******', company=self.company) LegalSetting.objects.create() def test_successful_login(self): request = self.factory.get(PrivacyPolicyViewTest.url) request.user = self.admin response = PrivacyPolicyView.as_view()(request) self.assertEqual(response.status_code, 200) def test_permission_denied_for_loggedin_user(self): request = self.factory.get(PrivacyPolicyViewTest.url) request.user = self.contact self.assertRaises(PermissionDenied) def test_permission_denied_for_anonymous_user(self): request = self.factory.get(PrivacyPolicyViewTest.url) request.user = AnonymousUser() self.assertRaises(PermissionDenied)
def setUp(self): self.factory = AsyncRequestFactory() self.admin = User.objects.create_user(username='******', email='', password='******') self.admin.is_superuser = True self.company = Company.objects.create(name='Company', street='street', number='1', zipcode='12345', city='city') self.contact = Contact.objects.create(username='******', email='', password='******', company=self.company) MailSetting.objects.create(smtp_user='******', smtp_server='localhost', smtp_port=587, smtp_password='******', stmp_use_tls=True) ShopSetting.objects.create(google_recaptcha_publickey='pub', google_recaptcha_privatekey='priv')
class TestASGIStaticFilesHandler(StaticFilesTestCase): async_request_factory = AsyncRequestFactory() async def test_get_async_response(self): request = self.async_request_factory.get("/static/test/file.txt") handler = ASGIStaticFilesHandler(ASGIHandler()) response = await handler.get_response_async(request) response.close() self.assertEqual(response.status_code, 200) async def test_get_async_response_not_found(self): request = self.async_request_factory.get("/static/test/not-found.txt") handler = ASGIStaticFilesHandler(ASGIHandler()) response = await handler.get_response_async(request) self.assertEqual(response.status_code, 404)
class AsyncRequestFactoryTest(SimpleTestCase): request_factory = AsyncRequestFactory() async def test_request_factory(self): tests = ( 'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace', ) for method_name in tests: with self.subTest(method=method_name): async def async_generic_view(request): if request.method.lower() != method_name: return HttpResponseNotAllowed(method_name) return HttpResponse(status=200) method = getattr(self.request_factory, method_name) request = method('/somewhere/') response = await async_generic_view(request) self.assertEqual(response.status_code, 200) async def test_request_factory_data(self): async def async_generic_view(request): return HttpResponse(status=200, content=request.body) request = self.request_factory.post( '/somewhere/', data={'example': 'data'}, content_type='application/json', ) self.assertEqual(request.headers['content-length'], '19') self.assertEqual(request.headers['content-type'], 'application/json') response = await async_generic_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'{"example": "data"}')
class ASGITest(SimpleTestCase): async_request_factory = AsyncRequestFactory() def setUp(self): request_started.disconnect(close_old_connections) def tearDown(self): request_started.connect(close_old_connections) async def test_get_asgi_application(self): """ get_asgi_application() returns a functioning ASGI callable. """ application = get_asgi_application() # Construct HTTP request. scope = self.async_request_factory._base_scope(path="/") communicator = ApplicationCommunicator(application, scope) await communicator.send_input({"type": "http.request"}) # Read the response. response_start = await communicator.receive_output() self.assertEqual(response_start["type"], "http.response.start") self.assertEqual(response_start["status"], 200) self.assertEqual( set(response_start["headers"]), { (b"Content-Length", b"12"), (b"Content-Type", b"text/html; charset=utf-8"), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body["type"], "http.response.body") self.assertEqual(response_body["body"], b"Hello World!") async def test_file_response(self): """ Makes sure that FileResponse works over ASGI. """ application = get_asgi_application() # Construct HTTP request. scope = self.async_request_factory._base_scope(path="/file/") communicator = ApplicationCommunicator(application, scope) await communicator.send_input({"type": "http.request"}) # Get the file content. with open(test_filename, "rb") as test_file: test_file_contents = test_file.read() # Read the response. response_start = await communicator.receive_output() self.assertEqual(response_start["type"], "http.response.start") self.assertEqual(response_start["status"], 200) headers = response_start["headers"] self.assertEqual(len(headers), 3) expected_headers = { b"Content-Length": str(len(test_file_contents)).encode("ascii"), b"Content-Type": b"text/x-python", b"Content-Disposition": b'inline; filename="urls.py"', } for key, value in headers: try: self.assertEqual(value, expected_headers[key]) except AssertionError: # Windows registry may not be configured with correct # mimetypes. if sys.platform == "win32" and key == b"Content-Type": self.assertEqual(value, b"text/plain") else: raise response_body = await communicator.receive_output() self.assertEqual(response_body["type"], "http.response.body") self.assertEqual(response_body["body"], test_file_contents) # Allow response.close() to finish. await communicator.wait() @modify_settings(INSTALLED_APPS={"append": "django.contrib.staticfiles"}) @override_settings( STATIC_URL="static/", STATIC_ROOT=TEST_STATIC_ROOT, STATICFILES_DIRS=[TEST_STATIC_ROOT], STATICFILES_FINDERS=[ "django.contrib.staticfiles.finders.FileSystemFinder", ], ) async def test_static_file_response(self): application = ASGIStaticFilesHandler(get_asgi_application()) # Construct HTTP request. scope = self.async_request_factory._base_scope(path="/static/file.txt") communicator = ApplicationCommunicator(application, scope) await communicator.send_input({"type": "http.request"}) # Get the file content. file_path = TEST_STATIC_ROOT / "file.txt" with open(file_path, "rb") as test_file: test_file_contents = test_file.read() # Read the response. stat = file_path.stat() response_start = await communicator.receive_output() self.assertEqual(response_start["type"], "http.response.start") self.assertEqual(response_start["status"], 200) self.assertEqual( set(response_start["headers"]), { (b"Content-Length", str( len(test_file_contents)).encode("ascii")), (b"Content-Type", b"text/plain"), (b"Content-Disposition", b'inline; filename="file.txt"'), (b"Last-Modified", http_date(stat.st_mtime).encode("ascii")), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body["type"], "http.response.body") self.assertEqual(response_body["body"], test_file_contents) # Allow response.close() to finish. await communicator.wait() async def test_headers(self): application = get_asgi_application() communicator = ApplicationCommunicator( application, self.async_request_factory._base_scope( path="/meta/", headers=[ [b"content-type", b"text/plain; charset=utf-8"], [b"content-length", b"77"], [b"referer", b"Scotland"], [b"referer", b"Wales"], ], ), ) await communicator.send_input({"type": "http.request"}) response_start = await communicator.receive_output() self.assertEqual(response_start["type"], "http.response.start") self.assertEqual(response_start["status"], 200) self.assertEqual( set(response_start["headers"]), { (b"Content-Length", b"19"), (b"Content-Type", b"text/plain; charset=utf-8"), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body["type"], "http.response.body") self.assertEqual(response_body["body"], b"From Scotland,Wales") async def test_get_query_string(self): application = get_asgi_application() for query_string in (b"name=Andrew", "name=Andrew"): with self.subTest(query_string=query_string): scope = self.async_request_factory._base_scope( path="/", query_string=query_string, ) communicator = ApplicationCommunicator(application, scope) await communicator.send_input({"type": "http.request"}) response_start = await communicator.receive_output() self.assertEqual(response_start["type"], "http.response.start") self.assertEqual(response_start["status"], 200) response_body = await communicator.receive_output() self.assertEqual(response_body["type"], "http.response.body") self.assertEqual(response_body["body"], b"Hello Andrew!") async def test_disconnect(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path="/") communicator = ApplicationCommunicator(application, scope) await communicator.send_input({"type": "http.disconnect"}) with self.assertRaises(asyncio.TimeoutError): await communicator.receive_output() async def test_wrong_connection_type(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path="/", type="other") communicator = ApplicationCommunicator(application, scope) await communicator.send_input({"type": "http.request"}) msg = "Django can only handle ASGI/HTTP connections, not other." with self.assertRaisesMessage(ValueError, msg): await communicator.receive_output() async def test_non_unicode_query_string(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path="/", query_string=b"\xff") communicator = ApplicationCommunicator(application, scope) await communicator.send_input({"type": "http.request"}) response_start = await communicator.receive_output() self.assertEqual(response_start["type"], "http.response.start") self.assertEqual(response_start["status"], 400) response_body = await communicator.receive_output() self.assertEqual(response_body["type"], "http.response.body") self.assertEqual(response_body["body"], b"") async def test_request_lifecycle_signals_dispatched_with_thread_sensitive( self): class SignalHandler: """Track threads handler is dispatched on.""" threads = [] def __call__(self, **kwargs): self.threads.append(threading.current_thread()) signal_handler = SignalHandler() request_started.connect(signal_handler) request_finished.connect(signal_handler) # Perform a basic request. application = get_asgi_application() scope = self.async_request_factory._base_scope(path="/") communicator = ApplicationCommunicator(application, scope) await communicator.send_input({"type": "http.request"}) response_start = await communicator.receive_output() self.assertEqual(response_start["type"], "http.response.start") self.assertEqual(response_start["status"], 200) response_body = await communicator.receive_output() self.assertEqual(response_body["type"], "http.response.body") self.assertEqual(response_body["body"], b"Hello World!") # Give response.close() time to finish. await communicator.wait() # AsyncToSync should have executed the signals in the same thread. request_started_thread, request_finished_thread = signal_handler.threads self.assertEqual(request_started_thread, request_finished_thread) request_started.disconnect(signal_handler) request_finished.disconnect(signal_handler) async def test_concurrent_async_uses_multiple_thread_pools(self): sync_waiter.active_threads.clear() # Send 2 requests concurrently application = get_asgi_application() scope = self.async_request_factory._base_scope(path="/wait/") communicators = [] for _ in range(2): communicators.append(ApplicationCommunicator(application, scope)) await communicators[-1].send_input({"type": "http.request"}) # Each request must complete with a status code of 200 # If requests aren't scheduled concurrently, the barrier in the # sync_wait view will time out, resulting in a 500 status code. for communicator in communicators: response_start = await communicator.receive_output() self.assertEqual(response_start["type"], "http.response.start") self.assertEqual(response_start["status"], 200) response_body = await communicator.receive_output() self.assertEqual(response_body["type"], "http.response.body") self.assertEqual(response_body["body"], b"Hello World!") # Give response.close() time to finish. await communicator.wait() # The requests should have scheduled on different threads. Note # active_threads is a set (a thread can only appear once), therefore # length is a sufficient check. self.assertEqual(len(sync_waiter.active_threads), 2) sync_waiter.active_threads.clear()
class AccountingViewTest(TestCase): url = '/accounting' def setUp(self): self.factory = AsyncRequestFactory() self.admin = User.objects.create_user(username='******', email='', password='******') self.admin.is_superuser = True self.company = Company.objects.create(name='Company', street='street', number='1', zipcode='12345', city='city') self.contact = Contact.objects.create(username='******', email='', password='******', company=self.company) initial_state = OrderState.objects.create(initial=True, name="Start") paid_state = OrderState.objects.create(initial=False, name="Paid", is_paid_state=True) sub_item = ProductSubItem.objects.create(price=10, price_on_request=False, name='product') order_open = OrderDetail.objects.create(company=self.contact.company, contact=self.contact, state=initial_state) OrderItem.objects.create(order_detail=order_open, price=10, tax_rate=0.19, product=sub_item, price_wt=11.9, price_discounted=10, price_discounted_wt=11.9) order_paid = OrderDetail.objects.create(company=self.contact.company, contact=self.contact, state=paid_state) OrderItem.objects.create(order_detail=order_paid, price=10, tax_rate=0.19, product=sub_item, price_wt=11.9, price_discounted=10, price_discounted_wt=11.9) def test_successful_login(self): request = self.factory.get(AccountingViewTest.url) request.user = self.admin response = AccountingView.as_view()(request) self.assertEqual(response.status_code, 200) def test_permission_denied_for_loggedin_user(self): request = self.factory.get(AccountingViewTest.url) request.user = self.contact self.assertRaises(PermissionDenied) def test_permission_denied_for_anonymous_user(self): request = self.factory.get(AccountingViewTest.url) request.user = AnonymousUser() self.assertRaises(PermissionDenied) def test_elements_in_context_data(self): request = self.factory.get(AccountingViewTest.url) view = AccountingView() view.setup(request) view.object_list = view.get_queryset() context = view.get_context_data() self.assertIn('total_net', context) self.assertIn('total_gross', context) self.assertIn('counted_open_orders', context) self.assertIn('counted_open_payments', context) self.assertIn('counted_open_shipments', context) self.assertIn('last_orders', context) self.assertIn('open_order_state_id', context) self.assertIn('stock', context) def test_filter_in_context_data(self): request = self.factory.get(AccountingViewTest.url) view = AccountingView() view.setup(request) view.object_list = view.get_queryset() context = view.get_context_data() self.assertEqual(context.get('total_net'), Decimal('20.00')) self.assertEqual(context.get('total_gross'), Decimal('23.8')) self.assertEqual(context.get('counted_open_orders'), 1) self.assertEqual(context.get('counted_open_payments'), 0) self.assertEqual(context.get('counted_open_shipments'), 1) self.assertQuerysetEqual( context.get('last_orders'), map(repr, OrderDetail.objects.all().order_by('-date_added')[:5])) self.assertEqual(context.get('open_order_state_id'), 1)
class ASGITest(SimpleTestCase): async_request_factory = AsyncRequestFactory() def setUp(self): request_started.disconnect(close_old_connections) def tearDown(self): request_started.connect(close_old_connections) async def test_get_asgi_application(self): """ get_asgi_application() returns a functioning ASGI callable. """ application = get_asgi_application() # Construct HTTP request. scope = self.async_request_factory._base_scope(path='/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) # Read the response. response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) self.assertEqual( set(response_start['headers']), { (b'Content-Length', b'12'), (b'Content-Type', b'text/html; charset=utf-8'), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'Hello World!') async def test_file_response(self): """ Makes sure that FileResponse works over ASGI. """ application = get_asgi_application() # Construct HTTP request. scope = self.async_request_factory._base_scope(path='/file/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) # Get the file content. with open(test_filename, 'rb') as test_file: test_file_contents = test_file.read() # Read the response. response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) headers = response_start['headers'] self.assertEqual(len(headers), 3) expected_headers = { b'Content-Length': str(len(test_file_contents)).encode('ascii'), b'Content-Type': b'text/x-python', b'Content-Disposition': b'inline; filename="urls.py"', } for key, value in headers: try: self.assertEqual(value, expected_headers[key]) except AssertionError: # Windows registry may not be configured with correct # mimetypes. if sys.platform == 'win32' and key == b'Content-Type': self.assertEqual(value, b'text/plain') else: raise response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], test_file_contents) # Allow response.close() to finish. await communicator.wait() @modify_settings(INSTALLED_APPS={'append': 'django.contrib.staticfiles'}) @override_settings( STATIC_URL='static/', STATIC_ROOT=TEST_STATIC_ROOT, STATICFILES_DIRS=[TEST_STATIC_ROOT], STATICFILES_FINDERS=[ 'django.contrib.staticfiles.finders.FileSystemFinder', ], ) async def test_static_file_response(self): application = ASGIStaticFilesHandler(get_asgi_application()) # Construct HTTP request. scope = self.async_request_factory._base_scope(path='/static/file.txt') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) # Get the file content. file_path = TEST_STATIC_ROOT / 'file.txt' with open(file_path, 'rb') as test_file: test_file_contents = test_file.read() # Read the response. stat = file_path.stat() response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) self.assertEqual( set(response_start['headers']), { (b'Content-Length', str( len(test_file_contents)).encode('ascii')), (b'Content-Type', b'text/plain'), (b'Content-Disposition', b'inline; filename="file.txt"'), (b'Last-Modified', http_date(stat.st_mtime).encode('ascii')), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], test_file_contents) # Allow response.close() to finish. await communicator.wait() async def test_headers(self): application = get_asgi_application() communicator = ApplicationCommunicator( application, self.async_request_factory._base_scope( path='/meta/', headers=[ [b'content-type', b'text/plain; charset=utf-8'], [b'content-length', b'77'], [b'referer', b'Scotland'], [b'referer', b'Wales'], ], ), ) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) self.assertEqual( set(response_start['headers']), { (b'Content-Length', b'19'), (b'Content-Type', b'text/plain; charset=utf-8'), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'From Scotland,Wales') async def test_get_query_string(self): application = get_asgi_application() for query_string in (b'name=Andrew', 'name=Andrew'): with self.subTest(query_string=query_string): scope = self.async_request_factory._base_scope( path='/', query_string=query_string, ) communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'Hello Andrew!') async def test_disconnect(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.disconnect'}) with self.assertRaises(asyncio.TimeoutError): await communicator.receive_output() async def test_wrong_connection_type(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/', type='other') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) msg = 'Django can only handle ASGI/HTTP connections, not other.' with self.assertRaisesMessage(ValueError, msg): await communicator.receive_output() async def test_non_unicode_query_string(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/', query_string=b'\xff') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 400) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'') async def test_request_lifecycle_signals_dispatched_with_thread_sensitive( self): class SignalHandler: """Track threads handler is dispatched on.""" threads = [] def __call__(self, **kwargs): self.threads.append(threading.current_thread()) signal_handler = SignalHandler() request_started.connect(signal_handler) request_finished.connect(signal_handler) # Perform a basic request. application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'Hello World!') # Give response.close() time to finish. await communicator.wait() # At this point, AsyncToSync does not have a current executor. Thus # SyncToAsync falls-back to .single_thread_executor. target_thread = next(iter(SyncToAsync.single_thread_executor._threads)) request_started_thread, request_finished_thread = signal_handler.threads self.assertEqual(request_started_thread, target_thread) self.assertEqual(request_finished_thread, target_thread) request_started.disconnect(signal_handler) request_finished.disconnect(signal_handler)
class ASGITest(SimpleTestCase): async_request_factory = AsyncRequestFactory() def setUp(self): request_started.disconnect(close_old_connections) def tearDown(self): request_started.connect(close_old_connections) async def test_get_asgi_application(self): """ get_asgi_application() returns a functioning ASGI callable. """ application = get_asgi_application() # Construct HTTP request. scope = self.async_request_factory._base_scope(path='/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) # Read the response. response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) self.assertEqual( set(response_start['headers']), { (b'Content-Length', b'12'), (b'Content-Type', b'text/html; charset=utf-8'), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'Hello World!') async def test_file_response(self): """ Makes sure that FileResponse works over ASGI. """ application = get_asgi_application() # Construct HTTP request. scope = self.async_request_factory._base_scope(path='/file/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) # Get the file content. with open(test_filename, 'rb') as test_file: test_file_contents = test_file.read() # Read the response. response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) self.assertEqual( set(response_start['headers']), { (b'Content-Length', str( len(test_file_contents)).encode('ascii')), (b'Content-Type', b'text/plain' if sys.platform == 'win32' else b'text/x-python'), (b'Content-Disposition', b'inline; filename="urls.py"'), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], test_file_contents) # Allow response.close() to finish. await communicator.wait() async def test_headers(self): application = get_asgi_application() communicator = ApplicationCommunicator( application, self.async_request_factory._base_scope( path='/meta/', headers=[ [b'content-type', b'text/plain; charset=utf-8'], [b'content-length', b'77'], [b'referer', b'Scotland'], [b'referer', b'Wales'], ], ), ) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) self.assertEqual( set(response_start['headers']), { (b'Content-Length', b'19'), (b'Content-Type', b'text/plain; charset=utf-8'), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'From Scotland,Wales') async def test_get_query_string(self): application = get_asgi_application() for query_string in (b'name=Andrew', 'name=Andrew'): with self.subTest(query_string=query_string): scope = self.async_request_factory._base_scope( path='/', query_string=query_string, ) communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'Hello Andrew!') async def test_disconnect(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.disconnect'}) with self.assertRaises(asyncio.TimeoutError): await communicator.receive_output() async def test_wrong_connection_type(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/', type='other') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) msg = 'Django can only handle ASGI/HTTP connections, not other.' with self.assertRaisesMessage(ValueError, msg): await communicator.receive_output() async def test_non_unicode_query_string(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/', query_string=b'\xff') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 400) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'') async def test_request_lifecycle_signals_dispatched_with_thread_sensitive( self): class SignalHandler: """Track threads handler is dispatched on.""" threads = [] def __call__(self, **kwargs): self.threads.append(threading.current_thread()) signal_handler = SignalHandler() request_started.connect(signal_handler) request_finished.connect(signal_handler) # Perform a basic request. application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'Hello World!') # Give response.close() time to finish. await communicator.wait() # At this point, AsyncToSync does not have a current executor. Thus # SyncToAsync falls-back to .single_thread_executor. target_thread = next(iter(SyncToAsync.single_thread_executor._threads)) request_started_thread, request_finished_thread = signal_handler.threads self.assertEqual(request_started_thread, target_thread) self.assertEqual(request_finished_thread, target_thread) request_started.disconnect(signal_handler) request_finished.disconnect(signal_handler)
class ASGITest(SimpleTestCase): async_request_factory = AsyncRequestFactory() def setUp(self): request_started.disconnect(close_old_connections) def tearDown(self): request_started.connect(close_old_connections) async def test_get_asgi_application(self): """ get_asgi_application() returns a functioning ASGI callable. """ application = get_asgi_application() # Construct HTTP request. scope = self.async_request_factory._base_scope(path='/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) # Read the response. response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) self.assertEqual( set(response_start['headers']), { (b'Content-Length', b'12'), (b'Content-Type', b'text/html; charset=utf-8'), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'Hello World!') async def test_file_response(self): """ Makes sure that FileResponse works over ASGI. """ application = get_asgi_application() # Construct HTTP request. scope = self.async_request_factory._base_scope(path='/file/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) # Get the file content. with open(test_filename, 'rb') as test_file: test_file_contents = test_file.read() # Read the response. response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) self.assertEqual( set(response_start['headers']), { (b'Content-Length', str( len(test_file_contents)).encode('ascii')), (b'Content-Type', b'text/plain' if sys.platform == 'win32' else b'text/x-python'), (b'Content-Disposition', b'inline; filename="urls.py"'), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], test_file_contents) # Allow response.close() to finish. await communicator.wait() async def test_headers(self): application = get_asgi_application() communicator = ApplicationCommunicator( application, self.async_request_factory._base_scope( path='/meta/', headers=[ [b'content-type', b'text/plain; charset=utf-8'], [b'content-length', b'77'], [b'referer', b'Scotland'], [b'referer', b'Wales'], ], ), ) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) self.assertEqual( set(response_start['headers']), { (b'Content-Length', b'19'), (b'Content-Type', b'text/plain; charset=utf-8'), }, ) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'From Scotland,Wales') async def test_get_query_string(self): application = get_asgi_application() for query_string in (b'name=Andrew', 'name=Andrew'): with self.subTest(query_string=query_string): scope = self.async_request_factory._base_scope( path='/', query_string=query_string, ) communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 200) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'Hello Andrew!') async def test_disconnect(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.disconnect'}) with self.assertRaises(asyncio.TimeoutError): await communicator.receive_output() async def test_wrong_connection_type(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/', type='other') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) msg = 'Django can only handle ASGI/HTTP connections, not other.' with self.assertRaisesMessage(ValueError, msg): await communicator.receive_output() async def test_non_unicode_query_string(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(path='/', query_string=b'\xff') communicator = ApplicationCommunicator(application, scope) await communicator.send_input({'type': 'http.request'}) response_start = await communicator.receive_output() self.assertEqual(response_start['type'], 'http.response.start') self.assertEqual(response_start['status'], 400) response_body = await communicator.receive_output() self.assertEqual(response_body['type'], 'http.response.body') self.assertEqual(response_body['body'], b'')