diff options
Diffstat (limited to 'rest_framework/tests/request.py')
| -rw-r--r-- | rest_framework/tests/request.py | 252 | 
1 files changed, 252 insertions, 0 deletions
| diff --git a/rest_framework/tests/request.py b/rest_framework/tests/request.py new file mode 100644 index 00000000..805f6efc --- /dev/null +++ b/rest_framework/tests/request.py @@ -0,0 +1,252 @@ +""" +Tests for content parsing, and form-overloaded content parsing. +""" +from django.conf.urls.defaults import patterns +from django.contrib.auth.models import User +from django.test import TestCase, Client + +from rest_framework import status +from rest_framework.authentication import SessionAuthentication +from rest_framework.compat import RequestFactory +from rest_framework.parsers import ( +    FormParser, +    MultiPartParser, +    PlainTextParser, +) +from rest_framework.request import Request +from rest_framework.response import Response +from rest_framework.views import APIView + + +factory = RequestFactory() + + +class TestMethodOverloading(TestCase): +    def test_method(self): +        """ +        Request methods should be same as underlying request. +        """ +        request = Request(factory.get('/')) +        self.assertEqual(request.method, 'GET') +        request = Request(factory.post('/')) +        self.assertEqual(request.method, 'POST') + +    def test_overloaded_method(self): +        """ +        POST requests can be overloaded to another method by setting a +        reserved form field +        """ +        request = Request(factory.post('/', {Request._METHOD_PARAM: 'DELETE'})) +        self.assertEqual(request.method, 'DELETE') + + +class TestContentParsing(TestCase): +    def test_standard_behaviour_determines_no_content_GET(self): +        """ +        Ensure request.DATA returns None for GET request with no content. +        """ +        request = Request(factory.get('/')) +        self.assertEqual(request.DATA, None) + +    def test_standard_behaviour_determines_no_content_HEAD(self): +        """ +        Ensure request.DATA returns None for HEAD request. +        """ +        request = Request(factory.head('/')) +        self.assertEqual(request.DATA, None) + +    def test_standard_behaviour_determines_form_content_POST(self): +        """ +        Ensure request.DATA returns content for POST request with form content. +        """ +        data = {'qwerty': 'uiop'} +        request = Request(factory.post('/', data)) +        request.parser_classes = (FormParser, MultiPartParser) +        self.assertEqual(request.DATA.items(), data.items()) + +    def test_standard_behaviour_determines_non_form_content_POST(self): +        """ +        Ensure request.DATA returns content for POST request with +        non-form content. +        """ +        content = 'qwerty' +        content_type = 'text/plain' +        request = Request(factory.post('/', content, content_type=content_type)) +        request.parser_classes = (PlainTextParser,) +        self.assertEqual(request.DATA, content) + +    def test_standard_behaviour_determines_form_content_PUT(self): +        """ +        Ensure request.DATA returns content for PUT request with form content. +        """ +        data = {'qwerty': 'uiop'} + +        from django import VERSION + +        if VERSION >= (1, 5): +            from django.test.client import MULTIPART_CONTENT, BOUNDARY, encode_multipart +            request = Request(factory.put('/', encode_multipart(BOUNDARY, data), +                                  content_type=MULTIPART_CONTENT)) +        else: +            request = Request(factory.put('/', data)) + +        request.parser_classes = (FormParser, MultiPartParser) +        self.assertEqual(request.DATA.items(), data.items()) + +    def test_standard_behaviour_determines_non_form_content_PUT(self): +        """ +        Ensure request.DATA returns content for PUT request with +        non-form content. +        """ +        content = 'qwerty' +        content_type = 'text/plain' +        request = Request(factory.put('/', content, content_type=content_type)) +        request.parser_classes = (PlainTextParser, ) +        self.assertEqual(request.DATA, content) + +    def test_overloaded_behaviour_allows_content_tunnelling(self): +        """ +        Ensure request.DATA returns content for overloaded POST request. +        """ +        content = 'qwerty' +        content_type = 'text/plain' +        data = { +            Request._CONTENT_PARAM: content, +            Request._CONTENTTYPE_PARAM: content_type +        } +        request = Request(factory.post('/', data)) +        request.parser_classes = (PlainTextParser, ) +        self.assertEqual(request.DATA, content) + +    # def test_accessing_post_after_data_form(self): +    #     """ +    #     Ensures request.POST can be accessed after request.DATA in +    #     form request. +    #     """ +    #     data = {'qwerty': 'uiop'} +    #     request = factory.post('/', data=data) +    #     self.assertEqual(request.DATA.items(), data.items()) +    #     self.assertEqual(request.POST.items(), data.items()) + +    # def test_accessing_post_after_data_for_json(self): +    #     """ +    #     Ensures request.POST can be accessed after request.DATA in +    #     json request. +    #     """ +    #     data = {'qwerty': 'uiop'} +    #     content = json.dumps(data) +    #     content_type = 'application/json' +    #     parsers = (JSONParser, ) + +    #     request = factory.post('/', content, content_type=content_type, +    #                            parsers=parsers) +    #     self.assertEqual(request.DATA.items(), data.items()) +    #     self.assertEqual(request.POST.items(), []) + +    # def test_accessing_post_after_data_for_overloaded_json(self): +    #     """ +    #     Ensures request.POST can be accessed after request.DATA in overloaded +    #     json request. +    #     """ +    #     data = {'qwerty': 'uiop'} +    #     content = json.dumps(data) +    #     content_type = 'application/json' +    #     parsers = (JSONParser, ) +    #     form_data = {Request._CONTENT_PARAM: content, +    #                  Request._CONTENTTYPE_PARAM: content_type} + +    #     request = factory.post('/', form_data, parsers=parsers) +    #     self.assertEqual(request.DATA.items(), data.items()) +    #     self.assertEqual(request.POST.items(), form_data.items()) + +    # def test_accessing_data_after_post_form(self): +    #     """ +    #     Ensures request.DATA can be accessed after request.POST in +    #     form request. +    #     """ +    #     data = {'qwerty': 'uiop'} +    #     parsers = (FormParser, MultiPartParser) +    #     request = factory.post('/', data, parsers=parsers) + +    #     self.assertEqual(request.POST.items(), data.items()) +    #     self.assertEqual(request.DATA.items(), data.items()) + +    # def test_accessing_data_after_post_for_json(self): +    #     """ +    #     Ensures request.DATA can be accessed after request.POST in +    #     json request. +    #     """ +    #     data = {'qwerty': 'uiop'} +    #     content = json.dumps(data) +    #     content_type = 'application/json' +    #     parsers = (JSONParser, ) +    #     request = factory.post('/', content, content_type=content_type, +    #                            parsers=parsers) +    #     self.assertEqual(request.POST.items(), []) +    #     self.assertEqual(request.DATA.items(), data.items()) + +    # def test_accessing_data_after_post_for_overloaded_json(self): +    #     """ +    #     Ensures request.DATA can be accessed after request.POST in overloaded +    #     json request +    #     """ +    #     data = {'qwerty': 'uiop'} +    #     content = json.dumps(data) +    #     content_type = 'application/json' +    #     parsers = (JSONParser, ) +    #     form_data = {Request._CONTENT_PARAM: content, +    #                  Request._CONTENTTYPE_PARAM: content_type} + +    #     request = factory.post('/', form_data, parsers=parsers) +    #     self.assertEqual(request.POST.items(), form_data.items()) +    #     self.assertEqual(request.DATA.items(), data.items()) + + +class MockView(APIView): +    authentication_classes = (SessionAuthentication,) + +    def post(self, request): +        if request.POST.get('example') is not None: +            return Response(status=status.HTTP_200_OK) + +        return Response(status=status.INTERNAL_SERVER_ERROR) + +urlpatterns = patterns('', +    (r'^$', MockView.as_view()), +) + + +class TestContentParsingWithAuthentication(TestCase): +    urls = 'rest_framework.tests.request' + +    def setUp(self): +        self.csrf_client = Client(enforce_csrf_checks=True) +        self.username = 'john' +        self.email = 'lennon@thebeatles.com' +        self.password = 'password' +        self.user = User.objects.create_user(self.username, self.email, self.password) + +    def test_user_logged_in_authentication_has_POST_when_not_logged_in(self): +        """ +        Ensures request.POST exists after SessionAuthentication when user +        doesn't log in. +        """ +        content = {'example': 'example'} + +        response = self.client.post('/', content) +        self.assertEqual(status.HTTP_200_OK, response.status_code) + +        response = self.csrf_client.post('/', content) +        self.assertEqual(status.HTTP_200_OK, response.status_code) + +    # def test_user_logged_in_authentication_has_post_when_logged_in(self): +    #     """Ensures request.POST exists after UserLoggedInAuthentication when user does log in""" +    #     self.client.login(username='john', password='password') +    #     self.csrf_client.login(username='john', password='password') +    #     content = {'example': 'example'} + +    #     response = self.client.post('/', content) +    #     self.assertEqual(status.OK, response.status_code, "POST data is malformed") + +    #     response = self.csrf_client.post('/', content) +    #     self.assertEqual(status.OK, response.status_code, "POST data is malformed") | 
