tests.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import sys
  2. from asgiref.sync import async_to_sync
  3. from asgiref.testing import ApplicationCommunicator
  4. from django.core.asgi import get_asgi_application
  5. from django.core.signals import request_started
  6. from django.db import close_old_connections
  7. from django.test import SimpleTestCase, override_settings
  8. from .urls import test_filename
  9. @override_settings(ROOT_URLCONF='asgi.urls')
  10. class ASGITest(SimpleTestCase):
  11. def setUp(self):
  12. request_started.disconnect(close_old_connections)
  13. def _get_scope(self, **kwargs):
  14. return {
  15. 'type': 'http',
  16. 'asgi': {'version': '3.0', 'spec_version': '2.1'},
  17. 'http_version': '1.1',
  18. 'method': 'GET',
  19. 'query_string': b'',
  20. 'server': ('testserver', 80),
  21. **kwargs,
  22. }
  23. def tearDown(self):
  24. request_started.connect(close_old_connections)
  25. @async_to_sync
  26. async def test_get_asgi_application(self):
  27. """
  28. get_asgi_application() returns a functioning ASGI callable.
  29. """
  30. application = get_asgi_application()
  31. # Construct HTTP request.
  32. communicator = ApplicationCommunicator(application, self._get_scope(path='/'))
  33. await communicator.send_input({'type': 'http.request'})
  34. # Read the response.
  35. response_start = await communicator.receive_output()
  36. self.assertEqual(response_start['type'], 'http.response.start')
  37. self.assertEqual(response_start['status'], 200)
  38. self.assertEqual(
  39. set(response_start['headers']),
  40. {
  41. (b'Content-Length', b'12'),
  42. (b'Content-Type', b'text/html; charset=utf-8'),
  43. },
  44. )
  45. response_body = await communicator.receive_output()
  46. self.assertEqual(response_body['type'], 'http.response.body')
  47. self.assertEqual(response_body['body'], b'Hello World!')
  48. @async_to_sync
  49. async def test_file_response(self):
  50. """
  51. Makes sure that FileResponse works over ASGI.
  52. """
  53. application = get_asgi_application()
  54. # Construct HTTP request.
  55. communicator = ApplicationCommunicator(application, self._get_scope(path='/file/'))
  56. await communicator.send_input({'type': 'http.request'})
  57. # Get the file content.
  58. with open(test_filename, 'rb') as test_file:
  59. test_file_contents = test_file.read()
  60. # Read the response.
  61. response_start = await communicator.receive_output()
  62. self.assertEqual(response_start['type'], 'http.response.start')
  63. self.assertEqual(response_start['status'], 200)
  64. self.assertEqual(
  65. set(response_start['headers']),
  66. {
  67. (b'Content-Length', str(len(test_file_contents)).encode('ascii')),
  68. (b'Content-Type', b'text/plain' if sys.platform.startswith('win') else b'text/x-python'),
  69. (b'Content-Disposition', b'inline; filename="urls.py"'),
  70. },
  71. )
  72. response_body = await communicator.receive_output()
  73. self.assertEqual(response_body['type'], 'http.response.body')
  74. self.assertEqual(response_body['body'], test_file_contents)