From 213981cef394c6f7603c24b9a51096ffb56f6024 Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Fri, 4 Jan 2013 21:11:03 +0100 Subject: Handle ObjectDoesNotExist exceptions when serializing null reverse one-to-one --- rest_framework/tests/models.py | 5 +++++ rest_framework/tests/relations_nested.py | 22 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index 59c35074..34cdbff3 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -205,3 +205,8 @@ class NullableForeignKeySource(RESTFrameworkModel): name = models.CharField(max_length=100) target = models.ForeignKey(ForeignKeyTarget, null=True, blank=True, related_name='nullable_sources') + +class NullableOneToOneSource(RESTFrameworkModel): + name = models.CharField(max_length=100) + target = models.OneToOneField(ForeignKeyTarget, null=True, blank=True, + related_name='nullable_source') diff --git a/rest_framework/tests/relations_nested.py b/rest_framework/tests/relations_nested.py index 5710c1ef..808399f7 100644 --- a/rest_framework/tests/relations_nested.py +++ b/rest_framework/tests/relations_nested.py @@ -1,7 +1,7 @@ from django.db import models from django.test import TestCase from rest_framework import serializers -from rest_framework.tests.models import ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource +from rest_framework.tests.models import ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, NullableOneToOneSource class ForeignKeySourceSerializer(serializers.ModelSerializer): @@ -28,6 +28,13 @@ class NullableForeignKeySourceSerializer(serializers.ModelSerializer): model = NullableForeignKeySource +class NullableForeignKeyTargetSerializer(serializers.ModelSerializer): + nullable_source = serializers.PrimaryKeyRelatedField() + + class Meta: + model = ForeignKeyTarget + + class ReverseForeignKeyTests(TestCase): def setUp(self): target = ForeignKeyTarget(name='target-1') @@ -67,6 +74,10 @@ class NestedNullableForeignKeyTests(TestCase): def setUp(self): target = ForeignKeyTarget(name='target-1') target.save() + new_target = ForeignKeyTarget(name='target-2') + new_target.save() + one_source = NullableOneToOneSource(name='one-source-1', target=target) + one_source.save() for idx in range(1, 4): if idx == 3: target = None @@ -82,3 +93,12 @@ class NestedNullableForeignKeyTests(TestCase): {'id': 3, 'name': u'source-3', 'target': None}, ] self.assertEquals(serializer.data, expected) + + def test_reverse_foreign_key_retrieve_with_null(self): + queryset = ForeignKeyTarget.objects.all() + serializer = NullableForeignKeyTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'nullable_source': 1}, + {'id': 2, 'name': u'target-2', 'nullable_source': None}, + ] + self.assertEquals(serializer.data, expected) -- cgit v1.2.3 From 4e8f55887d6ce86a2293f8b8cbb255bc58995336 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 7 Jan 2013 21:37:44 +0000 Subject: Clean up test slightly. Refs #552 --- rest_framework/tests/pagination.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/pagination.py b/rest_framework/tests/pagination.py index 81d297a1..3b550877 100644 --- a/rest_framework/tests/pagination.py +++ b/rest_framework/tests/pagination.py @@ -181,10 +181,10 @@ class UnitTestPagination(TestCase): """ Ensure context gets passed through to the object serializer. """ - serializer = PassOnContextPaginationSerializer(self.first_page) + serializer = PassOnContextPaginationSerializer(self.first_page, context={'foo': 'bar'}) serializer.data results = serializer.fields[serializer.results_field] - self.assertTrue(serializer.context is results.context) + self.assertEquals(serializer.context, results.context) class TestUnpaginated(TestCase): -- cgit v1.2.3 From a897eb5480348838b11fdb428ce0d110e8bc8da1 Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Mon, 7 Jan 2013 16:27:31 -0800 Subject: Create separate *NullableOneToOneTests TestCase --- rest_framework/tests/models.py | 8 +++++- rest_framework/tests/relations_hyperlink.py | 38 +++++++++++++++++++++++------ rest_framework/tests/relations_nested.py | 33 ++++++++++++++++--------- rest_framework/tests/relations_pk.py | 29 +++++++++++++++++++++- 4 files changed, 88 insertions(+), 20 deletions(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index 34cdbff3..93f09761 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -206,7 +206,13 @@ class NullableForeignKeySource(RESTFrameworkModel): target = models.ForeignKey(ForeignKeyTarget, null=True, blank=True, related_name='nullable_sources') + +# OneToOne +class OneToOneTarget(RESTFrameworkModel): + name = models.CharField(max_length=100) + + class NullableOneToOneSource(RESTFrameworkModel): name = models.CharField(max_length=100) - target = models.OneToOneField(ForeignKeyTarget, null=True, blank=True, + target = models.OneToOneField(OneToOneTarget, null=True, blank=True, related_name='nullable_source') diff --git a/rest_framework/tests/relations_hyperlink.py b/rest_framework/tests/relations_hyperlink.py index a7f8a035..ef57dc83 100644 --- a/rest_framework/tests/relations_hyperlink.py +++ b/rest_framework/tests/relations_hyperlink.py @@ -2,7 +2,7 @@ from django.db import models from django.test import TestCase from rest_framework import serializers from rest_framework.compat import patterns, url -from rest_framework.tests.models import ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource +from rest_framework.tests.models import ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource def dummy_view(request, pk): pass @@ -13,6 +13,8 @@ urlpatterns = patterns('', url(r'^foreignkeysource/(?P[0-9]+)/$', dummy_view, name='foreignkeysource-detail'), url(r'^foreignkeytarget/(?P[0-9]+)/$', dummy_view, name='foreignkeytarget-detail'), url(r'^nullableforeignkeysource/(?P[0-9]+)/$', dummy_view, name='nullableforeignkeysource-detail'), + url(r'^onetoonetarget/(?P[0-9]+)/$', dummy_view, name='onetoonetarget-detail'), + url(r'^nullableonetoonesource/(?P[0-9]+)/$', dummy_view, name='nullableonetoonesource-detail'), ) class ManyToManyTargetSerializer(serializers.HyperlinkedModelSerializer): @@ -40,16 +42,17 @@ class ForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer): # Nullable ForeignKey +class NullableForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = NullableForeignKeySource -class NullableForeignKeySource(models.Model): - name = models.CharField(max_length=100) - target = models.ForeignKey(ForeignKeyTarget, null=True, blank=True, - related_name='nullable_sources') +# OneToOne +class NullableOneToOneTargetSerializer(serializers.HyperlinkedModelSerializer): + nullable_source = serializers.HyperlinkedRelatedField(view_name='nullableonetoonesource-detail') -class NullableForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer): class Meta: - model = NullableForeignKeySource + model = OneToOneTarget # TODO: Add test that .data cannot be accessed prior to .is_valid @@ -409,3 +412,24 @@ class HyperlinkedNullableForeignKeyTests(TestCase): # {'id': 2, 'name': u'target-2', 'sources': []}, # ] # self.assertEquals(serializer.data, expected) + + +class HyperlinkedNullableOneToOneTests(TestCase): + urls = 'rest_framework.tests.relations_hyperlink' + + def setUp(self): + target = OneToOneTarget(name='target-1') + target.save() + new_target = OneToOneTarget(name='target-2') + new_target.save() + source = NullableOneToOneSource(name='source-1', target=target) + source.save() + + def test_reverse_foreign_key_retrieve_with_null(self): + queryset = OneToOneTarget.objects.all() + serializer = NullableOneToOneTargetSerializer(queryset) + expected = [ + {'url': '/onetoonetarget/1/', 'name': u'target-1', 'nullable_source': '/nullableonetoonesource/1/'}, + {'url': '/onetoonetarget/2/', 'name': u'target-2', 'nullable_source': None}, + ] + self.assertEquals(serializer.data, expected) diff --git a/rest_framework/tests/relations_nested.py b/rest_framework/tests/relations_nested.py index 808399f7..225fee88 100644 --- a/rest_framework/tests/relations_nested.py +++ b/rest_framework/tests/relations_nested.py @@ -1,7 +1,7 @@ from django.db import models from django.test import TestCase from rest_framework import serializers -from rest_framework.tests.models import ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, NullableOneToOneSource +from rest_framework.tests.models import ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource class ForeignKeySourceSerializer(serializers.ModelSerializer): @@ -28,11 +28,16 @@ class NullableForeignKeySourceSerializer(serializers.ModelSerializer): model = NullableForeignKeySource -class NullableForeignKeyTargetSerializer(serializers.ModelSerializer): - nullable_source = serializers.PrimaryKeyRelatedField() +class NullableOneToOneSourceSerializer(serializers.ModelSerializer): + class Meta: + model = NullableOneToOneSource + + +class NullableOneToOneTargetSerializer(serializers.ModelSerializer): + nullable_source = NullableOneToOneSourceSerializer() class Meta: - model = ForeignKeyTarget + model = OneToOneTarget class ReverseForeignKeyTests(TestCase): @@ -74,10 +79,6 @@ class NestedNullableForeignKeyTests(TestCase): def setUp(self): target = ForeignKeyTarget(name='target-1') target.save() - new_target = ForeignKeyTarget(name='target-2') - new_target.save() - one_source = NullableOneToOneSource(name='one-source-1', target=target) - one_source.save() for idx in range(1, 4): if idx == 3: target = None @@ -94,11 +95,21 @@ class NestedNullableForeignKeyTests(TestCase): ] self.assertEquals(serializer.data, expected) + +class NestedNullableOneToOneTests(TestCase): + def setUp(self): + target = OneToOneTarget(name='target-1') + target.save() + new_target = OneToOneTarget(name='target-2') + new_target.save() + source = NullableOneToOneSource(name='source-1', target=target) + source.save() + def test_reverse_foreign_key_retrieve_with_null(self): - queryset = ForeignKeyTarget.objects.all() - serializer = NullableForeignKeyTargetSerializer(queryset) + queryset = OneToOneTarget.objects.all() + serializer = NullableOneToOneTargetSerializer(queryset) expected = [ - {'id': 1, 'name': u'target-1', 'nullable_source': 1}, + {'id': 1, 'name': u'target-1', 'nullable_source': {'id': 1, 'name': u'source-1', 'target': 1}}, {'id': 2, 'name': u'target-2', 'nullable_source': None}, ] self.assertEquals(serializer.data, expected) diff --git a/rest_framework/tests/relations_pk.py b/rest_framework/tests/relations_pk.py index af6da2c0..589b3646 100644 --- a/rest_framework/tests/relations_pk.py +++ b/rest_framework/tests/relations_pk.py @@ -1,7 +1,7 @@ from django.db import models from django.test import TestCase from rest_framework import serializers -from rest_framework.tests.models import ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource +from rest_framework.tests.models import ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource class ManyToManyTargetSerializer(serializers.ModelSerializer): @@ -33,6 +33,14 @@ class NullableForeignKeySourceSerializer(serializers.ModelSerializer): model = NullableForeignKeySource +# OneToOne +class NullableOneToOneTargetSerializer(serializers.ModelSerializer): + nullable_source = serializers.PrimaryKeyRelatedField() + + class Meta: + model = OneToOneTarget + + # TODO: Add test that .data cannot be accessed prior to .is_valid class PKManyToManyTests(TestCase): @@ -383,3 +391,22 @@ class PKNullableForeignKeyTests(TestCase): # {'id': 2, 'name': u'target-2', 'sources': []}, # ] # self.assertEquals(serializer.data, expected) + + +class PKNullableOneToOneTests(TestCase): + def setUp(self): + target = OneToOneTarget(name='target-1') + target.save() + new_target = OneToOneTarget(name='target-2') + new_target.save() + source = NullableOneToOneSource(name='source-1', target=target) + source.save() + + def test_reverse_foreign_key_retrieve_with_null(self): + queryset = OneToOneTarget.objects.all() + serializer = NullableOneToOneTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'nullable_source': 1}, + {'id': 2, 'name': u'target-2', 'nullable_source': None}, + ] + self.assertEquals(serializer.data, expected) -- cgit v1.2.3 From 268f60999cdca46e6541f5acc35fbbe08b85f477 Mon Sep 17 00:00:00 2001 From: Juan Riaza Date: Thu, 10 Jan 2013 15:48:22 +0100 Subject: unused imports --- rest_framework/tests/decorators.py | 1 - rest_framework/tests/relations_hyperlink.py | 1 - rest_framework/tests/relations_nested.py | 1 - rest_framework/tests/relations_pk.py | 1 - 4 files changed, 4 deletions(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/decorators.py b/rest_framework/tests/decorators.py index bc44a45b..5e6bce4e 100644 --- a/rest_framework/tests/decorators.py +++ b/rest_framework/tests/decorators.py @@ -1,5 +1,4 @@ from django.test import TestCase -from django.test.client import RequestFactory from rest_framework import status from rest_framework.response import Response from rest_framework.renderers import JSONRenderer diff --git a/rest_framework/tests/relations_hyperlink.py b/rest_framework/tests/relations_hyperlink.py index ef57dc83..57913670 100644 --- a/rest_framework/tests/relations_hyperlink.py +++ b/rest_framework/tests/relations_hyperlink.py @@ -1,4 +1,3 @@ -from django.db import models from django.test import TestCase from rest_framework import serializers from rest_framework.compat import patterns, url diff --git a/rest_framework/tests/relations_nested.py b/rest_framework/tests/relations_nested.py index 225fee88..0e129fae 100644 --- a/rest_framework/tests/relations_nested.py +++ b/rest_framework/tests/relations_nested.py @@ -1,4 +1,3 @@ -from django.db import models from django.test import TestCase from rest_framework import serializers from rest_framework.tests.models import ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource diff --git a/rest_framework/tests/relations_pk.py b/rest_framework/tests/relations_pk.py index 589b3646..54835860 100644 --- a/rest_framework/tests/relations_pk.py +++ b/rest_framework/tests/relations_pk.py @@ -1,4 +1,3 @@ -from django.db import models from django.test import TestCase from rest_framework import serializers from rest_framework.tests.models import ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource -- cgit v1.2.3 From 73c4e5c4603e24ec1ea9976a3c6152a797f8f041 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 12 Jan 2013 09:32:53 +0000 Subject: auto_now and auto_now_add fields should be read only by default --- rest_framework/tests/fields.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 rest_framework/tests/fields.py (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py new file mode 100644 index 00000000..b1a8161a --- /dev/null +++ b/rest_framework/tests/fields.py @@ -0,0 +1,26 @@ +""" +General tests for relational fields. +""" + +from django.db import models +from django.test import TestCase +from rest_framework import serializers + + +class TimestampedModel(models.Model): + added = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + + +class TimestampedModelSerializer(serializers.ModelSerializer): + class Meta: + model = TimestampedModel + + +class ReadOnlyFieldTests(TestCase): + def test_auto_now_fields_read_only(self): + """ + auto_now and auto_now_add fields should be readonly by default. + """ + serializer = TimestampedModelSerializer() + self.assertEquals(serializer.fields['added'].read_only, True) -- cgit v1.2.3 From d9acec3e6dd07d33f416646bc161108ea52842d6 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 12 Jan 2013 09:43:07 +0000 Subject: PK fields should only be read-only if they are an AutoField. Fixes #563 --- rest_framework/tests/fields.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py index b1a8161a..a6a05941 100644 --- a/rest_framework/tests/fields.py +++ b/rest_framework/tests/fields.py @@ -12,11 +12,20 @@ class TimestampedModel(models.Model): updated = models.DateTimeField(auto_now=True) +class CharPrimaryKeyModel(models.Model): + id = models.CharField(max_length=20, primary_key=True) + + class TimestampedModelSerializer(serializers.ModelSerializer): class Meta: model = TimestampedModel +class CharPrimaryKeyModelSerializer(serializers.ModelSerializer): + class Meta: + model = CharPrimaryKeyModel + + class ReadOnlyFieldTests(TestCase): def test_auto_now_fields_read_only(self): """ @@ -24,3 +33,11 @@ class ReadOnlyFieldTests(TestCase): """ serializer = TimestampedModelSerializer() self.assertEquals(serializer.fields['added'].read_only, True) + + def test_auto_pk_fields_read_only(self): + serializer = TimestampedModelSerializer() + self.assertEquals(serializer.fields['id'].read_only, True) + + def test_non_auto_pk_fields_not_read_only(self): + serializer = CharPrimaryKeyModelSerializer() + self.assertEquals(serializer.fields['id'].read_only, False) -- cgit v1.2.3 From da6b9576c5c5f019800555108fc86887ef7e453d Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 15 Jan 2013 10:51:10 +0000 Subject: Update docstrings --- rest_framework/tests/fields.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py index a6a05941..8068272d 100644 --- a/rest_framework/tests/fields.py +++ b/rest_framework/tests/fields.py @@ -1,5 +1,5 @@ """ -General tests for relational fields. +General serializer field tests. """ from django.db import models @@ -29,15 +29,21 @@ class CharPrimaryKeyModelSerializer(serializers.ModelSerializer): class ReadOnlyFieldTests(TestCase): def test_auto_now_fields_read_only(self): """ - auto_now and auto_now_add fields should be readonly by default. + auto_now and auto_now_add fields should be read_only by default. """ serializer = TimestampedModelSerializer() self.assertEquals(serializer.fields['added'].read_only, True) def test_auto_pk_fields_read_only(self): + """ + AutoField fields should be read_only by default. + """ serializer = TimestampedModelSerializer() self.assertEquals(serializer.fields['id'].read_only, True) def test_non_auto_pk_fields_not_read_only(self): + """ + PK fields other than AutoField fields should not be read_only by default. + """ serializer = CharPrimaryKeyModelSerializer() self.assertEquals(serializer.fields['id'].read_only, False) -- cgit v1.2.3 From 87029122c287b4a03e309a432dc9f9668efd7c0e Mon Sep 17 00:00:00 2001 From: Steven Gregory Date: Tue, 15 Jan 2013 13:49:48 -0700 Subject: Added a new file 'relations_slug.py' that tests Nullable Foreign Keys and the SlugRelatedField --- rest_framework/tests/relations_slug.py | 281 +++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 rest_framework/tests/relations_slug.py (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/relations_slug.py b/rest_framework/tests/relations_slug.py new file mode 100644 index 00000000..d56f4d4a --- /dev/null +++ b/rest_framework/tests/relations_slug.py @@ -0,0 +1,281 @@ +from django.test import TestCase +from rest_framework import serializers +from rest_framework.compat import patterns, url +from rest_framework.tests.models import NullableForeignKeySource, ForeignKeyTarget + +def dummy_view(request, pk): + pass + + +# Nullable ForeignKey +class SluggedNullableForeignKeySourceSerializer(serializers.ModelSerializer): + target = serializers.SlugRelatedField(slug_field='name') + class Meta: + model = NullableForeignKeySource + +class NullOKSluggedNullableForeignKeySourceSerializer(serializers.ModelSerializer): + target = serializers.SlugRelatedField(slug_field='name', null=True) + class Meta: + model = NullableForeignKeySource + +class DefaultSluggedNullableForeignKeySourceSerializer(serializers.ModelSerializer): + target = serializers.SlugRelatedField(slug_field='name', default='N/A') + class Meta: + model = NullableForeignKeySource + +class NotRequiredSluggedNullableForeignKeySourceSerializer(serializers.ModelSerializer): + target = serializers.SlugRelatedField(slug_field='name', required=False) + class Meta: + model = NullableForeignKeySource + + +class SluggedNullableForeignKeyTests(TestCase): + + def setUp(self): + target = ForeignKeyTarget(name='target-1') + target.save() + for idx in range(1, 4): + if idx == 3: + target = None + source = NullableForeignKeySource(name='source-%d' % idx, target=target) + source.save() + + def test_slug_foreign_key_retrieve_with_null(self): + queryset = NullableForeignKeySource.objects.all() + + default_expected = [ + {'name': u'source-1', 'target': 'target-1'}, + {'name': u'source-2', 'target': 'target-1'}, + {'name': u'source-3', 'target': 'N/A'}, + ] + expected = [ + {'name': u'source-1', 'target': 'target-1'}, + {'name': u'source-2', 'target': 'target-1'}, + {'name': u'source-3', 'target': None}, + ] + + serializer = DefaultSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, default_expected) + + serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, expected) + + serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, expected) + + serializer = SluggedNullableForeignKeySourceSerializer(queryset) + #Throws + self.assertEquals(serializer.data, expected) + + def test_slug_foreign_key_create_with_valid_null(self): + data = {'name': u'source-4', 'target': None} + default_data = {'name': u'source-4', 'target': 'N/A'} + + serializer = SluggedNullableForeignKeySourceSerializer(data=data) + self.assertFalse(serializer.is_valid()) + self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) + + + #If attribute not required, data should match + serializer = NullOKSluggedNullableForeignKeySourceSerializer(data=data) + self.assertTrue(serializer.is_valid()) + obj = serializer.save() + #BUG: Throws AttributeError: "NoneType object has no attribute 'name'" + self.assertEquals(serializer.data, data) + self.assertEqual(obj.name, u'source-4') + + #If default = 'N/A' then target should pass validation, and be the default ('N/A') + serializer = DefaultSluggedNullableForeignKeySourceSerializer(data=data) + #BUG: test case fails + self.assertTrue(serializer.is_valid()) + #BUG: serializer.errors = {'target': [u'Value may not be null']} + #BUG: Serializer does not use default value to save object + obj = serializer.save() + #BUG: Throws AttributeError - NoneType object has no attribute 'name' + self.assertEquals(serializer.data, data) + self.assertEqual(obj.name, u'source-4') + + #If null = True then target should be None + serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(data=data) + #BUG: test case fails + self.assertTrue(serializer.is_valid()) + #BUG: serializer.errors = {'target': [u'Value may not be null']} + #BUG: serializer does not save object (But it can because its not required) + obj = serializer.save() + #BUG: Throws AttributeError - NoneType object has no attribute 'name' + self.assertEquals(serializer.data, data) + self.assertEqual(obj.name, u'source-4') + + # Ensure source 4 is created, and everything else is as expected + queryset = NullableForeignKeySource.objects.all() + default_expected = [ + {'name': u'source-1', 'target': 'target-1'}, + {'name': u'source-2', 'target': 'target-1'}, + {'name': u'source-3', 'target': 'N/A'}, + {'name': u'source-4', 'target': 'N/A'} + ] + expected = [ + {'name': u'source-1', 'target': 'target-1'}, + {'name': u'source-2', 'target': 'target-1'}, + {'name': u'source-3', 'target': None}, + {'name': u'source-4', 'target': None} + ] + serializer = NullOKSluggedNullableForeignKeySourceSerializer(data=data) + self.assertEquals(serializer.data, expected) + serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(data=data) + self.assertEquals(serializer.data, expected) + serializer = DefaultSluggedNullableForeignKeySourceSerializer(data=data) + self.assertEquals(serializer.data, default_expected) + + def test_slug_foreign_key_create_with_valid_emptystring(self): + """ + The emptystring should be interpreted as null in the context + of relationships. + """ + data = {'name': u'source-4', 'target': ''} + expected_data = {'name': u'source-4', 'target': None} + + serializer = SluggedNullableForeignKeySourceSerializer(data=data) + self.assertFalse(serializer.is_valid()) + self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) + + serializer = NullOKSluggedNullableForeignKeySourceSerializer(data=data) + self.assertTrue(serializer.is_valid()) + obj = serializer.save() + #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' + self.assertEquals(serializer.data, expected_data) + self.assertEqual(obj.name, u'source-4') + + serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(data=data) + #BUG: is_valid() is False + self.assertTrue(serializer.is_valid()) + obj = serializer.save() + #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' + self.assertEquals(serializer.data, expected_data) + self.assertEqual(obj.name, u'source-4') + + serializer = DefaultSluggedNullableForeignKeySourceSerializer(data=data) + #BUG: is_valid() is False + self.assertTrue(serializer.is_valid()) + obj = serializer.save() + #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' + self.assertEquals(serializer.data, expected_data) + self.assertEqual(obj.name, u'source-4') + + # Ensure source 4 is created, and everything else is as expected + queryset = NullableForeignKeySource.objects.all() + default_expected = [ + {'name': u'source-1', 'target': 'target-1'}, + {'name': u'source-2', 'target': 'target-1'}, + {'name': u'source-3', 'target': 'N/A'}, + {'name': u'source-4', 'target': 'N/A'} + ] + expected = [ + {'name': u'source-1', 'target': 'target-1'}, + {'name': u'source-2', 'target': 'target-1'}, + {'name': u'source-3', 'target': None}, + {'name': u'source-4', 'target': None} + ] + #BUG: All serializers fail here + serializer = DefaultSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, default_expected) + serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, expected) + serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, expected) + + def test_slug_foreign_key_update_with_valid_null(self): + data = {'name': u'source-1', 'target': None} + default_data = {'name': u'source-1', 'target': 'N/A'} + instance = NullableForeignKeySource.objects.get(pk=1) + + serializer = SluggedNullableForeignKeySourceSerializer(instance, data=data) + self.assertFalse(serializer.is_valid()) + self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) + + serializer = DefaultSluggedNullableForeignKeySourceSerializer(instance, data=data) + #BUG: is_valid() is False + self.assertTrue(serializer.is_valid()) + self.assertEquals(serializer.data, default_data) + serializer.save() + + serializer = NullOKSluggedNullableForeignKeySourceSerializer(instance, data=data) + self.assertTrue(serializer.is_valid()) + #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' + self.assertEquals(serializer.data, data) + serializer.save() + + + serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(instance, data=data) + #BUG: is_valid() is False + self.assertTrue(serializer.is_valid()) + #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' + self.assertEquals(serializer.data, data) + serializer.save() + + # Ensure source 1 is updated, and everything else is as expected + queryset = NullableForeignKeySource.objects.all() + expected = [ + {'name': u'source-1', 'target': None}, + {'name': u'source-2', 'target': 'target-1'}, + {'name': u'source-3', 'target': None}, + ] + serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, expected) + + serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, expected) + + expected = [ + {'name': u'source-1', 'target': 'N/A'}, + {'name': u'source-2', 'target': 'target-1'}, + {'name': u'source-3', 'target': 'N/A'}, + ] + serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, expected) + + def test_slug_foreign_key_update_with_valid_emptystring(self): + """ + The emptystring should be interpreted as null in the context + of relationships. + """ + data = {'name': u'source-1', 'target': ''} + default_data = {'name': u'source-1', 'target': 'N/A'} + expected_data = {'name': u'source-1', 'target': None} + instance = NullableForeignKeySource.objects.get(pk=1) + + serializer = SluggedNullableForeignKeySourceSerializer(instance, data=data) + self.assertFalse(serializer.is_valid()) + self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) + + serializer = DefaultSluggedNullableForeignKeySourceSerializer(instance, data=data) + #BUG: is_valid() is False + self.assertTrue(serializer.is_valid()) + self.assertEquals(serializer.data, default_data) + serializer.save() + + serializer = NullOKSluggedNullableForeignKeySourceSerializer(instance, data=data) + self.assertTrue(serializer.is_valid()) + #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' + self.assertEquals(serializer.data, data) + serializer.save() + + serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(instance, data=data) + #BUG: is_valid() is False + self.assertTrue(serializer.is_valid()) + #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' + self.assertEquals(serializer.data, data) + serializer.save() + + # Ensure source 1 is updated, and everything else is as expected + queryset = NullableForeignKeySource.objects.all() + expected = [ + {'name': u'source-1', 'target': None}, + {'name': u'source-2', 'target': 'target-1'}, + {'name': u'source-3', 'target': None}, + ] + serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, expected) + serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(queryset) + self.assertEquals(serializer.data, expected) + -- cgit v1.2.3 From eb3d4d0e93b07d245232685d4fe3ad78144ea933 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 16 Jan 2013 14:32:51 +0000 Subject: Drop bits of relations_slug tests which don't mirror existing tests. --- rest_framework/tests/relations_hyperlink.py | 2 + rest_framework/tests/relations_pk.py | 2 +- rest_framework/tests/relations_slug.py | 246 +++++----------------------- 3 files changed, 44 insertions(+), 206 deletions(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/relations_hyperlink.py b/rest_framework/tests/relations_hyperlink.py index 57913670..7d65eae7 100644 --- a/rest_framework/tests/relations_hyperlink.py +++ b/rest_framework/tests/relations_hyperlink.py @@ -3,6 +3,7 @@ from rest_framework import serializers from rest_framework.compat import patterns, url from rest_framework.tests.models import ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource + def dummy_view(request, pk): pass @@ -16,6 +17,7 @@ urlpatterns = patterns('', url(r'^nullableonetoonesource/(?P[0-9]+)/$', dummy_view, name='nullableonetoonesource-detail'), ) + class ManyToManyTargetSerializer(serializers.HyperlinkedModelSerializer): sources = serializers.ManyHyperlinkedRelatedField(view_name='manytomanysource-detail') diff --git a/rest_framework/tests/relations_pk.py b/rest_framework/tests/relations_pk.py index 54835860..dd1e86b5 100644 --- a/rest_framework/tests/relations_pk.py +++ b/rest_framework/tests/relations_pk.py @@ -206,7 +206,7 @@ class PKForeignKeyTests(TestCase): expected = [ {'id': 1, 'name': u'target-1', 'sources': [1, 2, 3]}, {'id': 2, 'name': u'target-2', 'sources': []}, - ] + ] self.assertEquals(new_serializer.data, expected) serializer.save() diff --git a/rest_framework/tests/relations_slug.py b/rest_framework/tests/relations_slug.py index d56f4d4a..503b61e8 100644 --- a/rest_framework/tests/relations_slug.py +++ b/rest_framework/tests/relations_slug.py @@ -1,36 +1,18 @@ from django.test import TestCase from rest_framework import serializers -from rest_framework.compat import patterns, url from rest_framework.tests.models import NullableForeignKeySource, ForeignKeyTarget -def dummy_view(request, pk): - pass - -# Nullable ForeignKey -class SluggedNullableForeignKeySourceSerializer(serializers.ModelSerializer): - target = serializers.SlugRelatedField(slug_field='name') - class Meta: - model = NullableForeignKeySource - -class NullOKSluggedNullableForeignKeySourceSerializer(serializers.ModelSerializer): +class NullableSlugSourceSerializer(serializers.ModelSerializer): target = serializers.SlugRelatedField(slug_field='name', null=True) - class Meta: - model = NullableForeignKeySource -class DefaultSluggedNullableForeignKeySourceSerializer(serializers.ModelSerializer): - target = serializers.SlugRelatedField(slug_field='name', default='N/A') class Meta: model = NullableForeignKeySource -class NotRequiredSluggedNullableForeignKeySourceSerializer(serializers.ModelSerializer): - target = serializers.SlugRelatedField(slug_field='name', required=False) - class Meta: - model = NullableForeignKeySource +# TODO: M2M Tests, FKTests (Non-nulable), One2One -class SluggedNullableForeignKeyTests(TestCase): - +class SlugNullableForeignKeyTests(TestCase): def setUp(self): target = ForeignKeyTarget(name='target-1') target.save() @@ -40,242 +22,96 @@ class SluggedNullableForeignKeyTests(TestCase): source = NullableForeignKeySource(name='source-%d' % idx, target=target) source.save() - def test_slug_foreign_key_retrieve_with_null(self): + def test_foreign_key_retrieve_with_null(self): queryset = NullableForeignKeySource.objects.all() - - default_expected = [ - {'name': u'source-1', 'target': 'target-1'}, - {'name': u'source-2', 'target': 'target-1'}, - {'name': u'source-3', 'target': 'N/A'}, - ] + serializer = NullableSlugSourceSerializer(queryset) expected = [ - {'name': u'source-1', 'target': 'target-1'}, - {'name': u'source-2', 'target': 'target-1'}, - {'name': u'source-3', 'target': None}, + {'id': 1, 'name': u'source-1', 'target': 'target-1'}, + {'id': 2, 'name': u'source-2', 'target': 'target-1'}, + {'id': 3, 'name': u'source-3', 'target': None}, ] - - serializer = DefaultSluggedNullableForeignKeySourceSerializer(queryset) - self.assertEquals(serializer.data, default_expected) - - serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(queryset) - self.assertEquals(serializer.data, expected) - - serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) self.assertEquals(serializer.data, expected) - serializer = SluggedNullableForeignKeySourceSerializer(queryset) - #Throws - self.assertEquals(serializer.data, expected) - - def test_slug_foreign_key_create_with_valid_null(self): - data = {'name': u'source-4', 'target': None} - default_data = {'name': u'source-4', 'target': 'N/A'} - - serializer = SluggedNullableForeignKeySourceSerializer(data=data) - self.assertFalse(serializer.is_valid()) - self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) - - - #If attribute not required, data should match - serializer = NullOKSluggedNullableForeignKeySourceSerializer(data=data) - self.assertTrue(serializer.is_valid()) - obj = serializer.save() - #BUG: Throws AttributeError: "NoneType object has no attribute 'name'" - self.assertEquals(serializer.data, data) - self.assertEqual(obj.name, u'source-4') - - #If default = 'N/A' then target should pass validation, and be the default ('N/A') - serializer = DefaultSluggedNullableForeignKeySourceSerializer(data=data) - #BUG: test case fails + def test_foreign_key_create_with_valid_null(self): + data = {'id': 4, 'name': u'source-4', 'target': None} + serializer = NullableSlugSourceSerializer(data=data) self.assertTrue(serializer.is_valid()) - #BUG: serializer.errors = {'target': [u'Value may not be null']} - #BUG: Serializer does not use default value to save object obj = serializer.save() - #BUG: Throws AttributeError - NoneType object has no attribute 'name' - self.assertEquals(serializer.data, data) - self.assertEqual(obj.name, u'source-4') - - #If null = True then target should be None - serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(data=data) - #BUG: test case fails - self.assertTrue(serializer.is_valid()) - #BUG: serializer.errors = {'target': [u'Value may not be null']} - #BUG: serializer does not save object (But it can because its not required) - obj = serializer.save() - #BUG: Throws AttributeError - NoneType object has no attribute 'name' self.assertEquals(serializer.data, data) self.assertEqual(obj.name, u'source-4') # Ensure source 4 is created, and everything else is as expected queryset = NullableForeignKeySource.objects.all() - default_expected = [ - {'name': u'source-1', 'target': 'target-1'}, - {'name': u'source-2', 'target': 'target-1'}, - {'name': u'source-3', 'target': 'N/A'}, - {'name': u'source-4', 'target': 'N/A'} - ] + serializer = NullableSlugSourceSerializer(queryset) expected = [ - {'name': u'source-1', 'target': 'target-1'}, - {'name': u'source-2', 'target': 'target-1'}, - {'name': u'source-3', 'target': None}, - {'name': u'source-4', 'target': None} + {'id': 1, 'name': u'source-1', 'target': 'target-1'}, + {'id': 2, 'name': u'source-2', 'target': 'target-1'}, + {'id': 3, 'name': u'source-3', 'target': None}, + {'id': 4, 'name': u'source-4', 'target': None} ] - serializer = NullOKSluggedNullableForeignKeySourceSerializer(data=data) - self.assertEquals(serializer.data, expected) - serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(data=data) self.assertEquals(serializer.data, expected) - serializer = DefaultSluggedNullableForeignKeySourceSerializer(data=data) - self.assertEquals(serializer.data, default_expected) - def test_slug_foreign_key_create_with_valid_emptystring(self): + def test_foreign_key_create_with_valid_emptystring(self): """ The emptystring should be interpreted as null in the context of relationships. """ - data = {'name': u'source-4', 'target': ''} - expected_data = {'name': u'source-4', 'target': None} - - serializer = SluggedNullableForeignKeySourceSerializer(data=data) - self.assertFalse(serializer.is_valid()) - self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) - - serializer = NullOKSluggedNullableForeignKeySourceSerializer(data=data) + data = {'id': 4, 'name': u'source-4', 'target': ''} + expected_data = {'id': 4, 'name': u'source-4', 'target': None} + serializer = NullableSlugSourceSerializer(data=data) self.assertTrue(serializer.is_valid()) obj = serializer.save() - #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' - self.assertEquals(serializer.data, expected_data) - self.assertEqual(obj.name, u'source-4') - - serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(data=data) - #BUG: is_valid() is False - self.assertTrue(serializer.is_valid()) - obj = serializer.save() - #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' - self.assertEquals(serializer.data, expected_data) - self.assertEqual(obj.name, u'source-4') - - serializer = DefaultSluggedNullableForeignKeySourceSerializer(data=data) - #BUG: is_valid() is False - self.assertTrue(serializer.is_valid()) - obj = serializer.save() - #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' self.assertEquals(serializer.data, expected_data) self.assertEqual(obj.name, u'source-4') # Ensure source 4 is created, and everything else is as expected queryset = NullableForeignKeySource.objects.all() - default_expected = [ - {'name': u'source-1', 'target': 'target-1'}, - {'name': u'source-2', 'target': 'target-1'}, - {'name': u'source-3', 'target': 'N/A'}, - {'name': u'source-4', 'target': 'N/A'} - ] + serializer = NullableSlugSourceSerializer(queryset) expected = [ - {'name': u'source-1', 'target': 'target-1'}, - {'name': u'source-2', 'target': 'target-1'}, - {'name': u'source-3', 'target': None}, - {'name': u'source-4', 'target': None} + {'id': 1, 'name': u'source-1', 'target': 'target-1'}, + {'id': 2, 'name': u'source-2', 'target': 'target-1'}, + {'id': 3, 'name': u'source-3', 'target': None}, + {'id': 4, 'name': u'source-4', 'target': None} ] - #BUG: All serializers fail here - serializer = DefaultSluggedNullableForeignKeySourceSerializer(queryset) - self.assertEquals(serializer.data, default_expected) - serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) - self.assertEquals(serializer.data, expected) - serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(queryset) self.assertEquals(serializer.data, expected) - def test_slug_foreign_key_update_with_valid_null(self): - data = {'name': u'source-1', 'target': None} - default_data = {'name': u'source-1', 'target': 'N/A'} + def test_foreign_key_update_with_valid_null(self): + data = {'id': 1, 'name': u'source-1', 'target': None} instance = NullableForeignKeySource.objects.get(pk=1) - - serializer = SluggedNullableForeignKeySourceSerializer(instance, data=data) - self.assertFalse(serializer.is_valid()) - self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) - - serializer = DefaultSluggedNullableForeignKeySourceSerializer(instance, data=data) - #BUG: is_valid() is False + serializer = NullableSlugSourceSerializer(instance, data=data) self.assertTrue(serializer.is_valid()) - self.assertEquals(serializer.data, default_data) - serializer.save() - - serializer = NullOKSluggedNullableForeignKeySourceSerializer(instance, data=data) - self.assertTrue(serializer.is_valid()) - #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' - self.assertEquals(serializer.data, data) - serializer.save() - - - serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(instance, data=data) - #BUG: is_valid() is False - self.assertTrue(serializer.is_valid()) - #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' self.assertEquals(serializer.data, data) serializer.save() # Ensure source 1 is updated, and everything else is as expected queryset = NullableForeignKeySource.objects.all() + serializer = NullableSlugSourceSerializer(queryset) expected = [ - {'name': u'source-1', 'target': None}, - {'name': u'source-2', 'target': 'target-1'}, - {'name': u'source-3', 'target': None}, + {'id': 1, 'name': u'source-1', 'target': None}, + {'id': 2, 'name': u'source-2', 'target': 'target-1'}, + {'id': 3, 'name': u'source-3', 'target': None} ] - serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) self.assertEquals(serializer.data, expected) - serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(queryset) - self.assertEquals(serializer.data, expected) - - expected = [ - {'name': u'source-1', 'target': 'N/A'}, - {'name': u'source-2', 'target': 'target-1'}, - {'name': u'source-3', 'target': 'N/A'}, - ] - serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) - self.assertEquals(serializer.data, expected) - - def test_slug_foreign_key_update_with_valid_emptystring(self): + def test_foreign_key_update_with_valid_emptystring(self): """ The emptystring should be interpreted as null in the context of relationships. """ - data = {'name': u'source-1', 'target': ''} - default_data = {'name': u'source-1', 'target': 'N/A'} - expected_data = {'name': u'source-1', 'target': None} + data = {'id': 1, 'name': u'source-1', 'target': ''} + expected_data = {'id': 1, 'name': u'source-1', 'target': None} instance = NullableForeignKeySource.objects.get(pk=1) - - serializer = SluggedNullableForeignKeySourceSerializer(instance, data=data) - self.assertFalse(serializer.is_valid()) - self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) - - serializer = DefaultSluggedNullableForeignKeySourceSerializer(instance, data=data) - #BUG: is_valid() is False - self.assertTrue(serializer.is_valid()) - self.assertEquals(serializer.data, default_data) - serializer.save() - - serializer = NullOKSluggedNullableForeignKeySourceSerializer(instance, data=data) - self.assertTrue(serializer.is_valid()) - #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' - self.assertEquals(serializer.data, data) - serializer.save() - - serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(instance, data=data) - #BUG: is_valid() is False + serializer = NullableSlugSourceSerializer(instance, data=data) self.assertTrue(serializer.is_valid()) - #BUG: Throws AttributeError: 'NoneType' object has no attribute 'name' - self.assertEquals(serializer.data, data) + self.assertEquals(serializer.data, expected_data) serializer.save() # Ensure source 1 is updated, and everything else is as expected queryset = NullableForeignKeySource.objects.all() + serializer = NullableSlugSourceSerializer(queryset) expected = [ - {'name': u'source-1', 'target': None}, - {'name': u'source-2', 'target': 'target-1'}, - {'name': u'source-3', 'target': None}, + {'id': 1, 'name': u'source-1', 'target': None}, + {'id': 2, 'name': u'source-2', 'target': 'target-1'}, + {'id': 3, 'name': u'source-3', 'target': None} ] - serializer = NullOKSluggedNullableForeignKeySourceSerializer(queryset) self.assertEquals(serializer.data, expected) - serializer = NotRequiredSluggedNullableForeignKeySourceSerializer(queryset) - self.assertEquals(serializer.data, expected) - -- cgit v1.2.3 From 72c04d570d167209f3f34d6d78492426f206b245 Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Fri, 4 Jan 2013 12:50:01 +0100 Subject: Add nested create for 1to1 reverse relationships --- rest_framework/tests/nesting.py | 85 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 rest_framework/tests/nesting.py (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/nesting.py b/rest_framework/tests/nesting.py new file mode 100644 index 00000000..0c130dce --- /dev/null +++ b/rest_framework/tests/nesting.py @@ -0,0 +1,85 @@ +from django.db import models +from django.test import TestCase +from rest_framework import serializers + + +class OneToOneTarget(models.Model): + name = models.CharField(max_length=100) + + +class OneToOneTargetSource(models.Model): + name = models.CharField(max_length=100) + target = models.OneToOneField(OneToOneTarget, related_name='target_source') + + +class OneToOneSource(models.Model): + name = models.CharField(max_length=100) + target_source = models.OneToOneField(OneToOneTargetSource, related_name='source') + + +class OneToOneSourceSerializer(serializers.ModelSerializer): + class Meta: + model = OneToOneSource + exclude = ('target_source', ) + + +class OneToOneTargetSourceSerializer(serializers.ModelSerializer): + source = OneToOneSourceSerializer() + + class Meta: + model = OneToOneTargetSource + exclude = ('target', ) + +class OneToOneTargetSerializer(serializers.ModelSerializer): + target_source = OneToOneTargetSourceSerializer() + + class Meta: + model = OneToOneTarget + + +class NestedOneToOneTests(TestCase): + def setUp(self): + #import pdb ; pdb.set_trace() + for idx in range(1, 4): + target = OneToOneTarget(name='target-%d' % idx) + target.save() + target_source = OneToOneTargetSource(name='target-source-%d' % idx, target=target) + target_source.save() + source = OneToOneSource(name='source-%d' % idx, target_source=target_source) + source.save() + + def test_foreign_key_retrieve(self): + queryset = OneToOneTarget.objects.all() + serializer = OneToOneTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}}, + {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}}, + {'id': 3, 'name': u'target-3', 'target_source': {'id': 3, 'name': u'target-source-3', 'source': {'id': 3, 'name': u'source-3'}}} + ] + self.assertEquals(serializer.data, expected) + + + def test_foreign_key_create(self): + data = {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4, 'name': u'source-4'}}} + serializer = OneToOneTargetSerializer(data=data) + self.assertTrue(serializer.is_valid()) + obj = serializer.save() + self.assertEquals(serializer.data, data) + self.assertEqual(obj.name, u'target-4') + + # Ensure (source 4, target 4) is added, and everything else is as expected + queryset = OneToOneTarget.objects.all() + serializer = OneToOneTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}}, + {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}}, + {'id': 3, 'name': u'target-3', 'target_source': {'id': 3, 'name': u'target-source-3', 'source': {'id': 3, 'name': u'source-3'}}}, + {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4, 'name': u'source-4'}}} + ] + self.assertEquals(serializer.data, expected) + + def test_foreign_key_create_with_invalid_data(self): + data = {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4}}} + serializer = OneToOneTargetSerializer(data=data) + self.assertFalse(serializer.is_valid()) + self.assertEquals(serializer.errors, {'target_source': [{'source': [{'name': [u'This field is required.']}]}]}) -- cgit v1.2.3 From e66eeb4af8611ba255274f561afb674b25a93c8a Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Fri, 4 Jan 2013 13:13:03 +0100 Subject: Remove commented out debug code --- rest_framework/tests/nesting.py | 1 - 1 file changed, 1 deletion(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/nesting.py b/rest_framework/tests/nesting.py index 0c130dce..d6f9237f 100644 --- a/rest_framework/tests/nesting.py +++ b/rest_framework/tests/nesting.py @@ -39,7 +39,6 @@ class OneToOneTargetSerializer(serializers.ModelSerializer): class NestedOneToOneTests(TestCase): def setUp(self): - #import pdb ; pdb.set_trace() for idx in range(1, 4): target = OneToOneTarget(name='target-%d' % idx) target.save() -- cgit v1.2.3 From 46eea97380ab9723d747b41fab0a305dec19c738 Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Fri, 4 Jan 2013 13:48:01 +0100 Subject: Update one-to-one test names --- rest_framework/tests/nesting.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/nesting.py b/rest_framework/tests/nesting.py index d6f9237f..9cc46c6c 100644 --- a/rest_framework/tests/nesting.py +++ b/rest_framework/tests/nesting.py @@ -47,7 +47,7 @@ class NestedOneToOneTests(TestCase): source = OneToOneSource(name='source-%d' % idx, target_source=target_source) source.save() - def test_foreign_key_retrieve(self): + def test_one_to_one_retrieve(self): queryset = OneToOneTarget.objects.all() serializer = OneToOneTargetSerializer(queryset) expected = [ @@ -58,7 +58,7 @@ class NestedOneToOneTests(TestCase): self.assertEquals(serializer.data, expected) - def test_foreign_key_create(self): + def test_one_to_one_create(self): data = {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4, 'name': u'source-4'}}} serializer = OneToOneTargetSerializer(data=data) self.assertTrue(serializer.is_valid()) @@ -77,7 +77,7 @@ class NestedOneToOneTests(TestCase): ] self.assertEquals(serializer.data, expected) - def test_foreign_key_create_with_invalid_data(self): + def test_one_to_one_create_with_invalid_data(self): data = {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4}}} serializer = OneToOneTargetSerializer(data=data) self.assertFalse(serializer.is_valid()) -- cgit v1.2.3 From 8e5003a1f6e61664e99a376ef8c200f53c4507e1 Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Fri, 4 Jan 2013 13:54:51 +0100 Subject: Update errant test comment --- rest_framework/tests/nesting.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/nesting.py b/rest_framework/tests/nesting.py index 9cc46c6c..dbc8ebc9 100644 --- a/rest_framework/tests/nesting.py +++ b/rest_framework/tests/nesting.py @@ -66,7 +66,8 @@ class NestedOneToOneTests(TestCase): self.assertEquals(serializer.data, data) self.assertEqual(obj.name, u'target-4') - # Ensure (source 4, target 4) is added, and everything else is as expected + # Ensure (target 4, target_source 4, source 4) are added, and + # everything else is as expected. queryset = OneToOneTarget.objects.all() serializer = OneToOneTargetSerializer(queryset) expected = [ -- cgit v1.2.3 From 2d62bcd5aaa6d8f25f22b3e6b89ce26c44d9dfc4 Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Sat, 5 Jan 2013 00:02:48 +0100 Subject: Add one-to-one nested update and delete functionality --- rest_framework/tests/nesting.py | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/nesting.py b/rest_framework/tests/nesting.py index dbc8ebc9..10d5db99 100644 --- a/rest_framework/tests/nesting.py +++ b/rest_framework/tests/nesting.py @@ -9,7 +9,8 @@ class OneToOneTarget(models.Model): class OneToOneTargetSource(models.Model): name = models.CharField(max_length=100) - target = models.OneToOneField(OneToOneTarget, related_name='target_source') + target = models.OneToOneField(OneToOneTarget, null=True, blank=True, + related_name='target_source') class OneToOneSource(models.Model): @@ -83,3 +84,41 @@ class NestedOneToOneTests(TestCase): serializer = OneToOneTargetSerializer(data=data) self.assertFalse(serializer.is_valid()) self.assertEquals(serializer.errors, {'target_source': [{'source': [{'name': [u'This field is required.']}]}]}) + + def test_one_to_one_update(self): + data = {'id': 3, 'name': u'target-3-updated', 'target_source': {'id': 3, 'name': u'target-source-3-updated', 'source': {'id': 3, 'name': u'source-3-updated'}}} + instance = OneToOneTarget.objects.get(pk=3) + serializer = OneToOneTargetSerializer(instance, data=data) + self.assertTrue(serializer.is_valid()) + obj = serializer.save() + self.assertEquals(serializer.data, data) + self.assertEqual(obj.name, u'target-3-updated') + + # Ensure (target 3, target_source 3, source 3) are updated, + # and everything else is as expected. + queryset = OneToOneTarget.objects.all() + serializer = OneToOneTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}}, + {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}}, + {'id': 3, 'name': u'target-3-updated', 'target_source': {'id': 3, 'name': u'target-source-3-updated', 'source': {'id': 3, 'name': u'source-3-updated'}}} + ] + self.assertEquals(serializer.data, expected) + + def test_one_to_one_delete(self): + data = {'id': 3, 'name': u'target-3', 'target_source': {'_delete': True, 'id': 3, 'name': u'target-source-3', 'source': {'id': 3, 'name': u'source-3'}}} + instance = OneToOneTarget.objects.get(pk=3) + serializer = OneToOneTargetSerializer(instance, data=data) + self.assertTrue(serializer.is_valid()) + obj = serializer.save() + + # Ensure (target_source 3, source 3) are deleted, + # and everything else is as expected. + queryset = OneToOneTarget.objects.all() + serializer = OneToOneTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}}, + {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}}, + {'id': 3, 'name': u'target-3', 'target_source': None} + ] + self.assertEquals(serializer.data, expected) -- cgit v1.2.3 From 221f7326c7db7b6fa1a9ba2f0181ac075e3b482c Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Wed, 16 Jan 2013 16:03:59 -0800 Subject: Use None to delete nested object as opposed to _delete flag --- rest_framework/tests/nesting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/nesting.py b/rest_framework/tests/nesting.py index 10d5db99..e4e32667 100644 --- a/rest_framework/tests/nesting.py +++ b/rest_framework/tests/nesting.py @@ -106,7 +106,7 @@ class NestedOneToOneTests(TestCase): self.assertEquals(serializer.data, expected) def test_one_to_one_delete(self): - data = {'id': 3, 'name': u'target-3', 'target_source': {'_delete': True, 'id': 3, 'name': u'target-source-3', 'source': {'id': 3, 'name': u'source-3'}}} + data = {'id': 3, 'name': u'target-3', 'target_source': None} instance = OneToOneTarget.objects.get(pk=3) serializer = OneToOneTargetSerializer(instance, data=data) self.assertTrue(serializer.is_valid()) -- cgit v1.2.3 From 6385ac519defc8e434fd4e24a48a680845341cb7 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 18 Jan 2013 19:47:57 +0000 Subject: Revert accidental merge. --- rest_framework/tests/nesting.py | 124 ---------------------------------------- 1 file changed, 124 deletions(-) delete mode 100644 rest_framework/tests/nesting.py (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/nesting.py b/rest_framework/tests/nesting.py deleted file mode 100644 index e4e32667..00000000 --- a/rest_framework/tests/nesting.py +++ /dev/null @@ -1,124 +0,0 @@ -from django.db import models -from django.test import TestCase -from rest_framework import serializers - - -class OneToOneTarget(models.Model): - name = models.CharField(max_length=100) - - -class OneToOneTargetSource(models.Model): - name = models.CharField(max_length=100) - target = models.OneToOneField(OneToOneTarget, null=True, blank=True, - related_name='target_source') - - -class OneToOneSource(models.Model): - name = models.CharField(max_length=100) - target_source = models.OneToOneField(OneToOneTargetSource, related_name='source') - - -class OneToOneSourceSerializer(serializers.ModelSerializer): - class Meta: - model = OneToOneSource - exclude = ('target_source', ) - - -class OneToOneTargetSourceSerializer(serializers.ModelSerializer): - source = OneToOneSourceSerializer() - - class Meta: - model = OneToOneTargetSource - exclude = ('target', ) - -class OneToOneTargetSerializer(serializers.ModelSerializer): - target_source = OneToOneTargetSourceSerializer() - - class Meta: - model = OneToOneTarget - - -class NestedOneToOneTests(TestCase): - def setUp(self): - for idx in range(1, 4): - target = OneToOneTarget(name='target-%d' % idx) - target.save() - target_source = OneToOneTargetSource(name='target-source-%d' % idx, target=target) - target_source.save() - source = OneToOneSource(name='source-%d' % idx, target_source=target_source) - source.save() - - def test_one_to_one_retrieve(self): - queryset = OneToOneTarget.objects.all() - serializer = OneToOneTargetSerializer(queryset) - expected = [ - {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}}, - {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}}, - {'id': 3, 'name': u'target-3', 'target_source': {'id': 3, 'name': u'target-source-3', 'source': {'id': 3, 'name': u'source-3'}}} - ] - self.assertEquals(serializer.data, expected) - - - def test_one_to_one_create(self): - data = {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4, 'name': u'source-4'}}} - serializer = OneToOneTargetSerializer(data=data) - self.assertTrue(serializer.is_valid()) - obj = serializer.save() - self.assertEquals(serializer.data, data) - self.assertEqual(obj.name, u'target-4') - - # Ensure (target 4, target_source 4, source 4) are added, and - # everything else is as expected. - queryset = OneToOneTarget.objects.all() - serializer = OneToOneTargetSerializer(queryset) - expected = [ - {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}}, - {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}}, - {'id': 3, 'name': u'target-3', 'target_source': {'id': 3, 'name': u'target-source-3', 'source': {'id': 3, 'name': u'source-3'}}}, - {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4, 'name': u'source-4'}}} - ] - self.assertEquals(serializer.data, expected) - - def test_one_to_one_create_with_invalid_data(self): - data = {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4}}} - serializer = OneToOneTargetSerializer(data=data) - self.assertFalse(serializer.is_valid()) - self.assertEquals(serializer.errors, {'target_source': [{'source': [{'name': [u'This field is required.']}]}]}) - - def test_one_to_one_update(self): - data = {'id': 3, 'name': u'target-3-updated', 'target_source': {'id': 3, 'name': u'target-source-3-updated', 'source': {'id': 3, 'name': u'source-3-updated'}}} - instance = OneToOneTarget.objects.get(pk=3) - serializer = OneToOneTargetSerializer(instance, data=data) - self.assertTrue(serializer.is_valid()) - obj = serializer.save() - self.assertEquals(serializer.data, data) - self.assertEqual(obj.name, u'target-3-updated') - - # Ensure (target 3, target_source 3, source 3) are updated, - # and everything else is as expected. - queryset = OneToOneTarget.objects.all() - serializer = OneToOneTargetSerializer(queryset) - expected = [ - {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}}, - {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}}, - {'id': 3, 'name': u'target-3-updated', 'target_source': {'id': 3, 'name': u'target-source-3-updated', 'source': {'id': 3, 'name': u'source-3-updated'}}} - ] - self.assertEquals(serializer.data, expected) - - def test_one_to_one_delete(self): - data = {'id': 3, 'name': u'target-3', 'target_source': None} - instance = OneToOneTarget.objects.get(pk=3) - serializer = OneToOneTargetSerializer(instance, data=data) - self.assertTrue(serializer.is_valid()) - obj = serializer.save() - - # Ensure (target_source 3, source 3) are deleted, - # and everything else is as expected. - queryset = OneToOneTarget.objects.all() - serializer = OneToOneTargetSerializer(queryset) - expected = [ - {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}}, - {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}}, - {'id': 3, 'name': u'target-3', 'target_source': None} - ] - self.assertEquals(serializer.data, expected) -- cgit v1.2.3 From 211bb89eecfadd6831a0c59852926f16ea6bf733 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 18 Jan 2013 21:29:21 +0000 Subject: Raise Validation Errors when relationships receive incorrect types. Fixes #590. --- rest_framework/tests/relations_hyperlink.py | 9 +- rest_framework/tests/relations_pk.py | 7 ++ rest_framework/tests/relations_slug.py | 162 ++++++++++++++++++++++++++-- 3 files changed, 166 insertions(+), 12 deletions(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/relations_hyperlink.py b/rest_framework/tests/relations_hyperlink.py index 7d65eae7..6d137f68 100644 --- a/rest_framework/tests/relations_hyperlink.py +++ b/rest_framework/tests/relations_hyperlink.py @@ -215,6 +215,13 @@ class HyperlinkedForeignKeyTests(TestCase): ] self.assertEquals(serializer.data, expected) + def test_foreign_key_update_incorrect_type(self): + data = {'url': '/foreignkeysource/1/', 'name': u'source-1', 'target': 2} + instance = ForeignKeySource.objects.get(pk=1) + serializer = ForeignKeySourceSerializer(instance, data=data) + self.assertFalse(serializer.is_valid()) + self.assertEquals(serializer.errors, {'target': [u'Incorrect type. Expected url string, received int.']}) + def test_reverse_foreign_key_update(self): data = {'url': '/foreignkeytarget/2/', 'name': u'target-2', 'sources': ['/foreignkeysource/1/', '/foreignkeysource/3/']} instance = ForeignKeyTarget.objects.get(pk=2) @@ -227,7 +234,7 @@ class HyperlinkedForeignKeyTests(TestCase): expected = [ {'url': '/foreignkeytarget/1/', 'name': u'target-1', 'sources': ['/foreignkeysource/1/', '/foreignkeysource/2/', '/foreignkeysource/3/']}, {'url': '/foreignkeytarget/2/', 'name': u'target-2', 'sources': []}, - ] + ] self.assertEquals(new_serializer.data, expected) serializer.save() diff --git a/rest_framework/tests/relations_pk.py b/rest_framework/tests/relations_pk.py index dd1e86b5..3391e60a 100644 --- a/rest_framework/tests/relations_pk.py +++ b/rest_framework/tests/relations_pk.py @@ -194,6 +194,13 @@ class PKForeignKeyTests(TestCase): ] self.assertEquals(serializer.data, expected) + def test_foreign_key_update_incorrect_type(self): + data = {'id': 1, 'name': u'source-1', 'target': 'foo'} + instance = ForeignKeySource.objects.get(pk=1) + serializer = ForeignKeySourceSerializer(instance, data=data) + self.assertFalse(serializer.is_valid()) + self.assertEquals(serializer.errors, {'target': [u'Incorrect type. Expected pk value, received str.']}) + def test_reverse_foreign_key_update(self): data = {'id': 2, 'name': u'target-2', 'sources': [1, 3]} instance = ForeignKeyTarget.objects.get(pk=2) diff --git a/rest_framework/tests/relations_slug.py b/rest_framework/tests/relations_slug.py index 503b61e8..37ccc75e 100644 --- a/rest_framework/tests/relations_slug.py +++ b/rest_framework/tests/relations_slug.py @@ -1,9 +1,23 @@ from django.test import TestCase from rest_framework import serializers -from rest_framework.tests.models import NullableForeignKeySource, ForeignKeyTarget +from rest_framework.tests.models import NullableForeignKeySource, ForeignKeySource, ForeignKeyTarget -class NullableSlugSourceSerializer(serializers.ModelSerializer): +class ForeignKeyTargetSerializer(serializers.ModelSerializer): + sources = serializers.ManySlugRelatedField(slug_field='name') + + class Meta: + model = ForeignKeyTarget + + +class ForeignKeySourceSerializer(serializers.ModelSerializer): + target = serializers.SlugRelatedField(slug_field='name') + + class Meta: + model = ForeignKeySource + + +class NullableForeignKeySourceSerializer(serializers.ModelSerializer): target = serializers.SlugRelatedField(slug_field='name', null=True) class Meta: @@ -11,6 +25,132 @@ class NullableSlugSourceSerializer(serializers.ModelSerializer): # TODO: M2M Tests, FKTests (Non-nulable), One2One +class PKForeignKeyTests(TestCase): + def setUp(self): + target = ForeignKeyTarget(name='target-1') + target.save() + new_target = ForeignKeyTarget(name='target-2') + new_target.save() + for idx in range(1, 4): + source = ForeignKeySource(name='source-%d' % idx, target=target) + source.save() + + def test_foreign_key_retrieve(self): + queryset = ForeignKeySource.objects.all() + serializer = ForeignKeySourceSerializer(queryset) + expected = [ + {'id': 1, 'name': u'source-1', 'target': 'target-1'}, + {'id': 2, 'name': u'source-2', 'target': 'target-1'}, + {'id': 3, 'name': u'source-3', 'target': 'target-1'} + ] + self.assertEquals(serializer.data, expected) + + def test_reverse_foreign_key_retrieve(self): + queryset = ForeignKeyTarget.objects.all() + serializer = ForeignKeyTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, + {'id': 2, 'name': u'target-2', 'sources': []}, + ] + self.assertEquals(serializer.data, expected) + + def test_foreign_key_update(self): + data = {'id': 1, 'name': u'source-1', 'target': 'target-2'} + instance = ForeignKeySource.objects.get(pk=1) + serializer = ForeignKeySourceSerializer(instance, data=data) + self.assertTrue(serializer.is_valid()) + self.assertEquals(serializer.data, data) + serializer.save() + + # Ensure source 1 is updated, and everything else is as expected + queryset = ForeignKeySource.objects.all() + serializer = ForeignKeySourceSerializer(queryset) + expected = [ + {'id': 1, 'name': u'source-1', 'target': 'target-2'}, + {'id': 2, 'name': u'source-2', 'target': 'target-1'}, + {'id': 3, 'name': u'source-3', 'target': 'target-1'} + ] + self.assertEquals(serializer.data, expected) + + def test_foreign_key_update_incorrect_type(self): + data = {'id': 1, 'name': u'source-1', 'target': 123} + instance = ForeignKeySource.objects.get(pk=1) + serializer = ForeignKeySourceSerializer(instance, data=data) + self.assertFalse(serializer.is_valid()) + self.assertEquals(serializer.errors, {'target': [u'Object with name=123 does not exist.']}) + + def test_reverse_foreign_key_update(self): + data = {'id': 2, 'name': u'target-2', 'sources': ['source-1', 'source-3']} + instance = ForeignKeyTarget.objects.get(pk=2) + serializer = ForeignKeyTargetSerializer(instance, data=data) + self.assertTrue(serializer.is_valid()) + # We shouldn't have saved anything to the db yet since save + # hasn't been called. + queryset = ForeignKeyTarget.objects.all() + new_serializer = ForeignKeyTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, + {'id': 2, 'name': u'target-2', 'sources': []}, + ] + self.assertEquals(new_serializer.data, expected) + + serializer.save() + self.assertEquals(serializer.data, data) + + # Ensure target 2 is update, and everything else is as expected + queryset = ForeignKeyTarget.objects.all() + serializer = ForeignKeyTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'sources': ['source-2']}, + {'id': 2, 'name': u'target-2', 'sources': ['source-1', 'source-3']}, + ] + self.assertEquals(serializer.data, expected) + + def test_foreign_key_create(self): + data = {'id': 4, 'name': u'source-4', 'target': 'target-2'} + serializer = ForeignKeySourceSerializer(data=data) + serializer.is_valid() + self.assertTrue(serializer.is_valid()) + obj = serializer.save() + self.assertEquals(serializer.data, data) + self.assertEqual(obj.name, u'source-4') + + # Ensure source 4 is added, and everything else is as expected + queryset = ForeignKeySource.objects.all() + serializer = ForeignKeySourceSerializer(queryset) + expected = [ + {'id': 1, 'name': u'source-1', 'target': 'target-1'}, + {'id': 2, 'name': u'source-2', 'target': 'target-1'}, + {'id': 3, 'name': u'source-3', 'target': 'target-1'}, + {'id': 4, 'name': u'source-4', 'target': 'target-2'}, + ] + self.assertEquals(serializer.data, expected) + + def test_reverse_foreign_key_create(self): + data = {'id': 3, 'name': u'target-3', 'sources': ['source-1', 'source-3']} + serializer = ForeignKeyTargetSerializer(data=data) + self.assertTrue(serializer.is_valid()) + obj = serializer.save() + self.assertEquals(serializer.data, data) + self.assertEqual(obj.name, u'target-3') + + # Ensure target 3 is added, and everything else is as expected + queryset = ForeignKeyTarget.objects.all() + serializer = ForeignKeyTargetSerializer(queryset) + expected = [ + {'id': 1, 'name': u'target-1', 'sources': ['source-2']}, + {'id': 2, 'name': u'target-2', 'sources': []}, + {'id': 3, 'name': u'target-3', 'sources': ['source-1', 'source-3']}, + ] + self.assertEquals(serializer.data, expected) + + def test_foreign_key_update_with_invalid_null(self): + data = {'id': 1, 'name': u'source-1', 'target': None} + instance = ForeignKeySource.objects.get(pk=1) + serializer = ForeignKeySourceSerializer(instance, data=data) + self.assertFalse(serializer.is_valid()) + self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) + class SlugNullableForeignKeyTests(TestCase): def setUp(self): @@ -24,7 +164,7 @@ class SlugNullableForeignKeyTests(TestCase): def test_foreign_key_retrieve_with_null(self): queryset = NullableForeignKeySource.objects.all() - serializer = NullableSlugSourceSerializer(queryset) + serializer = NullableForeignKeySourceSerializer(queryset) expected = [ {'id': 1, 'name': u'source-1', 'target': 'target-1'}, {'id': 2, 'name': u'source-2', 'target': 'target-1'}, @@ -34,7 +174,7 @@ class SlugNullableForeignKeyTests(TestCase): def test_foreign_key_create_with_valid_null(self): data = {'id': 4, 'name': u'source-4', 'target': None} - serializer = NullableSlugSourceSerializer(data=data) + serializer = NullableForeignKeySourceSerializer(data=data) self.assertTrue(serializer.is_valid()) obj = serializer.save() self.assertEquals(serializer.data, data) @@ -42,7 +182,7 @@ class SlugNullableForeignKeyTests(TestCase): # Ensure source 4 is created, and everything else is as expected queryset = NullableForeignKeySource.objects.all() - serializer = NullableSlugSourceSerializer(queryset) + serializer = NullableForeignKeySourceSerializer(queryset) expected = [ {'id': 1, 'name': u'source-1', 'target': 'target-1'}, {'id': 2, 'name': u'source-2', 'target': 'target-1'}, @@ -58,7 +198,7 @@ class SlugNullableForeignKeyTests(TestCase): """ data = {'id': 4, 'name': u'source-4', 'target': ''} expected_data = {'id': 4, 'name': u'source-4', 'target': None} - serializer = NullableSlugSourceSerializer(data=data) + serializer = NullableForeignKeySourceSerializer(data=data) self.assertTrue(serializer.is_valid()) obj = serializer.save() self.assertEquals(serializer.data, expected_data) @@ -66,7 +206,7 @@ class SlugNullableForeignKeyTests(TestCase): # Ensure source 4 is created, and everything else is as expected queryset = NullableForeignKeySource.objects.all() - serializer = NullableSlugSourceSerializer(queryset) + serializer = NullableForeignKeySourceSerializer(queryset) expected = [ {'id': 1, 'name': u'source-1', 'target': 'target-1'}, {'id': 2, 'name': u'source-2', 'target': 'target-1'}, @@ -78,14 +218,14 @@ class SlugNullableForeignKeyTests(TestCase): def test_foreign_key_update_with_valid_null(self): data = {'id': 1, 'name': u'source-1', 'target': None} instance = NullableForeignKeySource.objects.get(pk=1) - serializer = NullableSlugSourceSerializer(instance, data=data) + serializer = NullableForeignKeySourceSerializer(instance, data=data) self.assertTrue(serializer.is_valid()) self.assertEquals(serializer.data, data) serializer.save() # Ensure source 1 is updated, and everything else is as expected queryset = NullableForeignKeySource.objects.all() - serializer = NullableSlugSourceSerializer(queryset) + serializer = NullableForeignKeySourceSerializer(queryset) expected = [ {'id': 1, 'name': u'source-1', 'target': None}, {'id': 2, 'name': u'source-2', 'target': 'target-1'}, @@ -101,14 +241,14 @@ class SlugNullableForeignKeyTests(TestCase): data = {'id': 1, 'name': u'source-1', 'target': ''} expected_data = {'id': 1, 'name': u'source-1', 'target': None} instance = NullableForeignKeySource.objects.get(pk=1) - serializer = NullableSlugSourceSerializer(instance, data=data) + serializer = NullableForeignKeySourceSerializer(instance, data=data) self.assertTrue(serializer.is_valid()) self.assertEquals(serializer.data, expected_data) serializer.save() # Ensure source 1 is updated, and everything else is as expected queryset = NullableForeignKeySource.objects.all() - serializer = NullableSlugSourceSerializer(queryset) + serializer = NullableForeignKeySourceSerializer(queryset) expected = [ {'id': 1, 'name': u'source-1', 'target': None}, {'id': 2, 'name': u'source-2', 'target': 'target-1'}, -- cgit v1.2.3 From a98049c5de9a4ac9e93eac9798e00df9c93caf81 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 19 Jan 2013 15:25:32 +0000 Subject: Drop unneeded test --- rest_framework/tests/decorators.py | 8 -------- 1 file changed, 8 deletions(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/decorators.py b/rest_framework/tests/decorators.py index 5e6bce4e..4012188d 100644 --- a/rest_framework/tests/decorators.py +++ b/rest_framework/tests/decorators.py @@ -28,14 +28,6 @@ class DecoratorTestCase(TestCase): response.request = request return APIView.finalize_response(self, request, response, *args, **kwargs) - def test_wrap_view(self): - - @api_view(['GET']) - def view(request): - return Response({}) - - self.assertTrue(isinstance(view.cls_instance, APIView)) - def test_calling_method(self): @api_view(['GET']) -- cgit v1.2.3 From 37d49429ca34eed86ea142e5dceea4cd9536df2d Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 19 Jan 2013 15:51:14 +0000 Subject: Raise assertion errors if @api_view decorator is applied incorrectly. Fixes #596. --- rest_framework/tests/decorators.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/decorators.py b/rest_framework/tests/decorators.py index 4012188d..82f912e9 100644 --- a/rest_framework/tests/decorators.py +++ b/rest_framework/tests/decorators.py @@ -28,6 +28,28 @@ class DecoratorTestCase(TestCase): response.request = request return APIView.finalize_response(self, request, response, *args, **kwargs) + def test_api_view_incorrect(self): + """ + If @api_view is not applied correct, we should raise an assertion. + """ + + @api_view + def view(request): + return Response() + + request = self.factory.get('/') + self.assertRaises(AssertionError, view, request) + + def test_api_view_incorrect_arguments(self): + """ + If @api_view is missing arguments, we should raise an assertion. + """ + + with self.assertRaises(AssertionError): + @api_view('GET') + def view(request): + return Response() + def test_calling_method(self): @api_view(['GET']) -- cgit v1.2.3 From 71bd2faa792569c9f4c83a06904b927616bfdbf1 Mon Sep 17 00:00:00 2001 From: Kevin Stone Date: Sun, 20 Jan 2013 12:59:27 -0800 Subject: Added test case for format_suffix_patterns to validate changes introduced with issue #593. Signed-off-by: Kevin Stone --- rest_framework/tests/urlpatterns.py | 75 +++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 rest_framework/tests/urlpatterns.py (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/urlpatterns.py b/rest_framework/tests/urlpatterns.py new file mode 100644 index 00000000..e96e7cf3 --- /dev/null +++ b/rest_framework/tests/urlpatterns.py @@ -0,0 +1,75 @@ +from collections import namedtuple + +from django.core import urlresolvers + +from django.test import TestCase +from django.test.client import RequestFactory + +from rest_framework.compat import patterns, url, include +from rest_framework.urlpatterns import format_suffix_patterns + + +# A container class for test paths for the test case +URLTestPath = namedtuple('URLTestPath', ['path', 'args', 'kwargs']) + + +def test_view(request, *args, **kwargs): + pass + + +class FormatSuffixTests(TestCase): + def _test_urlpatterns(self, urlpatterns, test_paths): + factory = RequestFactory() + try: + urlpatterns = format_suffix_patterns(urlpatterns) + except: + self.fail("Failed to apply `format_suffix_patterns` on the supplied urlpatterns") + resolver = urlresolvers.RegexURLResolver(r'^/', urlpatterns) + for test_path in test_paths: + request = factory.get(test_path.path) + try: + callback, callback_args, callback_kwargs = resolver.resolve(request.path_info) + except: + self.fail("Failed to resolve URL: %s" % request.path_info) + self.assertEquals(callback_args, test_path.args) + self.assertEquals(callback_kwargs, test_path.kwargs) + + def test_format_suffix(self): + urlpatterns = patterns( + '', + url(r'^test$', test_view), + ) + test_paths = [ + URLTestPath('/test', (), {}), + URLTestPath('/test.api', (), {'format': 'api'}), + URLTestPath('/test.asdf', (), {'format': 'asdf'}), + ] + self._test_urlpatterns(urlpatterns, test_paths) + + def test_default_args(self): + urlpatterns = patterns( + '', + url(r'^test$', test_view, {'foo': 'bar'}), + ) + test_paths = [ + URLTestPath('/test', (), {'foo': 'bar', }), + URLTestPath('/test.api', (), {'foo': 'bar', 'format': 'api'}), + URLTestPath('/test.asdf', (), {'foo': 'bar', 'format': 'asdf'}), + ] + self._test_urlpatterns(urlpatterns, test_paths) + + def test_included_urls(self): + nested_patterns = patterns( + '', + url(r'^path$', test_view) + ) + urlpatterns = patterns( + '', + url(r'^test/', include(nested_patterns), {'foo': 'bar'}), + ) + test_paths = [ + URLTestPath('/test/path', (), {'foo': 'bar', }), + URLTestPath('/test/path.api', (), {'foo': 'bar', 'format': 'api'}), + URLTestPath('/test/path.asdf', (), {'foo': 'bar', 'format': 'asdf'}), + ] + self._test_urlpatterns(urlpatterns, test_paths) -- cgit v1.2.3 From e7916ae0b1c4af35c55dc21e0d882f3f8ff3121e Mon Sep 17 00:00:00 2001 From: Kevin Stone Date: Mon, 21 Jan 2013 09:37:50 -0800 Subject: Tweaked some method names to be more clear and added a docstring to the test case class. Signed-off-by: Kevin Stone --- rest_framework/tests/urlpatterns.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'rest_framework/tests') diff --git a/rest_framework/tests/urlpatterns.py b/rest_framework/tests/urlpatterns.py index e96e7cf3..43e8ef69 100644 --- a/rest_framework/tests/urlpatterns.py +++ b/rest_framework/tests/urlpatterns.py @@ -13,12 +13,15 @@ from rest_framework.urlpatterns import format_suffix_patterns URLTestPath = namedtuple('URLTestPath', ['path', 'args', 'kwargs']) -def test_view(request, *args, **kwargs): +def dummy_view(request, *args, **kwargs): pass class FormatSuffixTests(TestCase): - def _test_urlpatterns(self, urlpatterns, test_paths): + """ + Tests `format_suffix_patterns` against different URLPatterns to ensure the URLs still resolve properly, including any captured parameters. + """ + def _resolve_urlpatterns(self, urlpatterns, test_paths): factory = RequestFactory() try: urlpatterns = format_suffix_patterns(urlpatterns) @@ -37,31 +40,31 @@ class FormatSuffixTests(TestCase): def test_format_suffix(self): urlpatterns = patterns( '', - url(r'^test$', test_view), + url(r'^test$', dummy_view), ) test_paths = [ URLTestPath('/test', (), {}), URLTestPath('/test.api', (), {'format': 'api'}), URLTestPath('/test.asdf', (), {'format': 'asdf'}), ] - self._test_urlpatterns(urlpatterns, test_paths) + self._resolve_urlpatterns(urlpatterns, test_paths) def test_default_args(self): urlpatterns = patterns( '', - url(r'^test$', test_view, {'foo': 'bar'}), + url(r'^test$', dummy_view, {'foo': 'bar'}), ) test_paths = [ URLTestPath('/test', (), {'foo': 'bar', }), URLTestPath('/test.api', (), {'foo': 'bar', 'format': 'api'}), URLTestPath('/test.asdf', (), {'foo': 'bar', 'format': 'asdf'}), ] - self._test_urlpatterns(urlpatterns, test_paths) + self._resolve_urlpatterns(urlpatterns, test_paths) def test_included_urls(self): nested_patterns = patterns( '', - url(r'^path$', test_view) + url(r'^path$', dummy_view) ) urlpatterns = patterns( '', @@ -72,4 +75,4 @@ class FormatSuffixTests(TestCase): URLTestPath('/test/path.api', (), {'foo': 'bar', 'format': 'api'}), URLTestPath('/test/path.asdf', (), {'foo': 'bar', 'format': 'asdf'}), ] - self._test_urlpatterns(urlpatterns, test_paths) + self._resolve_urlpatterns(urlpatterns, test_paths) -- cgit v1.2.3