test_http.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import datetime
  2. from asgiref.sync import iscoroutinefunction
  3. from django.http import HttpRequest, HttpResponse, HttpResponseNotAllowed
  4. from django.test import SimpleTestCase
  5. from django.views.decorators.http import condition, require_http_methods, require_safe
  6. class RequireHttpMethodsTest(SimpleTestCase):
  7. def test_wrapped_sync_function_is_not_coroutine_function(self):
  8. def sync_view(request):
  9. return HttpResponse()
  10. wrapped_view = require_http_methods(["GET"])(sync_view)
  11. self.assertIs(iscoroutinefunction(wrapped_view), False)
  12. def test_wrapped_async_function_is_coroutine_function(self):
  13. async def async_view(request):
  14. return HttpResponse()
  15. wrapped_view = require_http_methods(["GET"])(async_view)
  16. self.assertIs(iscoroutinefunction(wrapped_view), True)
  17. def test_require_http_methods_methods(self):
  18. @require_http_methods(["GET", "PUT"])
  19. def my_view(request):
  20. return HttpResponse("OK")
  21. request = HttpRequest()
  22. request.method = "GET"
  23. self.assertIsInstance(my_view(request), HttpResponse)
  24. request.method = "PUT"
  25. self.assertIsInstance(my_view(request), HttpResponse)
  26. request.method = "HEAD"
  27. self.assertIsInstance(my_view(request), HttpResponseNotAllowed)
  28. request.method = "POST"
  29. self.assertIsInstance(my_view(request), HttpResponseNotAllowed)
  30. request.method = "DELETE"
  31. self.assertIsInstance(my_view(request), HttpResponseNotAllowed)
  32. async def test_require_http_methods_methods_async_view(self):
  33. @require_http_methods(["GET", "PUT"])
  34. async def my_view(request):
  35. return HttpResponse("OK")
  36. request = HttpRequest()
  37. request.method = "GET"
  38. self.assertIsInstance(await my_view(request), HttpResponse)
  39. request.method = "PUT"
  40. self.assertIsInstance(await my_view(request), HttpResponse)
  41. request.method = "HEAD"
  42. self.assertIsInstance(await my_view(request), HttpResponseNotAllowed)
  43. request.method = "POST"
  44. self.assertIsInstance(await my_view(request), HttpResponseNotAllowed)
  45. request.method = "DELETE"
  46. self.assertIsInstance(await my_view(request), HttpResponseNotAllowed)
  47. class RequireSafeDecoratorTest(SimpleTestCase):
  48. def test_require_safe_accepts_only_safe_methods(self):
  49. def my_view(request):
  50. return HttpResponse("OK")
  51. my_safe_view = require_safe(my_view)
  52. request = HttpRequest()
  53. request.method = "GET"
  54. self.assertIsInstance(my_safe_view(request), HttpResponse)
  55. request.method = "HEAD"
  56. self.assertIsInstance(my_safe_view(request), HttpResponse)
  57. request.method = "POST"
  58. self.assertIsInstance(my_safe_view(request), HttpResponseNotAllowed)
  59. request.method = "PUT"
  60. self.assertIsInstance(my_safe_view(request), HttpResponseNotAllowed)
  61. request.method = "DELETE"
  62. self.assertIsInstance(my_safe_view(request), HttpResponseNotAllowed)
  63. async def test_require_safe_accepts_only_safe_methods_async_view(self):
  64. @require_safe
  65. async def async_view(request):
  66. return HttpResponse("OK")
  67. request = HttpRequest()
  68. request.method = "GET"
  69. self.assertIsInstance(await async_view(request), HttpResponse)
  70. request.method = "HEAD"
  71. self.assertIsInstance(await async_view(request), HttpResponse)
  72. request.method = "POST"
  73. self.assertIsInstance(await async_view(request), HttpResponseNotAllowed)
  74. request.method = "PUT"
  75. self.assertIsInstance(await async_view(request), HttpResponseNotAllowed)
  76. request.method = "DELETE"
  77. self.assertIsInstance(await async_view(request), HttpResponseNotAllowed)
  78. class ConditionDecoratorTest(SimpleTestCase):
  79. def etag_func(request, *args, **kwargs):
  80. return '"b4246ffc4f62314ca13147c9d4f76974"'
  81. def latest_entry(request, *args, **kwargs):
  82. return datetime.datetime(2023, 1, 2, 23, 21, 47)
  83. def test_wrapped_sync_function_is_not_coroutine_function(self):
  84. def sync_view(request):
  85. return HttpResponse()
  86. wrapped_view = condition(
  87. etag_func=self.etag_func, last_modified_func=self.latest_entry
  88. )(sync_view)
  89. self.assertIs(iscoroutinefunction(wrapped_view), False)
  90. def test_wrapped_async_function_is_coroutine_function(self):
  91. async def async_view(request):
  92. return HttpResponse()
  93. wrapped_view = condition(
  94. etag_func=self.etag_func, last_modified_func=self.latest_entry
  95. )(async_view)
  96. self.assertIs(iscoroutinefunction(wrapped_view), True)
  97. def test_condition_decorator(self):
  98. @condition(
  99. etag_func=self.etag_func,
  100. last_modified_func=self.latest_entry,
  101. )
  102. def my_view(request):
  103. return HttpResponse()
  104. request = HttpRequest()
  105. request.method = "GET"
  106. response = my_view(request)
  107. self.assertEqual(response.status_code, 200)
  108. self.assertEqual(response.headers["ETag"], '"b4246ffc4f62314ca13147c9d4f76974"')
  109. self.assertEqual(
  110. response.headers["Last-Modified"],
  111. "Mon, 02 Jan 2023 23:21:47 GMT",
  112. )
  113. async def test_condition_decorator_async_view(self):
  114. @condition(
  115. etag_func=self.etag_func,
  116. last_modified_func=self.latest_entry,
  117. )
  118. async def async_view(request):
  119. return HttpResponse()
  120. request = HttpRequest()
  121. request.method = "GET"
  122. response = await async_view(request)
  123. self.assertEqual(response.status_code, 200)
  124. self.assertEqual(response.headers["ETag"], '"b4246ffc4f62314ca13147c9d4f76974"')
  125. self.assertEqual(
  126. response.headers["Last-Modified"],
  127. "Mon, 02 Jan 2023 23:21:47 GMT",
  128. )