2017-09-26 22:18:39 +02:00
|
|
|
from django import forms
|
|
|
|
from django.contrib.auth import get_user_model
|
|
|
|
from django.contrib.auth.models import Permission
|
|
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
|
from django.test import TestCase
|
|
|
|
|
|
|
|
from utils.forms import KeepUnselectableModelFormMixin
|
|
|
|
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
|
|
|
|
|
|
class KeepUnselectableModelFormMixinTests(TestCase):
|
2017-10-25 14:28:24 +02:00
|
|
|
def _get_form_cls(self):
|
|
|
|
"""
|
|
|
|
We recreate a new form class for each test, because `queryset` may not
|
2017-10-25 15:43:35 +02:00
|
|
|
be reevaluated and may lack the permissions created by `setUp`.
|
2017-10-25 14:28:24 +02:00
|
|
|
"""
|
2019-01-14 22:41:38 +01:00
|
|
|
|
2017-10-25 14:28:24 +02:00
|
|
|
class ExampleForm(KeepUnselectableModelFormMixin, forms.ModelForm):
|
|
|
|
user_permissions = forms.ModelMultipleChoiceField(
|
2019-01-14 22:41:38 +01:00
|
|
|
queryset=Permission.objects.filter(codename__startswith="selec")
|
2017-10-25 14:28:24 +02:00
|
|
|
)
|
2017-09-26 22:18:39 +02:00
|
|
|
|
2019-01-14 22:41:38 +01:00
|
|
|
keep_unselectable_fields = ["user_permissions"]
|
2017-09-26 22:18:39 +02:00
|
|
|
|
2017-10-25 14:28:24 +02:00
|
|
|
class Meta:
|
|
|
|
model = User
|
2019-01-14 22:41:38 +01:00
|
|
|
fields = ("username", "user_permissions")
|
|
|
|
|
2017-10-25 14:28:24 +02:00
|
|
|
return ExampleForm
|
2017-09-26 22:18:39 +02:00
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
ct = ContentType.objects.get_for_model(Permission)
|
|
|
|
|
|
|
|
self.unselec_perm1 = Permission.objects.create(
|
2019-01-14 22:41:38 +01:00
|
|
|
content_type=ct, codename="unselec_perm1", name="Unselectable 1"
|
|
|
|
)
|
2017-09-26 22:18:39 +02:00
|
|
|
self.unselec_perm2 = Permission.objects.create(
|
2019-01-14 22:41:38 +01:00
|
|
|
content_type=ct, codename="unselec_perm2", name="Unselectable 2"
|
|
|
|
)
|
2017-09-26 22:18:39 +02:00
|
|
|
|
|
|
|
# These two perms are the only selectable permissions from
|
|
|
|
# 'permissions' field of ExampleForm.
|
|
|
|
self.selec_perm1 = Permission.objects.create(
|
2019-01-14 22:41:38 +01:00
|
|
|
content_type=ct, codename="selec_perm1", name="Selectable 1"
|
|
|
|
)
|
2017-09-26 22:18:39 +02:00
|
|
|
self.selec_perm2 = Permission.objects.create(
|
2019-01-14 22:41:38 +01:00
|
|
|
content_type=ct, codename="selec_perm2", name="Selectable 2"
|
|
|
|
)
|
2017-09-26 22:18:39 +02:00
|
|
|
|
|
|
|
def test_creation(self):
|
|
|
|
"""
|
|
|
|
The mixin functions properly when instance is being created.
|
|
|
|
"""
|
2017-10-25 14:28:24 +02:00
|
|
|
ExampleForm = self._get_form_cls()
|
2019-01-14 22:41:38 +01:00
|
|
|
data = {"username": "user", "user_permissions": [self.selec_perm1.pk]}
|
2017-10-25 14:28:24 +02:00
|
|
|
form = ExampleForm(data)
|
2017-09-26 22:18:39 +02:00
|
|
|
|
|
|
|
instance = form.save()
|
|
|
|
|
|
|
|
self.assertQuerysetEqual(
|
2019-01-14 22:41:38 +01:00
|
|
|
instance.user_permissions.all(), map(repr, [self.selec_perm1])
|
2017-09-26 22:18:39 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_creation_commit_false(self):
|
|
|
|
"""
|
|
|
|
When instance is being created and 'save' method is called with
|
|
|
|
'commit=False', 'save_m2m' method functions properly.
|
|
|
|
|
|
|
|
https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#the-save-method
|
|
|
|
"""
|
2017-10-25 14:28:24 +02:00
|
|
|
ExampleForm = self._get_form_cls()
|
2019-01-14 22:41:38 +01:00
|
|
|
data = {"username": "user", "user_permissions": [self.selec_perm1.pk]}
|
2017-10-25 14:28:24 +02:00
|
|
|
form = ExampleForm(data)
|
2017-09-26 22:18:39 +02:00
|
|
|
|
|
|
|
instance = form.save(commit=False)
|
|
|
|
|
|
|
|
with self.assertRaises(User.DoesNotExist):
|
2019-01-14 22:41:38 +01:00
|
|
|
User.objects.get(username="user")
|
2017-09-26 22:18:39 +02:00
|
|
|
|
|
|
|
instance.save()
|
|
|
|
form.save_m2m()
|
|
|
|
|
|
|
|
self.assertQuerysetEqual(
|
2019-01-14 22:41:38 +01:00
|
|
|
instance.user_permissions.all(), map(repr, [self.selec_perm1])
|
2017-09-26 22:18:39 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_existing(self):
|
|
|
|
"""
|
|
|
|
Unselectable items of an instance are kept.
|
|
|
|
"""
|
2019-01-14 22:41:38 +01:00
|
|
|
instance = User.objects.create(username="user")
|
2017-09-26 22:18:39 +02:00
|
|
|
# Link instance with an unselectable and a selectable permissions.
|
|
|
|
instance.user_permissions.add(self.unselec_perm1, self.selec_perm2)
|
|
|
|
|
2017-10-25 14:28:24 +02:00
|
|
|
ExampleForm = self._get_form_cls()
|
2019-01-14 22:41:38 +01:00
|
|
|
data = {"username": "user", "user_permissions": [self.selec_perm1.pk]}
|
2017-10-25 14:28:24 +02:00
|
|
|
form = ExampleForm(data, instance=instance)
|
2017-09-26 22:18:39 +02:00
|
|
|
|
|
|
|
instance = form.save()
|
|
|
|
|
|
|
|
self.assertQuerysetEqual(
|
|
|
|
instance.user_permissions.all(),
|
|
|
|
map(repr, [self.selec_perm1, self.unselec_perm1]),
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_existing_commit_false(self):
|
|
|
|
"""
|
|
|
|
When 'save' is called with 'commit=False', unselectable items of an
|
|
|
|
instance are kept by 'save_m2m'.
|
|
|
|
"""
|
2019-01-14 22:41:38 +01:00
|
|
|
instance = User.objects.create(username="user")
|
2017-09-26 22:18:39 +02:00
|
|
|
# Link instance with an unselectable and a selectable permissions.
|
|
|
|
instance.user_permissions.add(self.unselec_perm1, self.selec_perm2)
|
|
|
|
|
2017-10-25 14:28:24 +02:00
|
|
|
ExampleForm = self._get_form_cls()
|
2019-01-14 22:41:38 +01:00
|
|
|
data = {"username": "changed", "user_permissions": [self.selec_perm1.pk]}
|
2017-10-25 14:28:24 +02:00
|
|
|
form = ExampleForm(data, instance=instance)
|
2017-09-26 22:18:39 +02:00
|
|
|
|
|
|
|
instance = form.save(commit=False)
|
|
|
|
|
|
|
|
with self.assertRaises(User.DoesNotExist):
|
2019-01-14 22:41:38 +01:00
|
|
|
User.objects.get(username="changed")
|
2017-09-26 22:18:39 +02:00
|
|
|
|
|
|
|
instance.save()
|
|
|
|
form.save_m2m()
|
|
|
|
|
|
|
|
self.assertQuerysetEqual(
|
|
|
|
instance.user_permissions.all(),
|
|
|
|
map(repr, [self.selec_perm1, self.unselec_perm1]),
|
|
|
|
)
|