tests.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. # -*- coding:utf-8 -*-
  2. from __future__ import unicode_literals
  3. from datetime import datetime
  4. from django.test import TestCase, override_settings
  5. FULL_RESPONSE = 'Test conditional get response'
  6. LAST_MODIFIED = datetime(2007, 10, 21, 23, 21, 47)
  7. LAST_MODIFIED_STR = 'Sun, 21 Oct 2007 23:21:47 GMT'
  8. LAST_MODIFIED_NEWER_STR = 'Mon, 18 Oct 2010 16:56:23 GMT'
  9. LAST_MODIFIED_INVALID_STR = 'Mon, 32 Oct 2010 16:56:23 GMT'
  10. EXPIRED_LAST_MODIFIED_STR = 'Sat, 20 Oct 2007 23:21:47 GMT'
  11. ETAG = 'b4246ffc4f62314ca13147c9d4f76974'
  12. EXPIRED_ETAG = '7fae4cd4b0f81e7d2914700043aa8ed6'
  13. @override_settings(ROOT_URLCONF='conditional_processing.urls')
  14. class ConditionalGet(TestCase):
  15. def assertFullResponse(self, response, check_last_modified=True, check_etag=True):
  16. self.assertEqual(response.status_code, 200)
  17. self.assertEqual(response.content, FULL_RESPONSE.encode())
  18. if check_last_modified:
  19. self.assertEqual(response['Last-Modified'], LAST_MODIFIED_STR)
  20. if check_etag:
  21. self.assertEqual(response['ETag'], '"%s"' % ETAG)
  22. def assertNotModified(self, response):
  23. self.assertEqual(response.status_code, 304)
  24. self.assertEqual(response.content, b'')
  25. def test_without_conditions(self):
  26. response = self.client.get('/condition/')
  27. self.assertFullResponse(response)
  28. def test_if_modified_since(self):
  29. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
  30. response = self.client.get('/condition/')
  31. self.assertNotModified(response)
  32. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_NEWER_STR
  33. response = self.client.get('/condition/')
  34. self.assertNotModified(response)
  35. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_INVALID_STR
  36. response = self.client.get('/condition/')
  37. self.assertFullResponse(response)
  38. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
  39. response = self.client.get('/condition/')
  40. self.assertFullResponse(response)
  41. def test_if_unmodified_since(self):
  42. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = LAST_MODIFIED_STR
  43. response = self.client.get('/condition/')
  44. self.assertFullResponse(response)
  45. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = LAST_MODIFIED_NEWER_STR
  46. response = self.client.get('/condition/')
  47. self.assertFullResponse(response)
  48. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = LAST_MODIFIED_INVALID_STR
  49. response = self.client.get('/condition/')
  50. self.assertFullResponse(response)
  51. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
  52. response = self.client.get('/condition/')
  53. self.assertEqual(response.status_code, 412)
  54. def test_if_none_match(self):
  55. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
  56. response = self.client.get('/condition/')
  57. self.assertNotModified(response)
  58. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG
  59. response = self.client.get('/condition/')
  60. self.assertFullResponse(response)
  61. # Several etags in If-None-Match is a bit exotic but why not?
  62. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s", "%s"' % (ETAG, EXPIRED_ETAG)
  63. response = self.client.get('/condition/')
  64. self.assertNotModified(response)
  65. def test_if_match(self):
  66. self.client.defaults['HTTP_IF_MATCH'] = '"%s"' % ETAG
  67. response = self.client.put('/condition/etag/')
  68. self.assertEqual(response.status_code, 200)
  69. self.client.defaults['HTTP_IF_MATCH'] = '"%s"' % EXPIRED_ETAG
  70. response = self.client.put('/condition/etag/')
  71. self.assertEqual(response.status_code, 412)
  72. def test_both_headers(self):
  73. # see http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4
  74. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
  75. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
  76. response = self.client.get('/condition/')
  77. self.assertNotModified(response)
  78. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
  79. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
  80. response = self.client.get('/condition/')
  81. self.assertFullResponse(response)
  82. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
  83. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG
  84. response = self.client.get('/condition/')
  85. self.assertFullResponse(response)
  86. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
  87. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG
  88. response = self.client.get('/condition/')
  89. self.assertFullResponse(response)
  90. def test_both_headers_2(self):
  91. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = LAST_MODIFIED_STR
  92. self.client.defaults['HTTP_IF_MATCH'] = '"%s"' % ETAG
  93. response = self.client.get('/condition/')
  94. self.assertFullResponse(response)
  95. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
  96. self.client.defaults['HTTP_IF_MATCH'] = '"%s"' % EXPIRED_ETAG
  97. response = self.client.get('/condition/')
  98. self.assertEqual(response.status_code, 412)
  99. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = LAST_MODIFIED_STR
  100. self.client.defaults['HTTP_IF_MATCH'] = '"%s"' % EXPIRED_ETAG
  101. response = self.client.get('/condition/')
  102. self.assertEqual(response.status_code, 412)
  103. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
  104. self.client.defaults['HTTP_IF_MATCH'] = '"%s"' % ETAG
  105. response = self.client.get('/condition/')
  106. self.assertEqual(response.status_code, 412)
  107. def test_single_condition_1(self):
  108. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
  109. response = self.client.get('/condition/last_modified/')
  110. self.assertNotModified(response)
  111. response = self.client.get('/condition/etag/')
  112. self.assertFullResponse(response, check_last_modified=False)
  113. def test_single_condition_2(self):
  114. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
  115. response = self.client.get('/condition/etag/')
  116. self.assertNotModified(response)
  117. response = self.client.get('/condition/last_modified/')
  118. self.assertFullResponse(response, check_etag=False)
  119. def test_single_condition_3(self):
  120. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
  121. response = self.client.get('/condition/last_modified/')
  122. self.assertFullResponse(response, check_etag=False)
  123. def test_single_condition_4(self):
  124. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG
  125. response = self.client.get('/condition/etag/')
  126. self.assertFullResponse(response, check_last_modified=False)
  127. def test_single_condition_5(self):
  128. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
  129. response = self.client.get('/condition/last_modified2/')
  130. self.assertNotModified(response)
  131. response = self.client.get('/condition/etag2/')
  132. self.assertFullResponse(response, check_last_modified=False)
  133. def test_single_condition_6(self):
  134. self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG
  135. response = self.client.get('/condition/etag2/')
  136. self.assertNotModified(response)
  137. response = self.client.get('/condition/last_modified2/')
  138. self.assertFullResponse(response, check_etag=False)
  139. def test_single_condition_7(self):
  140. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
  141. response = self.client.get('/condition/last_modified/')
  142. self.assertEqual(response.status_code, 412)
  143. response = self.client.get('/condition/etag/')
  144. self.assertFullResponse(response, check_last_modified=False)
  145. def test_single_condition_8(self):
  146. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = LAST_MODIFIED_STR
  147. response = self.client.get('/condition/last_modified/')
  148. self.assertFullResponse(response, check_etag=False)
  149. def test_single_condition_9(self):
  150. self.client.defaults['HTTP_IF_UNMODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
  151. response = self.client.get('/condition/last_modified2/')
  152. self.assertEqual(response.status_code, 412)
  153. response = self.client.get('/condition/etag2/')
  154. self.assertFullResponse(response, check_last_modified=False)
  155. def test_single_condition_head(self):
  156. self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
  157. response = self.client.head('/condition/')
  158. self.assertNotModified(response)
  159. def test_invalid_etag(self):
  160. self.client.defaults['HTTP_IF_NONE_MATCH'] = r'"\"'
  161. response = self.client.get('/condition/etag/')
  162. self.assertFullResponse(response, check_last_modified=False)