From 4b691c402707775c3048a90531024f3bc5be6f91 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Sep 2012 13:06:27 +0100 Subject: Change package name: djangorestframework -> rest_framework --- rest_framework/tests/response.py | 177 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 rest_framework/tests/response.py (limited to 'rest_framework/tests/response.py') diff --git a/rest_framework/tests/response.py b/rest_framework/tests/response.py new file mode 100644 index 00000000..af70a387 --- /dev/null +++ b/rest_framework/tests/response.py @@ -0,0 +1,177 @@ +import unittest + +from django.conf.urls.defaults import patterns, url, include +from django.test import TestCase + +from rest_framework.response import Response +from rest_framework.views import APIView +from rest_framework import status +from rest_framework.renderers import ( + BaseRenderer, + JSONRenderer, + DocumentingHTMLRenderer +) + + +class MockPickleRenderer(BaseRenderer): + media_type = 'application/pickle' + + +class MockJsonRenderer(BaseRenderer): + media_type = 'application/json' + + +DUMMYSTATUS = status.HTTP_200_OK +DUMMYCONTENT = 'dummycontent' + +RENDERER_A_SERIALIZER = lambda x: 'Renderer A: %s' % x +RENDERER_B_SERIALIZER = lambda x: 'Renderer B: %s' % x + + +class RendererA(BaseRenderer): + media_type = 'mock/renderera' + format = "formata" + + def render(self, obj=None, media_type=None): + return RENDERER_A_SERIALIZER(obj) + + +class RendererB(BaseRenderer): + media_type = 'mock/rendererb' + format = "formatb" + + def render(self, obj=None, media_type=None): + return RENDERER_B_SERIALIZER(obj) + + +class MockView(APIView): + renderer_classes = (RendererA, RendererB) + + def get(self, request, **kwargs): + return Response(DUMMYCONTENT, status=DUMMYSTATUS) + + +class HTMLView(APIView): + renderer_classes = (DocumentingHTMLRenderer, ) + + def get(self, request, **kwargs): + return Response('text') + + +class HTMLView1(APIView): + renderer_classes = (DocumentingHTMLRenderer, JSONRenderer) + + def get(self, request, **kwargs): + return Response('text') + + +urlpatterns = patterns('', + url(r'^.*\.(?P.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB])), + url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB])), + url(r'^html$', HTMLView.as_view()), + url(r'^html1$', HTMLView1.as_view()), + url(r'^restframework', include('rest_framework.urls', namespace='rest_framework')) +) + + +# TODO: Clean tests bellow - remove duplicates with above, better unit testing, ... +class RendererIntegrationTests(TestCase): + """ + End-to-end testing of renderers using an ResponseMixin on a generic view. + """ + + urls = 'rest_framework.tests.response' + + def test_default_renderer_serializes_content(self): + """If the Accept header is not set the default renderer should serialize the response.""" + resp = self.client.get('/') + self.assertEquals(resp['Content-Type'], RendererA.media_type) + self.assertEquals(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT)) + self.assertEquals(resp.status_code, DUMMYSTATUS) + + def test_head_method_serializes_no_content(self): + """No response must be included in HEAD requests.""" + resp = self.client.head('/') + self.assertEquals(resp.status_code, DUMMYSTATUS) + self.assertEquals(resp['Content-Type'], RendererA.media_type) + self.assertEquals(resp.content, '') + + def test_default_renderer_serializes_content_on_accept_any(self): + """If the Accept header is set to */* the default renderer should serialize the response.""" + resp = self.client.get('/', HTTP_ACCEPT='*/*') + self.assertEquals(resp['Content-Type'], RendererA.media_type) + self.assertEquals(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT)) + self.assertEquals(resp.status_code, DUMMYSTATUS) + + def test_specified_renderer_serializes_content_default_case(self): + """If the Accept header is set the specified renderer should serialize the response. + (In this case we check that works for the default renderer)""" + resp = self.client.get('/', HTTP_ACCEPT=RendererA.media_type) + self.assertEquals(resp['Content-Type'], RendererA.media_type) + self.assertEquals(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT)) + self.assertEquals(resp.status_code, DUMMYSTATUS) + + def test_specified_renderer_serializes_content_non_default_case(self): + """If the Accept header is set the specified renderer should serialize the response. + (In this case we check that works for a non-default renderer)""" + resp = self.client.get('/', HTTP_ACCEPT=RendererB.media_type) + self.assertEquals(resp['Content-Type'], RendererB.media_type) + self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) + self.assertEquals(resp.status_code, DUMMYSTATUS) + + def test_specified_renderer_serializes_content_on_accept_query(self): + """The '_accept' query string should behave in the same way as the Accept header.""" + resp = self.client.get('/?_accept=%s' % RendererB.media_type) + self.assertEquals(resp['Content-Type'], RendererB.media_type) + self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) + self.assertEquals(resp.status_code, DUMMYSTATUS) + + @unittest.skip('can\'t pass because view is a simple Django view and response is an ImmediateResponse') + def test_unsatisfiable_accept_header_on_request_returns_406_status(self): + """If the Accept header is unsatisfiable we should return a 406 Not Acceptable response.""" + resp = self.client.get('/', HTTP_ACCEPT='foo/bar') + self.assertEquals(resp.status_code, status.HTTP_406_NOT_ACCEPTABLE) + + def test_specified_renderer_serializes_content_on_format_query(self): + """If a 'format' query is specified, the renderer with the matching + format attribute should serialize the response.""" + resp = self.client.get('/?format=%s' % RendererB.format) + self.assertEquals(resp['Content-Type'], RendererB.media_type) + self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) + self.assertEquals(resp.status_code, DUMMYSTATUS) + + def test_specified_renderer_serializes_content_on_format_kwargs(self): + """If a 'format' keyword arg is specified, the renderer with the matching + format attribute should serialize the response.""" + resp = self.client.get('/something.formatb') + self.assertEquals(resp['Content-Type'], RendererB.media_type) + self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) + self.assertEquals(resp.status_code, DUMMYSTATUS) + + def test_specified_renderer_is_used_on_format_query_with_matching_accept(self): + """If both a 'format' query and a matching Accept header specified, + the renderer with the matching format attribute should serialize the response.""" + resp = self.client.get('/?format=%s' % RendererB.format, + HTTP_ACCEPT=RendererB.media_type) + self.assertEquals(resp['Content-Type'], RendererB.media_type) + self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) + self.assertEquals(resp.status_code, DUMMYSTATUS) + + +class Issue122Tests(TestCase): + """ + Tests that covers #122. + """ + urls = 'rest_framework.tests.response' + + def test_only_html_renderer(self): + """ + Test if no infinite recursion occurs. + """ + self.client.get('/html') + + def test_html_renderer_is_first(self): + """ + Test if no infinite recursion occurs. + """ + self.client.get('/html1') -- cgit v1.2.3 From e7685f3eb5c7d7e8fb1678d673f03688012b00cb Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 2 Oct 2012 15:24:42 +0100 Subject: URL overrides in settings fixed up slightly --- rest_framework/tests/response.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'rest_framework/tests/response.py') diff --git a/rest_framework/tests/response.py b/rest_framework/tests/response.py index af70a387..f74e54fc 100644 --- a/rest_framework/tests/response.py +++ b/rest_framework/tests/response.py @@ -11,6 +11,7 @@ from rest_framework.renderers import ( JSONRenderer, DocumentingHTMLRenderer ) +from rest_framework.settings import api_settings class MockPickleRenderer(BaseRenderer): @@ -121,7 +122,11 @@ class RendererIntegrationTests(TestCase): def test_specified_renderer_serializes_content_on_accept_query(self): """The '_accept' query string should behave in the same way as the Accept header.""" - resp = self.client.get('/?_accept=%s' % RendererB.media_type) + param = '?%s=%s' % ( + api_settings.URL_ACCEPT_OVERRIDE, + RendererB.media_type + ) + resp = self.client.get('/' + param) self.assertEquals(resp['Content-Type'], RendererB.media_type) self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) self.assertEquals(resp.status_code, DUMMYSTATUS) -- cgit v1.2.3 From 97a7f27c8219181e40dddcaf820545e08283de93 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 9 Oct 2012 15:58:48 +0100 Subject: Rename HTMLTemplateRenderer -> HTMLRenderer, DocuemntingHTMLRenderer -> BrowseableAPIRenderer --- rest_framework/tests/response.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'rest_framework/tests/response.py') diff --git a/rest_framework/tests/response.py b/rest_framework/tests/response.py index f74e54fc..d1625b67 100644 --- a/rest_framework/tests/response.py +++ b/rest_framework/tests/response.py @@ -9,7 +9,7 @@ from rest_framework import status from rest_framework.renderers import ( BaseRenderer, JSONRenderer, - DocumentingHTMLRenderer + BrowsableAPIRenderer ) from rest_framework.settings import api_settings @@ -53,14 +53,14 @@ class MockView(APIView): class HTMLView(APIView): - renderer_classes = (DocumentingHTMLRenderer, ) + renderer_classes = (BrowsableAPIRenderer, ) def get(self, request, **kwargs): return Response('text') class HTMLView1(APIView): - renderer_classes = (DocumentingHTMLRenderer, JSONRenderer) + renderer_classes = (BrowsableAPIRenderer, JSONRenderer) def get(self, request, **kwargs): return Response('text') -- cgit v1.2.3 From 648d2be29b0738999742f4d844caab7b7652d1ad Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 10 Oct 2012 12:15:18 +0100 Subject: Make sure JSON output in Browseable API is nicely indented --- rest_framework/tests/response.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'rest_framework/tests/response.py') diff --git a/rest_framework/tests/response.py b/rest_framework/tests/response.py index d1625b67..18b6af39 100644 --- a/rest_framework/tests/response.py +++ b/rest_framework/tests/response.py @@ -33,16 +33,16 @@ class RendererA(BaseRenderer): media_type = 'mock/renderera' format = "formata" - def render(self, obj=None, media_type=None): - return RENDERER_A_SERIALIZER(obj) + def render(self, data, media_type=None, renderer_context=None): + return RENDERER_A_SERIALIZER(data) class RendererB(BaseRenderer): media_type = 'mock/rendererb' format = "formatb" - def render(self, obj=None, media_type=None): - return RENDERER_B_SERIALIZER(obj) + def render(self, data, media_type=None, renderer_context=None): + return RENDERER_B_SERIALIZER(data) class MockView(APIView): -- cgit v1.2.3