Repository: zestedesavoir/zds-site

Issue:
Impossible de modifier son mot de passe
Scenario.
- Je vais sur la page : http://beta.zestedesavoir.com/membres/parametres/compte/
- **le premier problème est que j'ai un message qui m'indique que certains champs sont obligatoire comme si j'avais soumis un formulaire**
- je modifie mon mot de passe
- je n'ai aucun messge d'erreur, mais en vrai **Le mot de passe est resté le meme**



Discussion:
Bug assez étrange, ce formulaire n'a pas été modifié par la ZEP-17 (pour la partie « Ce champ est obligatoire »).


Resolving patch:
diff --git a/zds/member/commons.py b/zds/member/commons.py
--- a/zds/member/commons.py
+++ b/zds/member/commons.py
@@ -51,7 +51,7 @@ def validate_username(self, value):
             elif User.objects.filter(username=value).count() > 0:
                 msg = _(u'Ce nom d\'utilisateur est déjà utilisé')
             if msg is not None:
-                self.throw_error("username", msg)
+                self.throw_error('username', msg)
         return value
 
 
diff --git a/zds/member/forms.py b/zds/member/forms.py
--- a/zds/member/forms.py
+++ b/zds/member/forms.py
@@ -5,7 +5,6 @@
 from django.contrib.auth.models import User, Group
 from django.core.urlresolvers import reverse
 from django.utils.translation import ugettext_lazy as _
-
 from crispy_forms.bootstrap import StrictButton
 from crispy_forms.helper import FormHelper
 from crispy_forms.layout import HTML, Layout, \
@@ -15,6 +14,7 @@
 from zds.member.models import Profile, listing, KarmaNote
 from zds.utils.forms import CommonLayoutModalText
 
+
 # Max password length for the user.
 # Unlike other fields, this is not the length of DB field
 MAX_PASSWORD_LENGTH = 76
@@ -23,7 +23,6 @@
 
 
 class OldTutoForm(forms.Form):
-
     id = forms.ChoiceField(
         label=_(u'Ancien Tutoriel'),
         required=True,
@@ -248,7 +247,7 @@ class ProfileForm(MiniProfileForm):
             ('show_sign', _(u"Afficher les signatures")),
             ('hover_or_click', _(u"Cochez pour dérouler les menus au survol")),
             ('email_for_answer', _(u'Recevez un courriel lorsque vous '
-             u'recevez une réponse à un message privé')),
+                                   u'recevez une réponse à un message privé')),
         ),
         widget=forms.CheckboxSelectMultiple,
     )
@@ -293,8 +292,7 @@ def __init__(self, *args, **kwargs):
 
 # to update email/username
 class ChangeUserForm(forms.Form, ProfileUsernameValidator, ProfileEmailValidator):
-
-    username_new = forms.CharField(
+    username = forms.CharField(
         label=_(u'Nouveau pseudo'),
         max_length=User._meta.get_field('username').max_length,
         min_length=1,
@@ -306,7 +304,7 @@ class ChangeUserForm(forms.Form, ProfileUsernameValidator, ProfileEmailValidator
         )
     )
 
-    email_new = forms.EmailField(
+    email = forms.EmailField(
         label=_(u'Nouvelle adresse courriel'),
         max_length=User._meta.get_field('email').max_length,
         required=False,
@@ -325,8 +323,8 @@ def __init__(self, *args, **kwargs):
         self.helper.form_method = 'post'
 
         self.helper.layout = Layout(
-            Field('username_new'),
-            Field('email_new'),
+            Field('username'),
+            Field('email'),
             ButtonHolder(
                 StrictButton(_(u'Enregistrer'), type='submit'),
             ),
@@ -335,12 +333,12 @@ def __init__(self, *args, **kwargs):
     def clean(self):
         cleaned_data = super(ChangeUserForm, self).clean()
 
-        username_new = cleaned_data.get('username_new')
-        if username_new is not None and not username_new.strip() == '':
+        username_new = cleaned_data.get('username')
+        if username_new is not None:
             self.validate_username(username_new)
 
-        email_new = cleaned_data.get('email_new')
-        if email_new is not None and not email_new.strip() == '':
+        email_new = cleaned_data.get('email')
+        if email_new is not None:
             self.validate_email(email_new)
 
         return cleaned_data
@@ -355,21 +353,19 @@ class ChangePasswordForm(forms.Form):
         label=_(u'Nouveau mot de passe'),
         max_length=MAX_PASSWORD_LENGTH,
         min_length=MIN_PASSWORD_LENGTH,
-        widget=forms.PasswordInput
+        widget=forms.PasswordInput,
     )
 
     password_old = forms.CharField(
         label=_(u'Mot de passe actuel'),
-        max_length=MAX_PASSWORD_LENGTH,
-        min_length=MIN_PASSWORD_LENGTH,
-        widget=forms.PasswordInput
+        widget=forms.PasswordInput,
     )
 
     password_confirm = forms.CharField(
         label=_(u'Confirmer le nouveau mot de passe'),
         max_length=MAX_PASSWORD_LENGTH,
         min_length=MIN_PASSWORD_LENGTH,
-        widget=forms.PasswordInput
+        widget=forms.PasswordInput,
     )
 
     def __init__(self, user, *args, **kwargs):
diff --git a/zds/member/views.py b/zds/member/views.py
--- a/zds/member/views.py
+++ b/zds/member/views.py
@@ -26,7 +26,6 @@
 from forms import LoginForm, MiniProfileForm, ProfileForm, RegisterForm, ChangePasswordForm, ChangeUserForm, \
     ForgotPasswordForm, NewPasswordForm, OldTutoForm, PromoteMemberForm, KarmaForm
 from models import Profile, TokenForgotPassword, TokenRegister, KarmaNote
-
 from zds.article.models import Article
 from zds.gallery.forms import ImageAsAvatarForm
 from zds.gallery.models import UserGallery
@@ -43,7 +42,6 @@
 
 
 class MemberList(ZdSPagingListView):
-
     """Displays the list of registered users."""
 
     context_object_name = 'members'
@@ -55,7 +53,6 @@ class MemberList(ZdSPagingListView):
 
 
 class MemberDetail(DetailView):
-
     """Displays details about a profile."""
 
     context_object_name = 'usr'
@@ -82,7 +79,6 @@ def get_context_data(self, **kwargs):
 
 
 class UpdateMember(UpdateView):
-
     """Updates a profile."""
 
     form_class = ProfileForm
@@ -107,7 +103,7 @@ def get_form(self, form_class):
             'hover_or_click': profile.hover_or_click,
             'email_for_answer': profile.email_for_answer,
             'sign': profile.sign
-            })
+        })
 
         return form
 
@@ -124,7 +120,7 @@ def form_valid(self, form):
         self.update_profile(profile, form)
         self.save_profile(profile)
 
-        return super(UpdateMember, self).form_valid(form)
+        return redirect(self.get_success_url())
 
     def update_profile(self, profile, form):
         cleaned_data_options = form.cleaned_data.get('options')
@@ -157,7 +153,6 @@ def get_error_message(self):
 
 
 class UpdateAvatarMember(UpdateMember):
-
     """Update avatar of a user logged."""
 
     form_class = ImageAsAvatarForm
@@ -178,13 +173,20 @@ def get_success_message(self):
 
 
 class UpdatePasswordMember(UpdateMember):
-
     """User's settings about his password."""
 
     form_class = ChangePasswordForm
 
+    def post(self, request, *args, **kwargs):
+        form = self.form_class(request.user, request.POST)
+
+        if form.is_valid():
+            return self.form_valid(form)
+
+        return render(request, self.template_name, {'form': form})
+
     def get_form(self, form_class):
-        return form_class(self.request.user, self.request.POST)
+        return form_class(self.request.user)
 
     def update_profile(self, profile, form):
         profile.user.set_password(form.data['password_new'])
@@ -197,7 +199,6 @@ def get_success_url(self):
 
 
 class UpdateUsernameEmailMember(UpdateMember):
-
     """User's settings about his username and email."""
 
     form_class = ChangeUserForm
@@ -206,11 +207,11 @@ def get_form(self, form_class):
         return form_class(self.request.POST)
 
     def update_profile(self, profile, form):
-        if form.data['username_new']:
-            profile.user.username = form.data['username_new']
-        elif form.data['email_new']:
-            if form.data['email_new'].strip() != '':
-                profile.user.email = form.data['email_new']
+        if form.data['username']:
+            profile.user.username = form.data['username']
+        if form.data['email']:
+            if form.data['email'].strip() != '':
+                profile.user.email = form.data['email']
 
     def get_success_url(self):
         profile = self.get_object()
@@ -219,7 +220,6 @@ def get_success_url(self):
 
 
 class RegisterView(CreateView, ProfileCreate, TokenGenerator):
-
     """Create a profile."""
 
     form_class = RegisterForm
@@ -328,7 +328,7 @@ def unregister(request):
     # - unpublished tutorials with only the unregistering member as an author
     # - unpublished articles with only the unregistering member as an author
     # - all category associated with those entites (have a look on article.delete_entity_and_tree
-    #   and tutorial.delete_entity_and_tree
+    # and tutorial.delete_entity_and_tree
     # So concerning galleries, we just have for us
     # - "personnal galleries" with only one owner (unregistering user)
     # - "personnal galleries" with more than one owner
@@ -587,8 +587,8 @@ def login_view(request):
     csrf_tk["form"] = form
     csrf_tk["next_page"] = next_page
     return render(request, "member/login.html",
-                           {"form": form,
-                            "csrf_tk": csrf_tk})
+                  {"form": form,
+                   "csrf_tk": csrf_tk})
 
 
 @login_required
@@ -629,7 +629,7 @@ def forgot_password(request):
                  "site_name": settings.ZDS_APP['site']['name'],
                  "site_url": settings.ZDS_APP['site']['url'],
                  "url": settings.ZDS_APP['site']['url'] + token.get_absolute_url()}))
-            message_txt = get_template("email/forgot_password/confirm.txt") .render(Context(
+            message_txt = get_template("email/forgot_password/confirm.txt").render(Context(
                 {"username": usr.username,
                  "site_name": settings.ZDS_APP['site']['name'],
                  "url": settings.ZDS_APP['site']['url'] + token.get_absolute_url()}))
@@ -640,7 +640,7 @@ def forgot_password(request):
             return render(request, "member/forgot_password/success.html")
         else:
             return render(request, "member/forgot_password/index.html",
-                                   {"form": form})
+                          {"form": form})
     form = ForgotPasswordForm()
     return render(request, "member/forgot_password/index.html", {"form": form})
 
@@ -691,7 +691,7 @@ def active_account(request):
 
     if datetime.now() > token.date_end:
         return render(request, "member/register/token_failed.html",
-                               {"token": token})
+                      {"token": token})
     usr.is_active = True
     usr.save()
 
@@ -724,7 +724,7 @@ def active_account(request):
         u'En espérant que tu te plairas ici, '
         u'je te laisse maintenant faire un petit tour.'
         u'\n\n'
-        u'Clem\'')\
+        u'Clem\'') \
         .format(username=usr.username,
                 tutorials_url=settings.ZDS_APP['site']['url'] + reverse("zds.tutorial.views.index"),
                 articles_url=settings.ZDS_APP['site']['url'] + reverse("zds.article.views.index"),
@@ -767,14 +767,12 @@ def generate_token_account(request):
     subject = _(u"{} - Confirmation d'inscription").format(settings.ZDS_APP['site']['abbr'])
     from_email = "{} <{}>".format(settings.ZDS_APP['site']['litteral_name'],
                                   settings.ZDS_APP['site']['email_noreply'])
-    message_html = get_template("email/register/confirm.html"
-                                ) \
+    message_html = get_template("email/register/confirm.html") \
         .render(Context({"username": token.user.username,
                          "site_url": settings.ZDS_APP['site']['url'],
                          "site_name": settings.ZDS_APP['site']['name'],
                          "url": settings.ZDS_APP['site']['url'] + token.get_absolute_url()}))
-    message_txt = get_template("email/register/confirm.txt"
-                               ) \
+    message_txt = get_template("email/register/confirm.txt") \
         .render(Context({"username": token.user.username,
                          "site_name": settings.ZDS_APP['site']['name'],
                          "url": settings.ZDS_APP['site']['url'] + token.get_absolute_url()}))
@@ -961,10 +959,11 @@ def settings_promote(request, user_pk):
 
         return redirect(profile.get_absolute_url())
 
-    form = PromoteMemberForm(initial={'superuser': user.is_superuser,
-                                      'groups': user.groups.all(),
-                                      'activation': user.is_active
-                                      })
+    form = PromoteMemberForm(initial={
+        'superuser': user.is_superuser,
+        'groups': user.groups.all(),
+        'activation': user.is_active
+    })
     return render(request, 'member/settings/promote.html', {
         "usr": user,
         "profile": profile,


Test patch:
diff --git a/zds/member/tests/tests_forms.py b/zds/member/tests/tests_forms.py
--- a/zds/member/tests/tests_forms.py
+++ b/zds/member/tests/tests_forms.py
@@ -266,76 +266,76 @@ def setUp(self):
 
     def test_valid_change_pseudo_user_form(self):
         data = {
-            'username_new': "MyNewPseudo",
-            'email_new': ''
+            'username': "MyNewPseudo",
+            'email': ''
         }
         form = ChangeUserForm(data=data)
         self.assertTrue(form.is_valid())
 
     def test_valid_change_email_user_form(self):
         data = {
-            'username_new': '',
-            'email_new': 'test@gmail.com'
+            'username': '',
+            'email': 'test@gmail.com'
         }
         form = ChangeUserForm(data=data)
         self.assertTrue(form.is_valid())
 
     def test_already_used_username_user_form(self):
         data = {
-            'username_new': self.user1.user.username,
-            'email_new': ''
+            'username': self.user1.user.username,
+            'email': ''
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())
 
     def test_already_used_email_user_form(self):
         data = {
-            'username_new': '',
-            'email_new': self.user1.user.email
+            'username': '',
+            'email': self.user1.user.email
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())
 
     def test_forbidden_email_provider_user_form(self):
         data = {
-            'username_new': '',
-            'email_new': 'test@yopmail.com'
+            'username': '',
+            'email': 'test@yopmail.com'
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())
 
     def test_wrong_email_user_form(self):
         data = {
-            'username_new': '',
-            'email_new': 'wrong@'
+            'username': '',
+            'email': 'wrong@'
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())
 
         data = {
-            'username_new': '',
-            'email_new': '@test.com'
+            'username': '',
+            'email': '@test.com'
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())
 
         data = {
-            'username_new': '',
-            'email_new': 'wrong@test'
+            'username': '',
+            'email': 'wrong@test'
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())
 
         data = {
-            'username_new': '',
-            'email_new': 'wrong@.com'
+            'username': '',
+            'email': 'wrong@.com'
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())
 
         data = {
-            'username_new': '',
-            'email_new': 'wrongtest.com'
+            'username': '',
+            'email': 'wrongtest.com'
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())
@@ -343,8 +343,8 @@ def test_wrong_email_user_form(self):
     def test_pseudo_espaces_register_form(self):
         ProfileFactory()
         data = {
-            'username_new': '  ZeTester  ',
-            'email_new': ''
+            'username': '  ZeTester  ',
+            'email': ''
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())
@@ -352,8 +352,8 @@ def test_pseudo_espaces_register_form(self):
     def test_pseudo_coma_register_form(self):
         ProfileFactory()
         data = {
-            'username_new': 'Ze,Tester',
-            'email_new': ''
+            'username': 'Ze,Tester',
+            'email': ''
         }
         form = ChangeUserForm(data=data)
         self.assertFalse(form.is_valid())