test_fallback.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. from django.contrib.messages import constants
  2. from django.contrib.messages.storage.fallback import (FallbackStorage,
  3. CookieStorage)
  4. from django.contrib.messages.tests.base import BaseTests
  5. from django.contrib.messages.tests.test_cookie import (set_cookie_data,
  6. stored_cookie_messages_count)
  7. from django.contrib.messages.tests.test_session import (set_session_data,
  8. stored_session_messages_count)
  9. from django.test import TestCase
  10. class FallbackTest(BaseTests, TestCase):
  11. storage_class = FallbackStorage
  12. def get_request(self):
  13. self.session = {}
  14. request = super(FallbackTest, self).get_request()
  15. request.session = self.session
  16. return request
  17. def get_cookie_storage(self, storage):
  18. return storage.storages[-2]
  19. def get_session_storage(self, storage):
  20. return storage.storages[-1]
  21. def stored_cookie_messages_count(self, storage, response):
  22. return stored_cookie_messages_count(self.get_cookie_storage(storage),
  23. response)
  24. def stored_session_messages_count(self, storage, response):
  25. return stored_session_messages_count(self.get_session_storage(storage))
  26. def stored_messages_count(self, storage, response):
  27. """
  28. Return the storage totals from both cookie and session backends.
  29. """
  30. total = (self.stored_cookie_messages_count(storage, response) +
  31. self.stored_session_messages_count(storage, response))
  32. return total
  33. def test_get(self):
  34. request = self.get_request()
  35. storage = self.storage_class(request)
  36. cookie_storage = self.get_cookie_storage(storage)
  37. # Set initial cookie data.
  38. example_messages = [str(i) for i in range(5)]
  39. set_cookie_data(cookie_storage, example_messages)
  40. # Overwrite the _get method of the fallback storage to prove it is not
  41. # used (it would cause a TypeError: 'NoneType' object is not callable).
  42. self.get_session_storage(storage)._get = None
  43. # Test that the message actually contains what we expect.
  44. self.assertEqual(list(storage), example_messages)
  45. def test_get_empty(self):
  46. request = self.get_request()
  47. storage = self.storage_class(request)
  48. # Overwrite the _get method of the fallback storage to prove it is not
  49. # used (it would cause a TypeError: 'NoneType' object is not callable).
  50. self.get_session_storage(storage)._get = None
  51. # Test that the message actually contains what we expect.
  52. self.assertEqual(list(storage), [])
  53. def test_get_fallback(self):
  54. request = self.get_request()
  55. storage = self.storage_class(request)
  56. cookie_storage = self.get_cookie_storage(storage)
  57. session_storage = self.get_session_storage(storage)
  58. # Set initial cookie and session data.
  59. example_messages = [str(i) for i in range(5)]
  60. set_cookie_data(cookie_storage, example_messages[:4] +
  61. [CookieStorage.not_finished])
  62. set_session_data(session_storage, example_messages[4:])
  63. # Test that the message actually contains what we expect.
  64. self.assertEqual(list(storage), example_messages)
  65. def test_get_fallback_only(self):
  66. request = self.get_request()
  67. storage = self.storage_class(request)
  68. cookie_storage = self.get_cookie_storage(storage)
  69. session_storage = self.get_session_storage(storage)
  70. # Set initial cookie and session data.
  71. example_messages = [str(i) for i in range(5)]
  72. set_cookie_data(cookie_storage, [CookieStorage.not_finished],
  73. encode_empty=True)
  74. set_session_data(session_storage, example_messages)
  75. # Test that the message actually contains what we expect.
  76. self.assertEqual(list(storage), example_messages)
  77. def test_flush_used_backends(self):
  78. request = self.get_request()
  79. storage = self.storage_class(request)
  80. cookie_storage = self.get_cookie_storage(storage)
  81. session_storage = self.get_session_storage(storage)
  82. # Set initial cookie and session data.
  83. set_cookie_data(cookie_storage, ['cookie', CookieStorage.not_finished])
  84. set_session_data(session_storage, ['session'])
  85. # When updating, previously used but no longer needed backends are
  86. # flushed.
  87. response = self.get_response()
  88. list(storage)
  89. storage.update(response)
  90. session_storing = self.stored_session_messages_count(storage, response)
  91. self.assertEqual(session_storing, 0)
  92. def test_no_fallback(self):
  93. """
  94. Confirms that:
  95. (1) A short number of messages whose data size doesn't exceed what is
  96. allowed in a cookie will all be stored in the CookieBackend.
  97. (2) If the CookieBackend can store all messages, the SessionBackend
  98. won't be written to at all.
  99. """
  100. storage = self.get_storage()
  101. response = self.get_response()
  102. # Overwrite the _store method of the fallback storage to prove it isn't
  103. # used (it would cause a TypeError: 'NoneType' object is not callable).
  104. self.get_session_storage(storage)._store = None
  105. for i in range(5):
  106. storage.add(constants.INFO, str(i) * 100)
  107. storage.update(response)
  108. cookie_storing = self.stored_cookie_messages_count(storage, response)
  109. self.assertEqual(cookie_storing, 5)
  110. session_storing = self.stored_session_messages_count(storage, response)
  111. self.assertEqual(session_storing, 0)
  112. def test_session_fallback(self):
  113. """
  114. Confirms that, if the data exceeds what is allowed in a cookie,
  115. messages which did not fit are stored in the SessionBackend.
  116. """
  117. storage = self.get_storage()
  118. response = self.get_response()
  119. # see comment in CookieText.test_cookie_max_length
  120. msg_size = int((CookieStorage.max_cookie_size - 54) / 4.5 - 37)
  121. for i in range(5):
  122. storage.add(constants.INFO, str(i) * msg_size)
  123. storage.update(response)
  124. cookie_storing = self.stored_cookie_messages_count(storage, response)
  125. self.assertEqual(cookie_storing, 4)
  126. session_storing = self.stored_session_messages_count(storage, response)
  127. self.assertEqual(session_storing, 1)
  128. def test_session_fallback_only(self):
  129. """
  130. Confirms that large messages, none of which fit in a cookie, are stored
  131. in the SessionBackend (and nothing is stored in the CookieBackend).
  132. """
  133. storage = self.get_storage()
  134. response = self.get_response()
  135. storage.add(constants.INFO, 'x' * 5000)
  136. storage.update(response)
  137. cookie_storing = self.stored_cookie_messages_count(storage, response)
  138. self.assertEqual(cookie_storing, 0)
  139. session_storing = self.stored_session_messages_count(storage, response)
  140. self.assertEqual(session_storing, 1)