def _get(self, *args, **kwargs): # The database backend for persistent messages doesn't support setting # messages with ``mark_safe``, therefore, we need to do it broadly here. messages, all_ret = (super(FallbackUniqueStorage, self) ._get(self, *args, **kwargs)) safe_messages = [] for message in messages: # Handle all message types, if the message is persistent, take # special action. As the default message handler, this will also # process ephemeral messages if message.level in PERSISTENT_MESSAGE_LEVELS: message_pk = message.pk message = Message(message.level, mark_safe(message.message), message.extra_tags) message.pk = message_pk safe_messages.append(message) return safe_messages, all_ret
def process_messages(self, obj): if isinstance(obj, list) and obj: if obj[0] == MessageEncoder.message_key: if obj[1]: obj[3] = mark_safe(obj[3]) return Message(*obj[2:]) return [self.process_messages(item) for item in obj] if isinstance(obj, dict): return { key: self.process_messages(value) for key, value in obj.items() } return obj
def test_json_encoder_decoder(self): """ A complex nested data structure containing Message instances is properly encoded/decoded by the custom JSON encoder/decoder classes. """ messages = [ { 'message': Message(constants.INFO, 'Test message'), 'message_list': [Message(constants.INFO, 'message %s') for x in range(5)] + [{ 'another-message': Message(constants.ERROR, 'error') }], }, Message(constants.INFO, 'message %s'), ] encoder = MessageEncoder(separators=(',', ':')) value = encoder.encode(messages) decoded_messages = json.loads(value, cls=MessageDecoder) self.assertEqual(messages, decoded_messages)
def test_messages(self): for tag in self.tags: txt = 'some message with {}'.format(repr(tag)) test_messages = [Message(tag, txt)] self.assertEqual( messages(test_messages), {'messages': [{ 'text': txt, 'tags': LEVEL_TAGS[tag] }]}) # clean one txt = '[\'some dirty message with {}\']'.format(repr(tag)) txt_altered = txt.replace('[\'', '').replace('\']', '') test_messages = [Message(tag, txt)] self.assertEqual( messages(test_messages), {'messages': [{ 'text': txt_altered, 'tags': LEVEL_TAGS[tag] }]}) # dirty one
def _get(self, *args, **kwargs): """ Retrieves a list of messages assigned to the User. This backend never stores anything, so all_retrieved is assumed to be False. """ queryset = self._get_messages_queryset() if queryset is None: # This is a read-only and optional storage, so to ensure other # storages will also be read if used with FallbackStorage an empty # list is returned rather than None. return [], False messages = [] for user_message in queryset: messages.append(Message(constants.INFO, user_message.message)) return messages, False
def add_unique_message(self, level, message, **kwargs): """ Add a message, but only after first making sure it's not already been emitted. This helps guard against any message generator adding the same message multiple times before the next time the messages are displayed. Once messages are displayed, `used` is set on the storage object returned by `get_messages()` and the queue is cleared. Returns True if message was sent for the first time. """ expected = Message(message=message, level=level, **kwargs) if any(msg == expected for msg in messages.get_messages(self.request)): return False messages.add_message(self.request, level, message, **kwargs) return True
def test_legacy_encode_decode(self): # RemovedInDjango41Warning: pre-Django 3.2 encoded messages will be # invalid. storage = self.storage_class(self.get_request()) messages = [ 'this', Message(0, 'Successfully signed in as [email protected]') ] # Encode/decode a message using the pre-Django 3.2 format. encoder = MessageEncoder() value = encoder.encode(messages) with self.assertRaises(binascii.Error): b64_decode(value.encode()) signer = get_cookie_signer(salt=storage.key_salt) encoded_messages = signer.sign(value) decoded_messages = storage._decode(encoded_messages) self.assertEqual(messages, decoded_messages)
def test_full_request_response_cycle(self): """ With the message middleware enabled, messages are properly stored and retrieved across the full request/redirect/response cycle. """ data = { 'messages': ['Test message %d' % x for x in range(5)], } show_url = reverse('show_message') for level in ('debug', 'info', 'success', 'warning', 'error'): add_url = reverse('add_message', args=(level,)) response = self.client.post(add_url, data, follow=True) self.assertRedirects(response, show_url) self.assertIn('messages', response.context) messages = [Message(self.levels[level], msg) for msg in data['messages']] self.assertEqual(list(response.context['messages']), messages) for msg in data['messages']: self.assertContains(response, msg)
def test_multiple_posts(self): """ Messages persist properly when multiple POSTs are made before a GET. """ data = { 'messages': ['Test message %d' % x for x in range(5)], } show_url = reverse('show_message') messages = [] for level in ('debug', 'info', 'success', 'warning', 'error'): messages.extend(Message(self.levels[level], msg) for msg in data['messages']) add_url = reverse('add_message', args=(level,)) self.client.post(add_url, data) response = self.client.get(show_url) self.assertIn('messages', response.context) self.assertEqual(list(response.context['messages']), messages) for msg in data['messages']: self.assertContains(response, msg)
def test_multiple_posts(self): """ Messages persist properly when multiple POSTs are made before a GET. """ data = { "messages": ["Test message %d" % x for x in range(5)], } show_url = reverse("show_message") messages = [] for level in ("debug", "info", "success", "warning", "error"): messages.extend( Message(self.levels[level], msg) for msg in data["messages"]) add_url = reverse("add_message", args=(level, )) self.client.post(add_url, data) response = self.client.get(show_url) self.assertIn("messages", response.context) self.assertEqual(list(response.context["messages"]), messages) for msg in data["messages"]: self.assertContains(response, msg)
def add(self, level, message, extra_tags='', *args, **kwargs): """ Queues a message to be stored. The message is only queued if it contained something and its level is not less than the recording level (``self.level``). """ if not message: return # Check that the message level is not less than the recording level. level = int(level) if level < self.level: return # Add the message. self.added_new = True message = Message(level, message, extra_tags=extra_tags) message = self.process_message(message, *args, **kwargs) if message: self._queued_messages.append(message)
def save_form(request): """Save the current form in data base. Converts it to XML format first. Args: request: Returns: """ try: # get curate data structure curate_data_structure_id = request.POST['id'] curate_data_structure = curate_data_structure_api.get_by_id( curate_data_structure_id) # unlock from database if curate_data_structure.data is not None: lock_api.remove_lock_on_object(curate_data_structure.data, request.user) # generate xml data xml_data = render_xml( curate_data_structure.data_structure_element_root) # update curate data structure data curate_data_structure.form_string = xml_data # save data structure curate_data_structure_api.upsert(curate_data_structure) # add success message message = Message( messages.SUCCESS, get_form_label().capitalize() + ' saved with success.') return HttpResponse(json.dumps({ 'message': message.message, 'tags': message.tags }), content_type='application/json') except: return HttpResponseBadRequest()
def test_pre_1_5_message_format(self): """ Messages that were set in the cookie before the addition of is_safedata are decoded correctly (#22426). """ # Encode the messages using the current encoder. messages = [Message(constants.INFO, 'message %s') for x in range(5)] encoder = MessageEncoder(separators=(',', ':')) encoded_messages = encoder.encode(messages) # Remove the is_safedata flag from the messages in order to imitate # the behavior of before 1.5 (monkey patching). encoded_messages = json.loads(encoded_messages) for obj in encoded_messages: obj.pop(1) encoded_messages = json.dumps(encoded_messages, separators=(',', ':')) # Decode the messages in the old format (without is_safedata) decoded_messages = json.loads(encoded_messages, cls=MessageDecoder) self.assertEqual(messages, decoded_messages)
def test_full_request_response_cycle(self): """ With the message middleware enabled, messages are properly stored and retrieved across the full request/redirect/response cycle. """ data = { "messages": ["Test message %d" % x for x in range(5)], } show_url = reverse("show_message") for level in ("debug", "info", "success", "warning", "error"): add_url = reverse("add_message", args=(level, )) response = self.client.post(add_url, data, follow=True) self.assertRedirects(response, show_url) self.assertIn("messages", response.context) messages = [ Message(self.levels[level], msg) for msg in data["messages"] ] self.assertEqual(list(response.context["messages"]), messages) for msg in data["messages"]: self.assertContains(response, msg)
def core_clear_cache(request): # Delete caches objects from the database data_cached_api.clean_datacached_objects() leaf_api.clean_leaves_objects() navigation_api.clean_navigation_objects() # Clear real caches leaf_cache.clear() html_tree_cache.clear() navigation_cache.clear() branch_cache.clear() link_cache.clear() message = Message(messages.SUCCESS, "Cached objects deleted with success.") return HttpResponse( json.dumps({ "message": message.message, "tags": message.tags }), content_type="application/json", )
def test_multiple_posts(self): """ Tests that messages persist properly when multiple POSTs are made before a GET. """ settings.MESSAGE_LEVEL = constants.DEBUG data = { 'messages': ['Test message %d' % x for x in xrange(10)], } show_url = reverse('django.contrib.messages.tests.urls.show') messages = [] for level in ('debug', 'info', 'success', 'warning', 'error'): messages.extend( [Message(self.levels[level], msg) for msg in data['messages']]) add_url = reverse('django.contrib.messages.tests.urls.add', args=(level, )) self.client.post(add_url, data) response = self.client.get(show_url) self.assertTrue('messages' in response.context) self.assertEqual(list(response.context['messages']), messages) for msg in data['messages']: self.assertContains(response, msg)
def save_form(request): """Save the current form in data base. Converts it to XML format first. Args: request: Returns: """ try: # get curate data structure curate_data_structure_id = request.POST["id"] curate_data_structure = curate_data_structure_api.get_by_id( curate_data_structure_id, request.user) # generate xml data xml_data = render_xml( request, curate_data_structure.data_structure_element_root) # update curate data structure data curate_data_structure.form_string = xml_data # save data structure curate_data_structure_api.upsert(curate_data_structure, request.user) # add success message message = Message( messages.SUCCESS, get_form_label().capitalize() + " saved with success.") return HttpResponse( json.dumps({ "message": message.message, "tags": message.tags }), content_type="application/json", ) except Exception as e: return HttpResponseBadRequest(escape(str(e)))
def test_full_request_response_cycle(self): """ With the message middleware enabled, tests that messages are properly stored and then retrieved across the full request/redirect/response cycle. """ settings.MESSAGE_LEVEL = constants.DEBUG data = { 'messages': ['Test message %d' % x for x in xrange(10)], } show_url = reverse('django.contrib.messages.tests.urls.show') for level in ('debug', 'info', 'success', 'warning', 'error'): add_url = reverse('django.contrib.messages.tests.urls.add', args=(level,)) response = self.client.post(add_url, data, follow=True) self.assertRedirects(response, show_url) self.assertTrue('messages' in response.context) messages = [Message(self.levels[level], msg) for msg in data['messages']] self.assertEqual(list(response.context['messages']), messages) for msg in data['messages']: self.assertContains(response, msg)
def encode_decode(self, *args, **kwargs): storage = self.get_storage() message = Message(constants.DEBUG, *args, **kwargs) encoded = storage._encode(message) return storage._decode(encoded)
def encode_decode(data): message = Message(constants.DEBUG, data) encoded = storage._encode(message) decoded = storage._decode(encoded) return decoded.message
def get_existing_storage(self): return self.get_storage([ Message(constants.INFO, 'Test message 1'), Message(constants.INFO, 'Test message 2', extra_tags='tag') ])
def test_bootstrap_messages_with_safe_message(self): messages = [Message(DEFAULT_MESSAGE_LEVELS.INFO, mark_safe("Click <a href='https://www.github.com/'>here</a>"))] self.assertHTMLEqual( self.render("{% bootstrap_messages messages %}", {"messages": messages}), self._html(content="Click <a href='https://www.github.com/'>here</a>", css_class="alert-info"), )
def get_existing_storage(self): return self.get_storage([ Message(constants.INFO, "Test message 1"), Message(constants.INFO, "Test message 2", extra_tags="tag"), ])
def add(self, level, message, extra_tags=''): self._loaded_data.append(Message(level, message, extra_tags=extra_tags))
def add(self, level, message, extra_tags=''): obj_message = Message(level, message, extra_tags) if obj_message in self._loaded_messages: self._loaded_messages.remove(obj_message) super(MessageStorage, self).add(level, message, extra_tags='')
def add_message(self, lvl, msg): self.append(Message(lvl, msg))
def test_error_message_icon(self): self.assertEqual(message_icon(Message(messages.ERROR, "error")), "pficon-error-circle-o")
def test_warning_message_icon(self): self.assertEqual( message_icon(Message(messages.WARNING, "warning")), "pficon-warning-triangle-o", )
def test_success_message_icon(self): self.assertEqual(message_icon(Message(messages.SUCCESS, "ok")), "pficon-ok")
def assert_message_exists(self, request, level, message): self.assertIn(Message(level=level, message=message), messages.get_messages(request), 'Message matching criteria does not exist')
def test_info_message_icon(self): self.assertEqual(message_icon(Message(messages.INFO, "info")), "pficon-info")