Fix support of get_full_details() for Throttled exceptions (#4627)

Since `str` objects are immutable, appending to existing `str` creates
in fact a new `str` instance.

Thus `ErrorDetail.detail.code` attribute is lost after `str` concatenation operation.
This commit is contained in:
Nicolas Delaby 2016-11-01 11:38:56 +01:00 committed by Tom Christie
parent 98df932194
commit 97d848413e
2 changed files with 29 additions and 11 deletions

View File

@ -210,14 +210,14 @@ class Throttled(APIException):
default_code = 'throttled'
def __init__(self, wait=None, detail=None, code=None):
if detail is None:
detail = force_text(self.default_detail)
if wait is not None:
wait = math.ceil(wait)
detail = ' '.join((
detail,
force_text(ungettext(self.extra_detail_singular.format(wait=wait),
self.extra_detail_plural.format(wait=wait),
wait))))
self.wait = wait
super(Throttled, self).__init__(detail, code)
if wait is None:
self.wait = None
else:
self.wait = math.ceil(wait)
self.detail += ' ' + force_text(ungettext(
self.extra_detail_singular.format(wait=self.wait),
self.extra_detail_plural.format(wait=self.wait),
self.wait
))

View File

@ -1,9 +1,12 @@
from __future__ import unicode_literals
from django.test import TestCase
from django.utils import six
from django.utils.translation import ugettext_lazy as _
from rest_framework.exceptions import ErrorDetail, _get_error_details
from rest_framework.exceptions import (
ErrorDetail, Throttled, _get_error_details
)
class ExceptionTestCase(TestCase):
@ -39,3 +42,18 @@ class ExceptionTestCase(TestCase):
_get_error_details([[lazy_example]])[0][0],
ErrorDetail
)
def test_get_full_details_with_throttling(self):
exception = Throttled()
assert exception.get_full_details() == {
'message': 'Request was throttled.', 'code': 'throttled'}
exception = Throttled(wait=2)
assert exception.get_full_details() == {
'message': 'Request was throttled. Expected available in {} seconds.'.format(2 if six.PY3 else 2.),
'code': 'throttled'}
exception = Throttled(wait=2, detail='Slow down!')
assert exception.get_full_details() == {
'message': 'Slow down! Expected available in {} seconds.'.format(2 if six.PY3 else 2.),
'code': 'throttled'}