diff options
| author | Xavier Ordoquy | 2014-11-26 16:36:56 +0100 | 
|---|---|---|
| committer | Xavier Ordoquy | 2014-11-26 16:36:56 +0100 | 
| commit | f5e5ed0077cc477a7b8af98c7b10d8d3701f1a65 (patch) | |
| tree | 252729a9e61deb0dbc1a098feb1c55eae56ca948 /tests/test_metadata.py | |
| parent | 311d315a739f4d1d02e87a09de0bbf9e7b0cee46 (diff) | |
| parent | 2647e1aaaadfc2cfd947c633399dca1060c17401 (diff) | |
| download | django-rest-framework-f5e5ed0077cc477a7b8af98c7b10d8d3701f1a65.tar.bz2 | |
Merge remote-tracking branch 'reference/master' into bugfix/1850
Diffstat (limited to 'tests/test_metadata.py')
| -rw-r--r-- | tests/test_metadata.py | 166 | 
1 files changed, 166 insertions, 0 deletions
| diff --git a/tests/test_metadata.py b/tests/test_metadata.py new file mode 100644 index 00000000..5ff59c72 --- /dev/null +++ b/tests/test_metadata.py @@ -0,0 +1,166 @@ +from __future__ import unicode_literals + +from rest_framework import exceptions, serializers, views +from rest_framework.request import Request +from rest_framework.test import APIRequestFactory +import pytest + +request = Request(APIRequestFactory().options('/')) + + +class TestMetadata: +    def test_metadata(self): +        """ +        OPTIONS requests to views should return a valid 200 response. +        """ +        class ExampleView(views.APIView): +            """Example view.""" +            pass + +        response = ExampleView().options(request=request) +        expected = { +            'name': 'Example', +            'description': 'Example view.', +            'renders': [ +                'application/json', +                'text/html' +            ], +            'parses': [ +                'application/json', +                'application/x-www-form-urlencoded', +                'multipart/form-data' +            ] +        } +        assert response.status_code == 200 +        assert response.data == expected + +    def test_none_metadata(self): +        """ +        OPTIONS requests to views where `metadata_class = None` should raise +        a MethodNotAllowed exception, which will result in an HTTP 405 response. +        """ +        class ExampleView(views.APIView): +            metadata_class = None + +        with pytest.raises(exceptions.MethodNotAllowed): +            ExampleView().options(request=request) + +    def test_actions(self): +        """ +        On generic views OPTIONS should return an 'actions' key with metadata +        on the fields that may be supplied to PUT and POST requests. +        """ +        class ExampleSerializer(serializers.Serializer): +            choice_field = serializers.ChoiceField(['red', 'green', 'blue']) +            integer_field = serializers.IntegerField(max_value=10) +            char_field = serializers.CharField(required=False) + +        class ExampleView(views.APIView): +            """Example view.""" +            def post(self, request): +                pass + +            def get_serializer(self): +                return ExampleSerializer() + +        response = ExampleView().options(request=request) +        expected = { +            'name': 'Example', +            'description': 'Example view.', +            'renders': [ +                'application/json', +                'text/html' +            ], +            'parses': [ +                'application/json', +                'application/x-www-form-urlencoded', +                'multipart/form-data' +            ], +            'actions': { +                'POST': { +                    'choice_field': { +                        'type': 'choice', +                        'required': True, +                        'read_only': False, +                        'label': 'Choice field', +                        'choices': [ +                            {'display_name': 'red', 'value': 'red'}, +                            {'display_name': 'green', 'value': 'green'}, +                            {'display_name': 'blue', 'value': 'blue'} +                        ] +                    }, +                    'integer_field': { +                        'type': 'integer', +                        'required': True, +                        'read_only': False, +                        'label': 'Integer field' +                    }, +                    'char_field': { +                        'type': 'string', +                        'required': False, +                        'read_only': False, +                        'label': 'Char field' +                    } +                } +            } +        } +        assert response.status_code == 200 +        assert response.data == expected + +    def test_global_permissions(self): +        """ +        If a user does not have global permissions on an action, then any +        metadata associated with it should not be included in OPTION responses. +        """ +        class ExampleSerializer(serializers.Serializer): +            choice_field = serializers.ChoiceField(['red', 'green', 'blue']) +            integer_field = serializers.IntegerField(max_value=10) +            char_field = serializers.CharField(required=False) + +        class ExampleView(views.APIView): +            """Example view.""" +            def post(self, request): +                pass + +            def put(self, request): +                pass + +            def get_serializer(self): +                return ExampleSerializer() + +            def check_permissions(self, request): +                if request.method == 'POST': +                    raise exceptions.PermissionDenied() + +        response = ExampleView().options(request=request) +        assert response.status_code == 200 +        assert list(response.data['actions'].keys()) == ['PUT'] + +    def test_object_permissions(self): +        """ +        If a user does not have object permissions on an action, then any +        metadata associated with it should not be included in OPTION responses. +        """ +        class ExampleSerializer(serializers.Serializer): +            choice_field = serializers.ChoiceField(['red', 'green', 'blue']) +            integer_field = serializers.IntegerField(max_value=10) +            char_field = serializers.CharField(required=False) + +        class ExampleView(views.APIView): +            """Example view.""" +            def post(self, request): +                pass + +            def put(self, request): +                pass + +            def get_serializer(self): +                return ExampleSerializer() + +            def get_object(self): +                if self.request.method == 'PUT': +                    raise exceptions.PermissionDenied() + +        response = ExampleView().options(request=request) +        assert response.status_code == 200 +        assert list(response.data['actions'].keys()) == ['POST'] | 
