From b1c07670ca65084c5fef2bbb63d1f4163763014b Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 9 Sep 2014 17:46:28 +0100 Subject: Fleshing out serializer fields --- tests/test_model_field_mappings.py | 160 +++++++++++++++++++++++++++++++++++++ tests/test_modelinfo.py | 31 +++++++ tests/test_relations.py | 12 +-- tests/test_serializer_empty.py | 2 +- tests/test_serializers.py | 31 ------- 5 files changed, 198 insertions(+), 38 deletions(-) create mode 100644 tests/test_model_field_mappings.py create mode 100644 tests/test_modelinfo.py delete mode 100644 tests/test_serializers.py (limited to 'tests') diff --git a/tests/test_model_field_mappings.py b/tests/test_model_field_mappings.py new file mode 100644 index 00000000..dc254da4 --- /dev/null +++ b/tests/test_model_field_mappings.py @@ -0,0 +1,160 @@ +""" +The `ModelSerializer` and `HyperlinkedModelSerializer` classes are essentially +shortcuts for automatically creating serializers based on a given model class. + +These tests deal with ensuring that we correctly map the model fields onto +an appropriate set of serializer fields for each case. +""" +from django.db import models +from django.test import TestCase +from rest_framework import serializers + + +# Models for testing regular field mapping + +class RegularFieldsModel(models.Model): + auto_field = models.AutoField(primary_key=True) + big_integer_field = models.BigIntegerField() + boolean_field = models.BooleanField() + char_field = models.CharField(max_length=100) + comma_seperated_integer_field = models.CommaSeparatedIntegerField(max_length=100) + date_field = models.DateField() + datetime_field = models.DateTimeField() + decimal_field = models.DecimalField(max_digits=3, decimal_places=1) + email_field = models.EmailField(max_length=100) + float_field = models.FloatField() + integer_field = models.IntegerField() + null_boolean_field = models.NullBooleanField() + positive_integer_field = models.PositiveIntegerField() + positive_small_integer_field = models.PositiveSmallIntegerField() + slug_field = models.SlugField(max_length=100) + small_integer_field = models.SmallIntegerField() + text_field = models.TextField() + time_field = models.TimeField() + url_field = models.URLField(max_length=100) + + +REGULAR_FIELDS_REPR = """ +TestSerializer(): + auto_field = IntegerField(label='auto field', read_only=True) + big_integer_field = IntegerField(label='big integer field') + boolean_field = BooleanField(default=False, label='boolean field') + char_field = CharField(label='char field', max_length=100) + comma_seperated_integer_field = CharField(label='comma seperated integer field', max_length=100, validators=[]) + date_field = DateField(label='date field') + datetime_field = DateTimeField(label='datetime field') + decimal_field = DecimalField(decimal_places=1, label='decimal field', max_digits=3) + email_field = EmailField(label='email field', max_length=100) + float_field = FloatField(label='float field') + integer_field = IntegerField(label='integer field') + null_boolean_field = BooleanField(label='null boolean field', required=False) + positive_integer_field = IntegerField(label='positive integer field') + positive_small_integer_field = IntegerField(label='positive small integer field') + slug_field = SlugField(label='slug field', max_length=100) + small_integer_field = IntegerField(label='small integer field') + text_field = CharField(label='text field') + time_field = TimeField(label='time field') + url_field = URLField(label='url field', max_length=100) +""".strip() + + +# Model for testing relational field mapping + +class ForeignKeyTarget(models.Model): + char_field = models.CharField(max_length=100) + + +class ManyToManyTarget(models.Model): + char_field = models.CharField(max_length=100) + + +class OneToOneTarget(models.Model): + char_field = models.CharField(max_length=100) + + +class RelationalModel(models.Model): + foreign_key = models.ForeignKey(ForeignKeyTarget) + many_to_many = models.ManyToManyField(ManyToManyTarget) + one_to_one = models.OneToOneField(OneToOneTarget) + + +RELATIONAL_FLAT_REPR = """ +TestSerializer(): + id = IntegerField(label='ID', read_only=True) + foreign_key = PrimaryKeyRelatedField(label='foreign key', queryset=) + one_to_one = PrimaryKeyRelatedField(label='one to one', queryset=) + many_to_many = PrimaryKeyRelatedField(label='many to many', many=True, queryset=) +""".strip() + + +RELATIONAL_NESTED_REPR = """ +TestSerializer(): + id = IntegerField(label='ID', read_only=True) + foreign_key = NestedModelSerializer(read_only=True): + id = IntegerField(label='ID', read_only=True) + name = CharField(label='name', max_length=100) + one_to_one = NestedModelSerializer(read_only=True): + id = IntegerField(label='ID', read_only=True) + name = CharField(label='name', max_length=100) + many_to_many = NestedModelSerializer(many=True, read_only=True): + id = IntegerField(label='ID', read_only=True) + name = CharField(label='name', max_length=100) +""".strip() + + +HYPERLINKED_FLAT_REPR = """ +TestSerializer(): + url = HyperlinkedIdentityField(view_name='relationalmodel-detail') + foreign_key = HyperlinkedRelatedField(label='foreign key', queryset=, view_name='foreignkeytarget-detail') + one_to_one = HyperlinkedRelatedField(label='one to one', queryset=, view_name='onetoonetarget-detail') + many_to_many = HyperlinkedRelatedField(label='many to many', many=True, queryset=, view_name='manytomanytarget-detail') +""".strip() + + +HYPERLINKED_NESTED_REPR = """ +TestSerializer(): + url = HyperlinkedIdentityField(view_name='relationalmodel-detail') + foreign_key = NestedModelSerializer(read_only=True): + id = IntegerField(label='ID', read_only=True) + name = CharField(label='name', max_length=100) + one_to_one = NestedModelSerializer(read_only=True): + id = IntegerField(label='ID', read_only=True) + name = CharField(label='name', max_length=100) + many_to_many = NestedModelSerializer(many=True, read_only=True): + id = IntegerField(label='ID', read_only=True) + name = CharField(label='name', max_length=100) +""".strip() + + +class TestSerializerMappings(TestCase): + def test_regular_fields(self): + class TestSerializer(serializers.ModelSerializer): + class Meta: + model = RegularFieldsModel + self.assertEqual(repr(TestSerializer()), REGULAR_FIELDS_REPR) + + def test_flat_relational_fields(self): + class TestSerializer(serializers.ModelSerializer): + class Meta: + model = RelationalModel + self.assertEqual(repr(TestSerializer()), RELATIONAL_FLAT_REPR) + + def test_nested_relational_fields(self): + class TestSerializer(serializers.ModelSerializer): + class Meta: + model = RelationalModel + depth = 1 + self.assertEqual(repr(TestSerializer()), RELATIONAL_NESTED_REPR) + + def test_flat_hyperlinked_fields(self): + class TestSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = RelationalModel + self.assertEqual(repr(TestSerializer()), HYPERLINKED_FLAT_REPR) + + def test_nested_hyperlinked_fields(self): + class TestSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = RelationalModel + depth = 1 + self.assertEqual(repr(TestSerializer()), HYPERLINKED_NESTED_REPR) diff --git a/tests/test_modelinfo.py b/tests/test_modelinfo.py new file mode 100644 index 00000000..254a33c9 --- /dev/null +++ b/tests/test_modelinfo.py @@ -0,0 +1,31 @@ +from django.test import TestCase +from django.utils import six +from rest_framework.utils.modelinfo import _resolve_model +from tests.models import BasicModel + + +class ResolveModelTests(TestCase): + """ + `_resolve_model` should return a Django model class given the + provided argument is a Django model class itself, or a properly + formatted string representation of one. + """ + def test_resolve_django_model(self): + resolved_model = _resolve_model(BasicModel) + self.assertEqual(resolved_model, BasicModel) + + def test_resolve_string_representation(self): + resolved_model = _resolve_model('tests.BasicModel') + self.assertEqual(resolved_model, BasicModel) + + def test_resolve_unicode_representation(self): + resolved_model = _resolve_model(six.text_type('tests.BasicModel')) + self.assertEqual(resolved_model, BasicModel) + + def test_resolve_non_django_model(self): + with self.assertRaises(ValueError): + _resolve_model(TestCase) + + def test_resolve_improper_string_representation(self): + with self.assertRaises(ValueError): + _resolve_model('BasicModel') diff --git a/tests/test_relations.py b/tests/test_relations.py index a30b12e6..b1bc66b6 100644 --- a/tests/test_relations.py +++ b/tests/test_relations.py @@ -22,18 +22,18 @@ # https://github.com/tomchristie/django-rest-framework/issues/446 # """ # field = serializers.PrimaryKeyRelatedField(queryset=NullModel.objects.all()) -# self.assertRaises(serializers.ValidationError, field.from_native, '') -# self.assertRaises(serializers.ValidationError, field.from_native, []) +# self.assertRaises(serializers.ValidationError, field.to_primative, '') +# self.assertRaises(serializers.ValidationError, field.to_primative, []) # def test_hyperlinked_related_field_with_empty_string(self): # field = serializers.HyperlinkedRelatedField(queryset=NullModel.objects.all(), view_name='') -# self.assertRaises(serializers.ValidationError, field.from_native, '') -# self.assertRaises(serializers.ValidationError, field.from_native, []) +# self.assertRaises(serializers.ValidationError, field.to_primative, '') +# self.assertRaises(serializers.ValidationError, field.to_primative, []) # def test_slug_related_field_with_empty_string(self): # field = serializers.SlugRelatedField(queryset=NullModel.objects.all(), slug_field='pk') -# self.assertRaises(serializers.ValidationError, field.from_native, '') -# self.assertRaises(serializers.ValidationError, field.from_native, []) +# self.assertRaises(serializers.ValidationError, field.to_primative, '') +# self.assertRaises(serializers.ValidationError, field.to_primative, []) # class TestManyRelatedMixin(TestCase): diff --git a/tests/test_serializer_empty.py b/tests/test_serializer_empty.py index d0006ad3..4e4a7b42 100644 --- a/tests/test_serializer_empty.py +++ b/tests/test_serializer_empty.py @@ -6,7 +6,7 @@ # def test_empty_serializer(self): # class FooBarSerializer(serializers.Serializer): # foo = serializers.IntegerField() -# bar = serializers.SerializerMethodField('get_bar') +# bar = serializers.MethodField() # def get_bar(self, obj): # return 'bar' diff --git a/tests/test_serializers.py b/tests/test_serializers.py deleted file mode 100644 index 31c41730..00000000 --- a/tests/test_serializers.py +++ /dev/null @@ -1,31 +0,0 @@ -from django.test import TestCase -from django.utils import six -from rest_framework.serializers import _resolve_model -from tests.models import BasicModel - - -class ResolveModelTests(TestCase): - """ - `_resolve_model` should return a Django model class given the - provided argument is a Django model class itself, or a properly - formatted string representation of one. - """ - def test_resolve_django_model(self): - resolved_model = _resolve_model(BasicModel) - self.assertEqual(resolved_model, BasicModel) - - def test_resolve_string_representation(self): - resolved_model = _resolve_model('tests.BasicModel') - self.assertEqual(resolved_model, BasicModel) - - def test_resolve_unicode_representation(self): - resolved_model = _resolve_model(six.text_type('tests.BasicModel')) - self.assertEqual(resolved_model, BasicModel) - - def test_resolve_non_django_model(self): - with self.assertRaises(ValueError): - _resolve_model(TestCase) - - def test_resolve_improper_string_representation(self): - with self.assertRaises(ValueError): - _resolve_model('BasicModel') -- cgit v1.2.3