diff options
| author | Tom Christie | 2014-11-06 17:32:33 +0000 |
|---|---|---|
| committer | Tom Christie | 2014-11-06 17:32:33 +0000 |
| commit | db1dd8e2406bf54a82d154babd360fba52a0d4bc (patch) | |
| tree | b30e3f59c264b0ac5196fb8f824bd87ddf1f1e56 /tests | |
| parent | 4e001dbb7ac0bc13d6d5fbb4524e905184610aa2 (diff) | |
| download | django-rest-framework-db1dd8e2406bf54a82d154babd360fba52a0d4bc.tar.bz2 | |
Tests & fixes for list serialization
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_serializer_lists.py | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/tests/test_serializer_lists.py b/tests/test_serializer_lists.py new file mode 100644 index 00000000..640067e3 --- /dev/null +++ b/tests/test_serializer_lists.py @@ -0,0 +1,274 @@ +from rest_framework import serializers +from django.utils.datastructures import MultiValueDict + + +class BasicObject: + """ + A mock object for testing serializer save behavior. + """ + def __init__(self, **kwargs): + self._data = kwargs + for key, value in kwargs.items(): + setattr(self, key, value) + + def __eq__(self, other): + if self._data.keys() != other._data.keys(): + return False + for key in self._data.keys(): + if self._data[key] != other._data[key]: + return False + return True + + +class TestListSerializer: + """ + Tests for using a ListSerializer as a top-level serializer. + Note that this is in contrast to using ListSerializer as a field. + """ + + def setup(self): + class IntegerListSerializer(serializers.ListSerializer): + child = serializers.IntegerField() + self.Serializer = IntegerListSerializer + + def test_validate(self): + """ + Validating a list of items should return a list of validated items. + """ + input_data = ["123", "456"] + expected_output = [123, 456] + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.validated_data == expected_output + + def test_validate_html_input(self): + """ + HTML input should be able to mock list structures using [x] style ids. + """ + input_data = MultiValueDict({"[0]": ["123"], "[1]": ["456"]}) + expected_output = [123, 456] + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.validated_data == expected_output + + +class TestListSerializerContainingNestedSerializer: + """ + Tests for using a ListSerializer containing another serializer. + """ + + def setup(self): + class TestSerializer(serializers.Serializer): + integer = serializers.IntegerField() + boolean = serializers.BooleanField() + + def create(self, validated_data): + return BasicObject(**validated_data) + + class ObjectListSerializer(serializers.ListSerializer): + child = TestSerializer() + + self.Serializer = ObjectListSerializer + + def test_validate(self): + """ + Validating a list of dictionaries should return a list of + validated dictionaries. + """ + input_data = [ + {"integer": "123", "boolean": "true"}, + {"integer": "456", "boolean": "false"} + ] + expected_output = [ + {"integer": 123, "boolean": True}, + {"integer": 456, "boolean": False} + ] + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.validated_data == expected_output + + def test_create(self): + """ + Creating from a list of dictionaries should return a list of objects. + """ + input_data = [ + {"integer": "123", "boolean": "true"}, + {"integer": "456", "boolean": "false"} + ] + expected_output = [ + BasicObject(integer=123, boolean=True), + BasicObject(integer=456, boolean=False), + ] + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.save() == expected_output + + def test_serialize(self): + """ + Serialization of a list of objects should return a list of dictionaries. + """ + input_objects = [ + BasicObject(integer=123, boolean=True), + BasicObject(integer=456, boolean=False) + ] + expected_output = [ + {"integer": 123, "boolean": True}, + {"integer": 456, "boolean": False} + ] + serializer = self.Serializer(input_objects) + assert serializer.data == expected_output + + def test_validate_html_input(self): + """ + HTML input should be able to mock list structures using [x] + style prefixes. + """ + input_data = MultiValueDict({ + "[0]integer": ["123"], + "[0]boolean": ["true"], + "[1]integer": ["456"], + "[1]boolean": ["false"] + }) + expected_output = [ + {"integer": 123, "boolean": True}, + {"integer": 456, "boolean": False} + ] + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.validated_data == expected_output + + +class TestNestedListSerializer: + """ + Tests for using a ListSerializer as a field. + """ + + def setup(self): + class TestSerializer(serializers.Serializer): + integers = serializers.ListSerializer(child=serializers.IntegerField()) + booleans = serializers.ListSerializer(child=serializers.BooleanField()) + + def create(self, validated_data): + return BasicObject(**validated_data) + + self.Serializer = TestSerializer + + def test_validate(self): + """ + Validating a list of items should return a list of validated items. + """ + input_data = { + "integers": ["123", "456"], + "booleans": ["true", "false"] + } + expected_output = { + "integers": [123, 456], + "booleans": [True, False] + } + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.validated_data == expected_output + + def test_create(self): + """ + Creation with a list of items return an object with an attribute that + is a list of items. + """ + input_data = { + "integers": ["123", "456"], + "booleans": ["true", "false"] + } + expected_output = BasicObject( + integers=[123, 456], + booleans=[True, False] + ) + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.save() == expected_output + + def test_serialize(self): + """ + Serialization of a list of items should return a list of items. + """ + input_object = BasicObject( + integers=[123, 456], + booleans=[True, False] + ) + expected_output = { + "integers": [123, 456], + "booleans": [True, False] + } + serializer = self.Serializer(input_object) + assert serializer.data == expected_output + + def test_validate_html_input(self): + """ + HTML input should be able to mock list structures using [x] + style prefixes. + """ + input_data = MultiValueDict({ + "integers[0]": ["123"], + "integers[1]": ["456"], + "booleans[0]": ["true"], + "booleans[1]": ["false"] + }) + expected_output = { + "integers": [123, 456], + "booleans": [True, False] + } + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.validated_data == expected_output + + +class TestNestedListOfListsSerializer: + def setup(self): + class TestSerializer(serializers.Serializer): + integers = serializers.ListSerializer( + child=serializers.ListSerializer( + child=serializers.IntegerField() + ) + ) + booleans = serializers.ListSerializer( + child=serializers.ListSerializer( + child=serializers.BooleanField() + ) + ) + + self.Serializer = TestSerializer + + def test_validate(self): + input_data = { + 'integers': [['123', '456'], ['789', '0']], + 'booleans': [['true', 'true'], ['false', 'true']] + } + expected_output = { + "integers": [[123, 456], [789, 0]], + "booleans": [[True, True], [False, True]] + } + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.validated_data == expected_output + + def test_validate_html_input(self): + """ + HTML input should be able to mock lists of lists using [x][y] + style prefixes. + """ + input_data = MultiValueDict({ + "integers[0][0]": ["123"], + "integers[0][1]": ["456"], + "integers[1][0]": ["789"], + "integers[1][1]": ["000"], + "booleans[0][0]": ["true"], + "booleans[0][1]": ["true"], + "booleans[1][0]": ["false"], + "booleans[1][1]": ["true"] + }) + expected_output = { + "integers": [[123, 456], [789, 0]], + "booleans": [[True, True], [False, True]] + } + serializer = self.Serializer(data=input_data) + assert serializer.is_valid() + assert serializer.validated_data == expected_output |
