web/lib/django/contrib/messages/tests/cookie.py
changeset 29 cc9b7e14412b
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
       
     1 from django.contrib.messages import constants
       
     2 from django.contrib.messages.tests.base import BaseTest
       
     3 from django.contrib.messages.storage.cookie import CookieStorage, \
       
     4                                             MessageEncoder, MessageDecoder
       
     5 from django.contrib.messages.storage.base import Message
       
     6 from django.utils import simplejson as json
       
     7 
       
     8 
       
     9 def set_cookie_data(storage, messages, invalid=False, encode_empty=False):
       
    10     """
       
    11     Sets ``request.COOKIES`` with the encoded data and removes the storage
       
    12     backend's loaded data cache.
       
    13     """
       
    14     encoded_data = storage._encode(messages, encode_empty=encode_empty)
       
    15     if invalid:
       
    16         # Truncate the first character so that the hash is invalid.
       
    17         encoded_data = encoded_data[1:]
       
    18     storage.request.COOKIES = {CookieStorage.cookie_name: encoded_data}
       
    19     if hasattr(storage, '_loaded_data'):
       
    20         del storage._loaded_data
       
    21 
       
    22 
       
    23 def stored_cookie_messages_count(storage, response):
       
    24     """
       
    25     Returns an integer containing the number of messages stored.
       
    26     """
       
    27     # Get a list of cookies, excluding ones with a max-age of 0 (because
       
    28     # they have been marked for deletion).
       
    29     cookie = response.cookies.get(storage.cookie_name)
       
    30     if not cookie or cookie['max-age'] == 0:
       
    31         return 0
       
    32     data = storage._decode(cookie.value)
       
    33     if not data:
       
    34         return 0
       
    35     if data[-1] == CookieStorage.not_finished:
       
    36         data.pop()
       
    37     return len(data)
       
    38 
       
    39 
       
    40 class CookieTest(BaseTest):
       
    41     storage_class = CookieStorage
       
    42 
       
    43     def stored_messages_count(self, storage, response):
       
    44         return stored_cookie_messages_count(storage, response)
       
    45 
       
    46     def test_get(self):
       
    47         storage = self.storage_class(self.get_request())
       
    48         # Set initial data.
       
    49         example_messages = ['test', 'me']
       
    50         set_cookie_data(storage, example_messages)
       
    51         # Test that the message actually contains what we expect.
       
    52         self.assertEqual(list(storage), example_messages)
       
    53 
       
    54     def test_get_bad_cookie(self):
       
    55         request = self.get_request()
       
    56         storage = self.storage_class(request)
       
    57         # Set initial (invalid) data.
       
    58         example_messages = ['test', 'me']
       
    59         set_cookie_data(storage, example_messages, invalid=True)
       
    60         # Test that the message actually contains what we expect.
       
    61         self.assertEqual(list(storage), [])
       
    62 
       
    63     def test_max_cookie_length(self):
       
    64         """
       
    65         Tests that, if the data exceeds what is allowed in a cookie, older
       
    66         messages are removed before saving (and returned by the ``update``
       
    67         method).
       
    68         """
       
    69         storage = self.get_storage()
       
    70         response = self.get_response()
       
    71 
       
    72         # When storing as a cookie, the cookie has constant overhead of approx
       
    73         # 54 chars, and each message has a constant overhead of about 37 chars
       
    74         # and a variable overhead of zero in the best case. We aim for a message
       
    75         # size which will fit 4 messages into the cookie, but not 5.
       
    76         # See also FallbackTest.test_session_fallback
       
    77         msg_size = int((CookieStorage.max_cookie_size - 54) / 4.5 - 37)
       
    78         for i in range(5):
       
    79             storage.add(constants.INFO, str(i) * msg_size)
       
    80         unstored_messages = storage.update(response)
       
    81 
       
    82         cookie_storing = self.stored_messages_count(storage, response)
       
    83         self.assertEqual(cookie_storing, 4)
       
    84 
       
    85         self.assertEqual(len(unstored_messages), 1)
       
    86         self.assert_(unstored_messages[0].message == '0' * msg_size)
       
    87 
       
    88     def test_json_encoder_decoder(self):
       
    89         """
       
    90         Tests that a complex nested data structure containing Message
       
    91         instances is properly encoded/decoded by the custom JSON
       
    92         encoder/decoder classes.
       
    93         """
       
    94         messages = [
       
    95             {
       
    96                 'message': Message(constants.INFO, 'Test message'),
       
    97                 'message_list': [Message(constants.INFO, 'message %s') \
       
    98                                  for x in xrange(5)] + [{'another-message': \
       
    99                                  Message(constants.ERROR, 'error')}],
       
   100             },
       
   101             Message(constants.INFO, 'message %s'),
       
   102         ]
       
   103         encoder = MessageEncoder(separators=(',', ':'))
       
   104         value = encoder.encode(messages)
       
   105         decoded_messages = json.loads(value, cls=MessageDecoder)
       
   106         self.assertEqual(messages, decoded_messages)