-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
5 changed files
with
210 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
from tests.util import APITestCase | ||
from tracker import models | ||
from tracker.api.serializers import CountryRegionSerializer, CountrySerializer | ||
|
||
|
||
class TestCountry(APITestCase): | ||
serializer_class = CountrySerializer | ||
model_name = 'country' | ||
lookup_key = 'numeric_or_alpha' | ||
id_field = 'alpha2' | ||
|
||
def test_fetch(self): | ||
with self.saveSnapshot(): | ||
country = models.Country.objects.first() | ||
data = self.get_list() | ||
self.assertEqual( | ||
data['count'], | ||
models.Country.objects.count(), | ||
msg='Country count did not match', | ||
) | ||
self.assertV2ModelPresent(country, data['results']) | ||
|
||
with self.subTest('via numeric code'): | ||
data = self.get_detail( | ||
country, kwargs={'numeric_or_alpha': country.numeric} | ||
) | ||
self.assertV2ModelPresent(country, data) | ||
|
||
with self.subTest('via alpha2'): | ||
data = self.get_detail( | ||
country, kwargs={'numeric_or_alpha': country.alpha2} | ||
) | ||
self.assertV2ModelPresent(country, data) | ||
|
||
with self.subTest('via alpha3'): | ||
data = self.get_detail( | ||
country, kwargs={'numeric_or_alpha': country.alpha3} | ||
) | ||
self.assertV2ModelPresent(country, data) | ||
|
||
with self.subTest('error cases'): | ||
self.get_detail(None, kwargs={'numeric_or_alpha': '00'}, status_code=404) | ||
self.get_detail(None, kwargs={'numeric_or_alpha': '000'}, status_code=404) | ||
self.get_detail(None, kwargs={'numeric_or_alpha': 'XX'}, status_code=404) | ||
self.get_detail(None, kwargs={'numeric_or_alpha': 'XXX'}, status_code=404) | ||
self.get_detail( | ||
None, kwargs={'numeric_or_alpha': 'foobar'}, status_code=404 | ||
) | ||
|
||
|
||
class TestCountryRegions(APITestCase): | ||
serializer_class = CountryRegionSerializer | ||
model_name = 'countryregion' | ||
|
||
def test_fetch(self): | ||
region = models.CountryRegion.objects.create( | ||
name='Test Region', country=models.Country.objects.first() | ||
) | ||
|
||
with self.saveSnapshot(): | ||
data = self.get_list(model_name='region') | ||
self.assertEqual( | ||
data['count'], | ||
models.CountryRegion.objects.count(), | ||
msg='Region count did not match', | ||
) | ||
self.assertV2ModelPresent(region, data['results']) | ||
|
||
data = self.get_detail(region, model_name='region') | ||
self.assertV2ModelPresent(region, data) | ||
|
||
with self.subTest('via country'): | ||
data = self.get_noun( | ||
'regions', | ||
region.country, | ||
lookup_key='numeric_or_alpha', | ||
model_name='country', | ||
kwargs={'numeric_or_alpha': region.country.alpha3}, | ||
) | ||
self.assertV2ModelPresent(region, data['results']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import re | ||
|
||
from django.db.models import Q | ||
from rest_framework.decorators import action | ||
from rest_framework.exceptions import NotFound | ||
from rest_framework.generics import get_object_or_404 | ||
|
||
from tracker.api.pagination import TrackerPagination | ||
from tracker.api.serializers import CountryRegionSerializer, CountrySerializer | ||
from tracker.api.views import TrackerReadViewSet | ||
from tracker.models import Country, CountryRegion | ||
|
||
|
||
class CountryViewSet(TrackerReadViewSet): | ||
serializer_class = CountrySerializer | ||
pagination_class = TrackerPagination | ||
queryset = Country.objects.all() | ||
lookup_field = 'numeric_or_alpha' | ||
|
||
def get_object(self): | ||
queryset = self.get_queryset() | ||
pk = self.kwargs['numeric_or_alpha'] | ||
if re.match('[0-9]{3}', pk): | ||
return get_object_or_404(queryset, numeric=pk) | ||
elif re.match('[A-Z]{2,3}', pk): | ||
return get_object_or_404(queryset, Q(alpha2=pk) | Q(alpha3=pk)) | ||
raise NotFound( | ||
detail='Provide either an ISO 3166-1 numeric, alpha2, or alpha3 code', | ||
code='invalid_lookup', | ||
) | ||
|
||
@action(detail=True) | ||
def regions(self, request, *args, **kwargs): | ||
viewset = CountryRegionViewSet(request=request, country=self.get_object()) | ||
viewset.initial(request, *args, **kwargs) | ||
return viewset.list(request, *args, **kwargs) | ||
|
||
|
||
class CountryRegionViewSet(TrackerReadViewSet): | ||
serializer_class = CountryRegionSerializer | ||
pagination_class = TrackerPagination | ||
queryset = CountryRegion.objects.select_related('country') | ||
|
||
def __init__(self, country=None, *args, **kwargs): | ||
self.country = country | ||
super().__init__(*args, **kwargs) | ||
|
||
def filter_queryset(self, queryset): | ||
if self.country: | ||
queryset = queryset.filter(country=self.country) | ||
return queryset |