from django.contrib.auth.models import Group, Permission, User from django.contrib.contenttypes.models import ContentType from django.core.management import call_command from django.forms.models import modelform_factory from django.test import TestCase, override_settings from perfieldperms.forms import PFPModelForm, PFPPermFilterForm, PFPRoleFilterForm from perfieldperms.models import PFPFilterType, PFPRoleType from perfieldperms.utils import get_non_pfp_perms, get_unpermitted_fields from . import helpers from .models import Pizza @override_settings( AUTHENTICATION_BACKENDS=['perfieldperms.backends.PFPBackend'], PFP_MODELS=[('tests', 'pizza')], PFP_IGNORE_PERMS={} ) class PFPModelFormTest(TestCase): @classmethod def setUpTestData(cls): call_command('pfp-makeperms') def setUp(self): pass def test_configure_form(self): """Test setting user/disable_attributes of form.""" # Set attributes on class PizzaForm = modelform_factory(Pizza, form=PFPModelForm, fields='__all__') PizzaForm.disable_fields = False PizzaForm.disabled_fields = ['name'] form = PizzaForm() self.assertEqual(['name'], form.disabled_fields) self.assertFalse(form.disable_fields) # Defaults get set PizzaForm = modelform_factory(Pizza, form=PFPModelForm, fields='__all__') form = PizzaForm() self.assertFalse(form.disabled_fields) self.assertTrue(form.disable_fields) # Set via args form = PizzaForm(disabled_fields=['name'], disable_fields=False) self.assertEqual(['name'], form.disabled_fields) self.assertFalse(form.disable_fields) # Set via passing in user merged with other config methods user1 = User.objects.create_user(username='user1', password='sekret') pfp = helpers.get_perm('tests', 'pizza', 'add_pizza__name') user1.user_permissions.add(pfp) form = PizzaForm(disabled_fields=['name'], user=user1) self.assertSetEqual({'name', 'price', 'toppings', 'bases'}, set(form.disabled_fields)) self.assertTrue(form.disable_fields) def test_modify_fields(self): """Form fields are modified when appropriate.""" PizzaForm = modelform_factory(Pizza, form=PFPModelForm, fields='__all__') user1 = User.objects.create_user(username='user1', password='supersekret') # Test disable fields pfp1 = helpers.get_perm('tests', 'pizza', 'add_pizza__name') pfp2 = helpers.get_perm('tests', 'pizza', 'add_pizza__price') user1.user_permissions.add(pfp1, pfp2) disabled_fields = get_unpermitted_fields(Pizza, user1) form = PizzaForm(disabled_fields=disabled_fields) self.assertFalse(form.fields['name'].disabled) self.assertFalse(form.fields['price'].disabled) self.assertTrue(form.fields['toppings'].disabled) self.assertTrue(form.fields['bases'].disabled) # Test delete fields form = PizzaForm(disabled_fields=disabled_fields, disable_fields=False) self.assertIn('name', form.fields) self.assertIn('price', form.fields) self.assertNotIn('toppings', form.fields) self.assertNotIn('bases', form.fields) # Form without all fields. PizzaForm = modelform_factory(Pizza, form=PFPModelForm, exclude=['toppings']) form = PizzaForm(disabled_fields=disabled_fields) self.assertNotIn('toppings', form.fields) self.assertFalse(form.fields['name'].disabled) self.assertFalse(form.fields['price'].disabled) self.assertTrue(form.fields['bases'].disabled) class PFPRoleFilterFormTest(TestCase): def test_user_model(self): """Sets current user model if nothing else configured.""" user_ctype = ContentType.objects.get_for_model(User) form = PFPRoleFilterForm() self.assertSetEqual( {user_ctype}, set(form.fields['role_type'].queryset), ) def test_added_roles(self): """Additional configured role types are added to queryset.""" roles = [] ctype = ContentType.objects.get_for_model(User) roles.append(ctype.id) PFPRoleType.objects.create(role_ctype=ctype) ctype = ContentType.objects.get_for_model(Group) roles.append(ctype.id) PFPRoleType.objects.create(role_ctype=ctype) form = PFPRoleFilterForm() self.assertSetEqual( set(ContentType.objects.filter(id__in=roles)), set(form.fields['role_type'].queryset), ) self.assertEqual( len(ContentType.objects.filter(id__in=roles)), len(form.fields['role_type'].queryset), ) class PFPPermFilterFormTest(TestCase): def test_all_models(self): """All models are returned if no restrictions configured.""" form = PFPPermFilterForm() self.assertSetEqual( set(ContentType.objects.all()), set(form.fields['model'].queryset) ) def test_filtered_models(self): """Only filtered models returned if any are configured.""" user_ctype = ContentType.objects.get_for_model(User) PFPFilterType.objects.create(filter_ctype=user_ctype) form = PFPPermFilterForm() self.assertEqual( set(ContentType.objects.filter(id=user_ctype.id)), set(form.fields['model'].queryset) ) def test_initial_set(self): """Correct permission queryset initialised.""" user_ctype = ContentType.objects.get_for_model(User) initial = {'model': user_ctype} form = PFPPermFilterForm(initial=initial) self.assertSetEqual( set(get_non_pfp_perms(user_ctype)), set(form.fields['permissions'].queryset) ) def test_initial_set_show_pfps_false(self): """ PFPs are NOT in the permissions queryset if not in selected filter settings. """ user_ctype = ContentType.objects.get_for_model(User) helpers.create_pfp('auth', 'user', 'add_user', 'email') initial = {'model': user_ctype, 'show_pfps': False} form = PFPPermFilterForm(initial=initial) self.assertSetEqual( set(get_non_pfp_perms(user_ctype)), set(form.fields['permissions'].queryset) ) def test_initial_set_with_pfps(self): """PFPs are in the permissions queryset if selected in the filter.""" user_ctype = ContentType.objects.get_for_model(User) helpers.create_pfp('auth', 'user', 'add_user', 'email') initial = {'model': user_ctype, 'show_pfps': True} form = PFPPermFilterForm(initial=initial) self.assertSetEqual( set(Permission.objects.filter(content_type=user_ctype)), set(form.fields['permissions'].queryset) )