From 995c7154056830d8b052b787de6519f9886a8c26 Mon Sep 17 00:00:00 2001 From: Dave Shawley Date: Sun, 31 Jan 2016 12:09:07 -0500 Subject: [PATCH] Normalize registered content types. MIME content type strings are normalized by lower-casing the content type parameters and then sorting them. Each parameter is preceded by a space. --- docs/history.rst | 1 + sprockets/mixins/mediatype/content.py | 7 +++++-- tests.py | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/history.rst b/docs/history.rst index 4df82b8..b310248 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -9,6 +9,7 @@ Version History - Add :class:`sprockets.mixins.mediatype.transcoders.JSONTranscoder` - Add :class:`sprockets.mixins.mediatype.transcoders.MsgPackTranscoder` - Add :class:`sprockets.mixins.mediatype.transcoders.BinaryWrapper` +- Normalize registered MIME types. `1.0.4`_ (14 Sep 2015) ---------------------- diff --git a/sprockets/mixins/mediatype/content.py b/sprockets/mixins/mediatype/content.py index df6fea6..bdc8bc6 100644 --- a/sprockets/mixins/mediatype/content.py +++ b/sprockets/mixins/mediatype/content.py @@ -83,15 +83,18 @@ class ContentSettings(object): self.default_encoding = None def __getitem__(self, content_type): - return self._handlers[content_type] + parsed = headers.parse_content_type(content_type) + return self._handlers[str(parsed)] def __setitem__(self, content_type, handler): + parsed = headers.parse_content_type(content_type) + content_type = str(parsed) if content_type in self._handlers: logger.warning('handler for %s already set to %r', content_type, self._handlers[content_type]) return - self._available_types.append(headers.parse_content_type(content_type)) + self._available_types.append(parsed) self._handlers[content_type] = handler def get(self, content_type, default=None): diff --git a/tests.py b/tests.py index fdbd605..ebd9546 100644 --- a/tests.py +++ b/tests.py @@ -194,6 +194,26 @@ class ContentSettingsTests(unittest.TestCase): settings['application/json'] = object() self.assertIs(settings.get('application/json'), handler) + def test_that_registered_content_types_are_normalized(self): + settings = content.ContentSettings() + handler = object() + settings['application/json; VerSion=foo; type=WhatEver'] = handler + self.assertIs(settings['application/json; type=whatever; version=foo'], + handler) + self.assertIn('application/json; type=whatever; version=foo', + (str(c) for c in settings.available_content_types)) + + def test_that_normalized_content_types_do_not_overwrite(self): + settings = content.ContentSettings() + settings['application/json; charset=UTF-8'] = handler = object() + settings['application/json; charset=utf-8'] = object() + self.assertEqual(len(settings.available_content_types), 1) + self.assertEqual(settings.available_content_types[0].content_type, + 'application') + self.assertEqual(settings.available_content_types[0].content_subtype, + 'json') + self.assertEqual(settings['application/json; charset=utf-8'], handler) + class ContentFunctionTests(unittest.TestCase):