From f028723e458d4f252a3439829e5bb9ea76bcc513 Mon Sep 17 00:00:00 2001 From: "Gavin M. Roy" Date: Fri, 20 Nov 2015 14:14:39 -0500 Subject: [PATCH] Use mediatype.ContentMixin if its also extended --- .gitignore | 1 + docs/api.rst | 9 ++++++--- docs/history.rst | 3 +++ requires/testing.txt | 1 + setup.py | 1 - sprockets/http/__init__.py | 2 +- sprockets/http/mixins.py | 19 ++++++++++++++----- tests.py | 13 +++++++++++++ 8 files changed, 39 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index dc310ff..d42f6b1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ build dist env *.egg-info +.coverage diff --git a/docs/api.rst b/docs/api.rst index 22e71d4..b350a06 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -79,9 +79,12 @@ exceptions will include the stack traces, etc. Standardized Error Response Documents ------------------------------------- Version 0.5.0 also introduced the :class:`~sprockets.http.mixins.ErrorWriter` -class which implements ``write_error`` to provide a standard JSON -document response instead of the default HTML response that Tornado -implements. +class which implements ``write_error`` to provide a standard machine-readable +document response instead of the default HTML response that Tornado implements. +If :class:`~sprockets.mixins.mediatype.ContentMixin` is being used as well, +``write_error`` will use +:meth:`~sprockets.mixins.mediatype.ContentMixin.send_response` to send the +document, otherwise it is sent as JSON. .. autoclass:: sprockets.http.mixins.ErrorWriter :members: diff --git a/docs/history.rst b/docs/history.rst index c702fbe..5d719fd 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -2,6 +2,9 @@ Release History =============== +`1.0.1`_ (20 Nov 2015) +---------------------- +- Add support for ``sprockets.mixins.mediatype`` in ``sprockets.http.mixins.ErrorWriter`` `1.0.0`_ (20 Nov 2015) ---------------------- diff --git a/requires/testing.txt b/requires/testing.txt index f51104e..946de5c 100644 --- a/requires/testing.txt +++ b/requires/testing.txt @@ -1 +1,2 @@ nose>=1.3.1,<2 +mock>=1.3,<2 diff --git a/setup.py b/setup.py index 0052003..75ba034 100755 --- a/setup.py +++ b/setup.py @@ -2,7 +2,6 @@ # import os.path -import sys import setuptools diff --git a/sprockets/http/__init__.py b/sprockets/http/__init__.py index 13627eb..290be4f 100644 --- a/sprockets/http/__init__.py +++ b/sprockets/http/__init__.py @@ -1,7 +1,7 @@ import os -version_info = (1, 0, 0) +version_info = (1, 0, 1) __version__ = '.'.join(str(v) for v in version_info) diff --git a/sprockets/http/mixins.py b/sprockets/http/mixins.py index bc39ed5..fc65654 100644 --- a/sprockets/http/mixins.py +++ b/sprockets/http/mixins.py @@ -78,9 +78,14 @@ class ErrorWriter(object): """ Write error bodies out consistently. - Mix this class in to your inheritance chain to include error - bodies as a standard JSON document. The error document has - three simple properties: + Mix this class in to your inheritance chain to include error bodies in a + machine-readable document format. + + If :class:`~sprockets.mixins.mediatype.ContentMixin` is also in use, it + will send the error response with it, otherwise the response is sent as + a JSON document. + + The error document has three simple properties: **type** This is the type of exception that occurred or ``null``. @@ -121,5 +126,9 @@ class ErrorWriter(object): reason = kwargs.get('reason', _get_http_reason(status_code)) error_body.setdefault('message', reason) - self.set_header('Content-Type', 'application/json') - self.write(json.dumps(error_body).encode('utf-8')) + # If sprockets.mixins.media_type is being used, use it + if hasattr(self, 'send_response'): + self.send_response(error_body) + else: + self.set_header('Content-Type', 'application/json; charset=utf-8') + self.write(json.dumps(error_body).encode('utf-8')) diff --git a/tests.py b/tests.py index 33736d4..121056d 100644 --- a/tests.py +++ b/tests.py @@ -1,5 +1,6 @@ import logging import json +import mock from tornado import httputil, testing, web @@ -161,3 +162,15 @@ class ErrorWriterTests(testing.AsyncHTTPTestCase): body = self._decode_response(response) self.assertGreater(len(body['traceback']), 0) + + def test_that_mediatype_mixin_is_honored(self): + send_response = mock.Mock() + setattr(examples.StatusHandler, 'send_response', send_response) + response = self.fetch('/status/500') + self.assertEqual(response.code, 500) + send_response.assert_called_once_with({ + 'type': None, + 'message': 'Internal Server Error', + 'traceback': None + }) + delattr(examples.StatusHandler, 'send_response')