diff --git a/tests/test_permission_view.py b/tests/test_permission_view.py index 952958ab..0f3de6d0 100644 --- a/tests/test_permission_view.py +++ b/tests/test_permission_view.py @@ -5,7 +5,7 @@ from binder.json import jsonloads, jsondumps -from .testapp.models import Zoo, ZooEmployee, Country, City, PermanentCity, CityState +from .testapp.models import Zoo, ZooEmployee, Country, City, PermanentCity, CityState, Animal from binder.json import jsondumps from django.contrib.auth.models import User, Group @@ -692,3 +692,53 @@ def test_multiput_with_deletions_no_perm(self): self.assertEquals(403, res.status_code) country.refresh_from_db() + + +class TestColumnScoping(TestCase): + def setUp(self): + super().setUp() + + u = User(username='testuser_for_not_all_fields', is_active=True, is_superuser=False) + u.set_password('test') + u.save() + + self.client = Client() + r = self.client.login(username='testuser_for_not_all_fields', password='test') + self.assertTrue(r) + + self.zoo = Zoo(name='Artis') + self.zoo.save() + + + def test_column_scoping_excludes_columns(self): + res = self.client.get('/zoo/{}/'.format(self.zoo.id)) + self.assertEqual(res.status_code, 200) + + columns = jsonloads(res.content)['data'].keys() + + for field in ['name', 'founding_date', 'django_picture']: + self.zoo._meta.get_field(field) # check if those fields exist, otherwise throw error + self.assertTrue(field not in columns) + + for annotation in ['zoo_name']: + self.assertTrue(annotation not in columns) + + for property in ['animal_count']: + self.assertTrue(property not in columns) + + + def test_column_scoping_includes_columns(self): + res = self.client.get('/zoo/{}/'.format(self.zoo.id)) + self.assertEqual(res.status_code, 200) + + columns = jsonloads(res.content)['data'].keys() + + for field in ['id', 'floor_plan']: + self.zoo._meta.get_field(field) # check if those fields exist, otherwise throw error + self.assertTrue(field in columns) + + for annotation in ['another_zoo_name']: + self.assertTrue(annotation in columns) + + for property in ['another_animal_count']: + self.assertTrue(property in columns) diff --git a/tests/testapp/models/zoo.py b/tests/testapp/models/zoo.py index a6b1737c..e3c616f7 100644 --- a/tests/testapp/models/zoo.py +++ b/tests/testapp/models/zoo.py @@ -35,6 +35,12 @@ class Zoo(BinderModel): binder_picture_custom_extensions = BinderImageField(allowed_extensions=['png'], blank=True, null=True) + + class Annotations: + zoo_name = models.F('name') # simple alias for testing scoping on annotations + another_zoo_name = models.F('name') # simple alias for testing scoping on annotations + + def __str__(self): return 'zoo %d: %s' % (self.pk, self.name) @@ -42,6 +48,10 @@ def __str__(self): def animal_count(self): return self.animals.count() + @property + def another_animal_count(self): + return self.animals.count() + def clean(self): if self.name == 'very_special_forbidden_zoo_name': diff --git a/tests/testapp/views/zoo.py b/tests/testapp/views/zoo.py index 9f14bde2..e843d596 100644 --- a/tests/testapp/views/zoo.py +++ b/tests/testapp/views/zoo.py @@ -28,6 +28,8 @@ def _require_model_perm(self, perm_type, request, pk=None): return ['all'] elif perm_type == 'view' and request.user.username == 'testuser_for_bad_q_filter': return ['bad_q_filter'] + elif perm_type == 'view' and request.user.username == 'testuser_for_not_all_fields': + return ['not_all_fields'] else: model = self.perms_via if hasattr(self, 'perms_via') else self.model perm = '{}.{}_{}'.format(model._meta.app_label, perm_type, model.__name__.lower()) @@ -44,3 +46,12 @@ def _scope_view_bad_q_filter(self, request): return Q(animals__id__in=Animal.objects.all()) # Correct version of filter: # return Zoo.objects.filter(animals__id__in=Animal.objects.all()) + + def _scope_view_not_all_fields(self, request): + # expose only certain columns + columns = { + 'fields': ['id', 'floor_plan'], + 'properties': ['another_animal_count'], + 'annotations': ['another_zoo_name'], + } + return Zoo.objects.all(), columns