tests.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import os
  2. import sys
  3. from unittest import mock, skipIf
  4. from asgiref.sync import async_to_sync
  5. from django.core.exceptions import SynchronousOnlyOperation
  6. from django.test import SimpleTestCase
  7. from django.utils.asyncio import async_unsafe
  8. from .models import SimpleModel
  9. @skipIf(sys.platform == 'win32' and (3, 8, 0) < sys.version_info < (3, 8, 1), 'https://bugs.python.org/issue38563')
  10. class DatabaseConnectionTest(SimpleTestCase):
  11. """A database connection cannot be used in an async context."""
  12. @async_to_sync
  13. async def test_get_async_connection(self):
  14. with self.assertRaises(SynchronousOnlyOperation):
  15. list(SimpleModel.objects.all())
  16. @skipIf(sys.platform == 'win32' and (3, 8, 0) < sys.version_info < (3, 8, 1), 'https://bugs.python.org/issue38563')
  17. class AsyncUnsafeTest(SimpleTestCase):
  18. """
  19. async_unsafe decorator should work correctly and returns the correct
  20. message.
  21. """
  22. @async_unsafe
  23. def dangerous_method(self):
  24. return True
  25. @async_to_sync
  26. async def test_async_unsafe(self):
  27. # async_unsafe decorator catches bad access and returns the right
  28. # message.
  29. msg = (
  30. 'You cannot call this from an async context - use a thread or '
  31. 'sync_to_async.'
  32. )
  33. with self.assertRaisesMessage(SynchronousOnlyOperation, msg):
  34. self.dangerous_method()
  35. @mock.patch.dict(os.environ, {'DJANGO_ALLOW_ASYNC_UNSAFE': 'true'})
  36. @async_to_sync
  37. async def test_async_unsafe_suppressed(self):
  38. # Decorator doesn't trigger check when the environment variable to
  39. # suppress it is set.
  40. try:
  41. self.dangerous_method()
  42. except SynchronousOnlyOperation:
  43. self.fail('SynchronousOnlyOperation should not be raised.')