Daniel Naab 2014-08-19 18:33:39 -05:00
parent 48b66ec2a2
commit c40d8caa49

View File

@ -101,6 +101,14 @@ class HTMLView1(APIView):
def get(self, request, **kwargs): def get(self, request, **kwargs):
return Response('text') return Response('text')
class HTMLView2(APIView):
renderer_classes = (BrowsableAPIRenderer, JSONRenderer)
def get(self, request, **kwargs):
return Response({'url': 'http://domain.com/?param=Yes+%26+No'})
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^.*\.(?P<format>.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB])), url(r'^.*\.(?P<format>.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB])),
url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB])), url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB])),
@ -110,6 +118,7 @@ urlpatterns = patterns('',
url(r'^parseerror$', MockPOSTView.as_view(renderer_classes=[JSONRenderer, BrowsableAPIRenderer])), url(r'^parseerror$', MockPOSTView.as_view(renderer_classes=[JSONRenderer, BrowsableAPIRenderer])),
url(r'^html$', HTMLView.as_view()), url(r'^html$', HTMLView.as_view()),
url(r'^html1$', HTMLView1.as_view()), url(r'^html1$', HTMLView1.as_view()),
url(r'^html2$', HTMLView2.as_view()),
url(r'^empty$', EmptyGETView.as_view()), url(r'^empty$', EmptyGETView.as_view()),
url(r'^api', include('rest_framework.urls', namespace='rest_framework')) url(r'^api', include('rest_framework.urls', namespace='rest_framework'))
) )
@ -268,6 +277,16 @@ class RendererEndToEndTests(TestCase):
self.assertContains(resp, '>application/json<') self.assertContains(resp, '>application/json<')
self.assertNotContains(resp, '>text/html; charset=utf-8<') self.assertNotContains(resp, '>text/html; charset=utf-8<')
def test_browsable_api_urls(self):
"""
Issue #1649
Test that URLs have properly escaped GET parameters.
"""
resp = self.client.get('/html2')
# GET parameter should be escaped as Yes+%26+No, not Yes+&amp;+No
self.assertEqual(resp.rendered_content.find('Yes+&amp;+No'), -1)
_flat_repr = '{"foo": ["bar", "baz"]}' _flat_repr = '{"foo": ["bar", "baz"]}'
_indented_repr = '{\n "foo": [\n "bar",\n "baz"\n ]\n}' _indented_repr = '{\n "foo": [\n "bar",\n "baz"\n ]\n}'
@ -329,7 +348,7 @@ class JSONRendererTests(TestCase):
x[2] = 3 x[2] = 3
ret = JSONRenderer().render(x) ret = JSONRenderer().render(x)
data = json.loads(ret.decode('utf-8')) data = json.loads(ret.decode('utf-8'))
self.assertEquals(data, {'key': 'string value', '2': 3}) self.assertEquals(data, {'key': 'string value', '2': 3})
def test_render_obj_with_getitem(self): def test_render_obj_with_getitem(self):
class DictLike(object): class DictLike(object):
@ -339,12 +358,12 @@ class JSONRendererTests(TestCase):
self._dict = dict(value) self._dict = dict(value)
def __getitem__(self, key): def __getitem__(self, key):
return self._dict[key] return self._dict[key]
x = DictLike() x = DictLike()
x.set({'a': 1, 'b': 'string'}) x.set({'a': 1, 'b': 'string'})
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
JSONRenderer().render(x) JSONRenderer().render(x)
def test_without_content_type_args(self): def test_without_content_type_args(self):
""" """
Test basic JSON rendering. Test basic JSON rendering.