From a10291e38c42d3df4166a026a31810acc389c49e Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 27 May 2015 20:02:30 +0200 Subject: [PATCH 1/2] forms: if not form class is given to modelform_factory() on User model, user BaseUserForm (fixes #7391) Building of the base classe tuple has been refactoed. Bug introduced in 7141a96e6 --- src/authentic2/forms.py | 24 +++++++++++------------ src/authentic2/tests.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/src/authentic2/forms.py b/src/authentic2/forms.py index f211822..44032c2 100644 --- a/src/authentic2/forms.py +++ b/src/authentic2/forms.py @@ -76,27 +76,21 @@ class BaseUserForm(forms.ModelForm): self.save_m2m = save_m2m return result + def modelform_factory(model, **kwargs): '''Build a modelform for the given model, For the user model also add attribute based fields. ''' - form = kwargs.pop('form', None) or forms.ModelForm + form = kwargs.pop('form', None) fields = kwargs.get('fields', []) required = list(kwargs.pop('required', [])) d = {} - if not form or not hasattr(form, 'Meta'): - meta_d = {'model': model, 'fields': '__all__'} - meta = type('Meta', (), meta_d) - d['Meta'] = meta - bases = (form,) # KV attributes are only supported for the user model currently modelform = None if model == get_user_model(): - if form: - bases = (form,) - else: - bases = (BaseUserForm,) + if not form: + form = BaseUserForm attributes = models.Attribute.objects.all() for attribute in attributes: if fields and attribute.name not in fields: @@ -105,14 +99,20 @@ def modelform_factory(model, **kwargs): for field in app_settings.A2_REQUIRED_FIELDS: if not field in required: required.append(field) + if not form or not hasattr(form, 'Meta'): + meta_d = {'model': model, 'fields': '__all__'} + meta = type('Meta', (), meta_d) + d['Meta'] = meta + if not form: # fallback + form = forms.ModelForm modelform = None if required: def __init__(self, *args, **kwargs): super(modelform, self).__init__(*args, **kwargs) for field in required: if field in self.fields: - self.fields[field].required = True + self.fields[field].required = True d['__init__'] = __init__ - modelform = type(model.__name__ + 'ModelForm', bases, d) + modelform = type(model.__name__ + 'ModelForm', (form,), d) kwargs['form'] = modelform return django_modelform_factory(model, **kwargs) diff --git a/src/authentic2/tests.py b/src/authentic2/tests.py index 2472ecb..35fd574 100644 --- a/src/authentic2/tests.py +++ b/src/authentic2/tests.py @@ -284,7 +284,7 @@ class RegistrationTests(TestCase): 'password2': 'toto'}) self.assertEqual(response.status_code, 200) self.assertFormError(response, 'form', 'password1', ['password must contain at least 6 characters']) - + response = self.client.post(link, { 'password1': 'T0toto', 'password2': 'T0toto'}) new_user = User.objects.get() @@ -453,6 +453,55 @@ class RegistrationTests(TestCase): self.assertNotContains(response, 'John') +class UserProfileTests(TestCase): + def setUp(self): + from django.contrib.auth import get_user_model + User = get_user_model() + user = User.objects.create(username='testbot') + user.set_password('secret') + user.save() + self.client = Client() + + def test_edit_profile_attributes(self): + + models.Attribute.objects.create( + label=u'custom', + name='custom', + required=True, + user_visible=True, + user_editable=True, + kind='string') + models.Attribute.objects.create( + label=u'ID', + name='national_number', + user_editable=True, + user_visible=True, + kind='string') + self.assertTrue(self.client.login(username='testbot', password='secret')) + + # get the edit page in order to check form's prefix + response = self.client.get(reverse('profile_edit')) + form = get_response_form(response) + + kwargs = {'custom': 'random data', + 'national_number': 'xx20153566342yy'} + if form.prefix: + kwargs = dict(('%s-%s' % (form.prefix, k), v) + for k, v in kwargs.iteritems()) + + response = self.client.post(reverse('profile_edit'), kwargs) + + self.assertEqual(response.status_code, 302) + response = self.client.get(reverse('account_management')) + self.assertContains(response, 'random data') + self.assertContains(response, 'xx20153566342yy') + + response = self.client.get(reverse('profile_edit')) + form = get_response_form(response) + self.assertEqual(form['custom'].value(), 'random data') + self.assertEqual(form['national_number'].value(), 'xx20153566342yy') + + class CacheTests(TestCase): urls = 'authentic2.cache_tests_urls' -- 2.1.4