diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_metadata.py | 17 | ||||
| -rw-r--r-- | tests/test_parsers.py | 6 | ||||
| -rw-r--r-- | tests/test_renderers.py | 18 | ||||
| -rw-r--r-- | tests/test_routers.py | 14 | ||||
| -rw-r--r-- | tests/test_validators.py | 54 | 
5 files changed, 96 insertions, 13 deletions
| diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 5031c0f3..3a435f02 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -54,8 +54,12 @@ class TestMetadata:          """          class ExampleSerializer(serializers.Serializer):              choice_field = serializers.ChoiceField(['red', 'green', 'blue']) -            integer_field = serializers.IntegerField(max_value=10) -            char_field = serializers.CharField(required=False) +            integer_field = serializers.IntegerField( +                min_value=1, max_value=1000 +            ) +            char_field = serializers.CharField( +                required=False, min_length=3, max_length=40 +            )          class ExampleView(views.APIView):              """Example view.""" @@ -96,13 +100,18 @@ class TestMetadata:                          'type': 'integer',                          'required': True,                          'read_only': False, -                        'label': 'Integer field' +                        'label': 'Integer field', +                        'min_value': 1, +                        'max_value': 1000, +                      },                      'char_field': {                          'type': 'string',                          'required': False,                          'read_only': False, -                        'label': 'Char field' +                        'label': 'Char field', +                        'min_length': 3, +                        'max_length': 40                      }                  }              } diff --git a/tests/test_parsers.py b/tests/test_parsers.py index 8816065a..fe6aec19 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -99,11 +99,5 @@ class TestFileUploadParser(TestCase):          filename = parser.get_filename(self.stream, None, self.parser_context)          self.assertEqual(filename, 'ÀĥƦ.txt') -        self.__replace_content_disposition('inline; filename=fallback.txt; filename*=utf-8--ÀĥƦ.txt') -        filename = parser.get_filename(self.stream, None, self.parser_context) -        # Malformed. Either None or 'fallback.txt' will be acceptable. -        # See also https://code.djangoproject.com/ticket/24209 -        self.assertIn(filename, ('fallback.txt', None)) -      def __replace_content_disposition(self, disposition):          self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = disposition diff --git a/tests/test_renderers.py b/tests/test_renderers.py index 60a08225..cb76f683 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -10,7 +10,10 @@ from rest_framework import status, permissions  from rest_framework.compat import OrderedDict  from rest_framework.response import Response  from rest_framework.views import APIView -from rest_framework.renderers import BaseRenderer, JSONRenderer, BrowsableAPIRenderer +from rest_framework import serializers +from rest_framework.renderers import ( +    BaseRenderer, JSONRenderer, BrowsableAPIRenderer, HTMLFormRenderer +)  from rest_framework.settings import api_settings  from rest_framework.test import APIRequestFactory  from collections import MutableMapping @@ -455,3 +458,16 @@ class TestJSONIndentationStyles:          renderer.compact = False          data = OrderedDict([('a', 1), ('b', 2)])          assert renderer.render(data) == b'{"a": 1, "b": 2}' + + +class TestHiddenFieldHTMLFormRenderer(TestCase): +    def test_hidden_field_rendering(self): +        class TestSerializer(serializers.Serializer): +            published = serializers.HiddenField(default=True) + +        serializer = TestSerializer(data={}) +        serializer.is_valid() +        renderer = HTMLFormRenderer() +        field = serializer['published'] +        rendered = renderer.render_field(field, {}) +        assert rendered == '' diff --git a/tests/test_routers.py b/tests/test_routers.py index 948c69bb..08c58ec7 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -302,12 +302,16 @@ class DynamicListAndDetailViewSet(viewsets.ViewSet):          return Response({'method': 'link2'}) +class SubDynamicListAndDetailViewSet(DynamicListAndDetailViewSet): +    pass + +  class TestDynamicListAndDetailRouter(TestCase):      def setUp(self):          self.router = SimpleRouter() -    def test_list_and_detail_route_decorators(self): -        routes = self.router.get_routes(DynamicListAndDetailViewSet) +    def _test_list_and_detail_route_decorators(self, viewset): +        routes = self.router.get_routes(viewset)          decorator_routes = [r for r in routes if not (r.name.endswith('-list') or r.name.endswith('-detail'))]          MethodNamesMap = namedtuple('MethodNamesMap', 'method_name url_path') @@ -336,3 +340,9 @@ class TestDynamicListAndDetailRouter(TestCase):              else:                  method_map = 'get'              self.assertEqual(route.mapping[method_map], method_name) + +    def test_list_and_detail_route_decorators(self): +        self._test_list_and_detail_route_decorators(DynamicListAndDetailViewSet) + +    def test_inherited_list_and_detail_route_decorators(self): +        self._test_list_and_detail_route_decorators(SubDynamicListAndDetailViewSet) diff --git a/tests/test_validators.py b/tests/test_validators.py index 072cec36..127ec6f8 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -83,11 +83,37 @@ class UniquenessTogetherModel(models.Model):          unique_together = ('race_name', 'position') +class NullUniquenessTogetherModel(models.Model): +    """ +    Used to ensure that null values are not included when checking +    unique_together constraints. + +    Ignoring items which have a null in any of the validated fields is the same +    behavior that database backends will use when they have the +    unique_together constraint added. + +    Example case: a null position could indicate a non-finisher in the race, +    there could be many non-finishers in a race, but all non-NULL +    values *should* be unique against the given `race_name`. +    """ +    date_of_birth = models.DateField(null=True)  # Not part of the uniqueness constraint +    race_name = models.CharField(max_length=100) +    position = models.IntegerField(null=True) + +    class Meta: +        unique_together = ('race_name', 'position') + +  class UniquenessTogetherSerializer(serializers.ModelSerializer):      class Meta:          model = UniquenessTogetherModel +class NullUniquenessTogetherSerializer(serializers.ModelSerializer): +    class Meta: +        model = NullUniquenessTogetherModel + +  class TestUniquenessTogetherValidation(TestCase):      def setUp(self):          self.instance = UniquenessTogetherModel.objects.create( @@ -182,6 +208,34 @@ class TestUniquenessTogetherValidation(TestCase):          """)          assert repr(serializer) == expected +    def test_ignore_validation_for_null_fields(self): +        # None values that are on fields which are part of the uniqueness +        # constraint cause the instance to ignore uniqueness validation. +        NullUniquenessTogetherModel.objects.create( +            date_of_birth=datetime.date(2000, 1, 1), +            race_name='Paris Marathon', +            position=None +        ) +        data = { +            'date': datetime.date(2000, 1, 1), +            'race_name': 'Paris Marathon', +            'position': None +        } +        serializer = NullUniquenessTogetherSerializer(data=data) +        assert serializer.is_valid() + +    def test_do_not_ignore_validation_for_null_fields(self): +        # None values that are not on fields part of the uniqueness constraint +        # do not cause the instance to skip validation. +        NullUniquenessTogetherModel.objects.create( +            date_of_birth=datetime.date(2000, 1, 1), +            race_name='Paris Marathon', +            position=1 +        ) +        data = {'date': None, 'race_name': 'Paris Marathon', 'position': 1} +        serializer = NullUniquenessTogetherSerializer(data=data) +        assert not serializer.is_valid() +  # Tests for `UniqueForDateValidator`  # ---------------------------------- | 
