1from __future__ import unicode_literals 2 3from django.test import TestCase, override_settings 4 5from django_countries import countries 6from django_countries.fields import Country 7from django_countries.tests.models import Person, MultiCountry 8from django_countries.tests.custom_countries import FantasyCountries 9from django_countries.serializers import CountryFieldMixin 10 11from rest_framework.test import APIRequestFactory 12from rest_framework import serializers, views 13 14 15def countries_display(countries): 16 """ 17 Convert Countries into a DRF-OPTIONS formatted dict. 18 """ 19 return [{'display_name': v, 'value': k} for (k, v) in countries] 20 21 22class PersonSerializer(CountryFieldMixin, serializers.ModelSerializer): 23 24 class Meta: 25 model = Person 26 fields = ( 27 'name', 'country', 'other_country', 'favourite_country', 28 'fantasy_country') 29 extra_kwargs = { 30 'other_country': {'country_dict': True}, 31 } 32 33 34class MultiCountrySerializer(CountryFieldMixin, serializers.ModelSerializer): 35 36 class Meta: 37 model = MultiCountry 38 fields = ('countries',) 39 40 41class TestDRF(TestCase): 42 43 def test_serialize(self): 44 person = Person(name='Chris Beaven', country='NZ') 45 serializer = PersonSerializer(person) 46 self.assertEqual( 47 serializer.data, 48 { 49 'name': 'Chris Beaven', 50 'country': 'NZ', 51 'other_country': '', 52 'favourite_country': 'NZ', 53 'fantasy_country': '', 54 }) 55 56 def test_serialize_country_dict(self): 57 person = Person(name='Chris Beaven', other_country='AU') 58 serializer = PersonSerializer(person) 59 self.assertEqual( 60 serializer.data, 61 { 62 'name': 'Chris Beaven', 63 'country': '', 64 'other_country': {'code': 'AU', 'name': 'Australia'}, 65 'favourite_country': 'NZ', 66 'fantasy_country': '', 67 }) 68 69 def test_deserialize(self): 70 serializer = PersonSerializer(data={ 71 'name': 'Tester', 72 'country': 'US', 73 'fantasy_country': 'NV', 74 }) 75 self.assertTrue(serializer.is_valid()) 76 self.assertEqual(serializer.validated_data['country'], 'US') 77 78 def test_deserialize_country_dict(self): 79 serializer = PersonSerializer(data={ 80 'name': 'Tester', 81 'country': {'code': 'GB', 'name': 'Anything'}, 82 'fantasy_country': 'NV' 83 }) 84 self.assertTrue(serializer.is_valid()) 85 self.assertEqual(serializer.validated_data['country'], 'GB') 86 87 def test_deserialize_by_name(self): 88 serializer = PersonSerializer(data={ 89 'name': 'Chris', 90 'country': 'New Zealand', 91 'fantasy_country': 'Neverland', 92 }) 93 self.assertTrue(serializer.is_valid()) 94 self.assertEqual(serializer.validated_data['country'], 'NZ') 95 self.assertEqual(serializer.validated_data['fantasy_country'], 'NV') 96 97 def test_deserialize_invalid(self): 98 serializer = PersonSerializer(data={ 99 'name': 'Chris', 100 'country': 'No Such Zealand', 101 'fantasy_country': 'Neverland', 102 }) 103 self.assertFalse(serializer.is_valid()) 104 self.assertTrue( 105 serializer.errors['country'], 106 ['"No Such Zealand" is not a valid choice.']) 107 108 def test_multi_serialize(self): 109 mc = MultiCountry(countries='NZ,AU') 110 serializer = MultiCountrySerializer(mc) 111 self.assertEqual( 112 serializer.data, 113 { 114 'countries': ['NZ', 'AU'] 115 }) 116 117 def test_multi_serialize_empty(self): 118 mc = MultiCountry(countries='') 119 serializer = MultiCountrySerializer(mc) 120 self.assertEqual( 121 serializer.data, 122 { 123 'countries': [] 124 }) 125 126 def test_multi_deserialize(self): 127 serializer = MultiCountrySerializer(data={ 128 'countries': ['NZ', 'AU'] 129 }) 130 self.assertTrue(serializer.is_valid()) 131 self.assertEqual(serializer.validated_data['countries'], ['NZ', 'AU']) 132 133 def test_multi_deserialize_by_name(self): 134 serializer = MultiCountrySerializer(data={ 135 'countries': ['New Zealand', 'Australia'] 136 }) 137 self.assertTrue(serializer.is_valid()) 138 self.assertEqual(serializer.validated_data['countries'], ['NZ', 'AU']) 139 140 def test_multi_deserialize_invalid(self): 141 serializer = MultiCountrySerializer(data={ 142 'countries': ['NZ', 'BAD', 'AU'] 143 }) 144 self.assertFalse(serializer.is_valid()) 145 self.assertEqual( 146 serializer.errors['countries'], 147 ['"BAD" is not a valid choice.']) 148 149 def test_multi_deserialize_save(self): 150 serializer = MultiCountrySerializer(data={ 151 'countries': ['NZ', 'AU'] 152 }) 153 self.assertTrue(serializer.is_valid()) 154 saved = serializer.save() 155 loaded = MultiCountry.objects.get(pk=saved.pk) 156 self.assertEqual(loaded.countries, [Country('NZ'), Country('AU')]) 157 158 159class TestDRFMetadata(TestCase): 160 """ 161 Tests against the DRF OPTIONS API metadata endpoint. 162 """ 163 164 def test_actions(self): 165 166 class ExampleView(views.APIView): 167 """Example view.""" 168 def post(self, request): 169 pass # pragma: nocover 170 171 def get_serializer(self): 172 return PersonSerializer() 173 174 def _choices(response, key): 175 """Helper method for unpacking response JSON.""" 176 return response.data['actions']['POST'][key]['choices'] 177 178 view = ExampleView.as_view() 179 180 factory = APIRequestFactory() 181 request = factory.options('/') 182 response = view(request=request) 183 country_choices = _choices(response, 'country') 184 fantasy_choices_en = _choices(response, 'fantasy_country') 185 self.assertEqual(response.status_code, 200) 186 self.assertEqual(country_choices, countries_display(countries)) 187 self.assertEqual( 188 fantasy_choices_en, countries_display(FantasyCountries())) 189 190 with override_settings(LANGUAGE_CODE='fr'): 191 response = view(request=request) 192 fantasy_choices_fr = _choices(response, 'fantasy_country') 193 self.assertNotEqual(fantasy_choices_en, fantasy_choices_fr) 194