From 984eef92e2fb750ba120f782e28e7e1e6ae29a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20I=C3=9Fbr=C3=BCcker?= Date: Sat, 16 Oct 2021 05:42:04 +0200 Subject: [PATCH] Add password change view (#168) --- .../registration/password_change_done.html | 21 +++++++ .../registration/password_change_form.html | 55 +++++++++++++++++++ bookmarks/templates/settings/general.html | 3 + bookmarks/tests/test_password_change_view.py | 55 +++++++++++++++++++ siteroot/urls.py | 3 + 5 files changed, 137 insertions(+) create mode 100644 bookmarks/templates/registration/password_change_done.html create mode 100644 bookmarks/templates/registration/password_change_form.html create mode 100644 bookmarks/tests/test_password_change_view.py diff --git a/bookmarks/templates/registration/password_change_done.html b/bookmarks/templates/registration/password_change_done.html new file mode 100644 index 0000000..a49160b --- /dev/null +++ b/bookmarks/templates/registration/password_change_done.html @@ -0,0 +1,21 @@ +{% extends 'bookmarks/layout.html' %} +{% load widget_tweaks %} + +{% block title %}Password changed{% endblock %} + +{% block content %} + +
+
+
+
+

Password Changed

+
+

+ Your password was changed successfully. +

+
+
+
+ +{% endblock %} diff --git a/bookmarks/templates/registration/password_change_form.html b/bookmarks/templates/registration/password_change_form.html new file mode 100644 index 0000000..fe4b52f --- /dev/null +++ b/bookmarks/templates/registration/password_change_form.html @@ -0,0 +1,55 @@ +{% extends 'bookmarks/layout.html' %} +{% load widget_tweaks %} + +{% block title %}Change Password{% endblock %} + +{% block content %} + +
+
+
+
+

Change Password

+
+
+ {% csrf_token %} +
+ + {{ form.old_password|add_class:'form-input'|attr:"placeholder: " }} + {% if form.old_password.errors %} +
+ {{ form.old_password.errors }} +
+ {% endif %} +
+
+ + {{ form.new_password1|add_class:'form-input'|attr:"placeholder: " }} + {% if form.new_password1.errors %} +
+ {{ form.new_password1.errors }} +
+ {% endif %} +
+
+ + {{ form.new_password2|add_class:'form-input'|attr:"placeholder: " }} + {% if form.new_password2.errors %} +
+ {{ form.new_password2.errors }} +
+ {% endif %} +
+ +
+
+
+ +
+
+
+
+
+
+ +{% endblock %} diff --git a/bookmarks/templates/settings/general.html b/bookmarks/templates/settings/general.html index 400eef4..32cde04 100644 --- a/bookmarks/templates/settings/general.html +++ b/bookmarks/templates/settings/general.html @@ -9,6 +9,9 @@ {# Profile section #}

Profile

+

+ Change password +

{% csrf_token %}
diff --git a/bookmarks/tests/test_password_change_view.py b/bookmarks/tests/test_password_change_view.py new file mode 100644 index 0000000..390e44c --- /dev/null +++ b/bookmarks/tests/test_password_change_view.py @@ -0,0 +1,55 @@ +from django.contrib.auth.models import User +from django.test import TestCase +from django.urls import reverse + +from bookmarks.tests.helpers import BookmarkFactoryMixin + + +class PasswordChangeViewTestCase(TestCase, BookmarkFactoryMixin): + def setUp(self) -> None: + self.user = User.objects.create_user('testuser', 'test@example.com', 'initial_password') + self.client.force_login(self.user) + + def test_change_password(self): + form_data = { + 'old_password': 'initial_password', + 'new_password1': 'new_password', + 'new_password2': 'new_password', + } + + response = self.client.post(reverse('change_password'), form_data) + + self.assertRedirects(response, reverse('password_change_done')) + + def test_change_password_done(self): + form_data = { + 'old_password': 'initial_password', + 'new_password1': 'new_password', + 'new_password2': 'new_password', + } + + response = self.client.post(reverse('change_password'), form_data, follow=True) + + self.assertContains(response, 'Your password was changed successfully') + + def test_should_return_error_for_invalid_old_password(self): + form_data = { + 'old_password': 'wrong_password', + 'new_password1': 'new_password', + 'new_password2': 'new_password', + } + + response = self.client.post(reverse('change_password'), form_data) + + self.assertIn('old_password', response.context_data['form'].errors) + + def test_should_return_error_for_mismatching_new_password(self): + form_data = { + 'old_password': 'initial_password', + 'new_password1': 'new_password', + 'new_password2': 'wrong_password', + } + + response = self.client.post(reverse('change_password'), form_data) + + self.assertIn('new_password2', response.context_data['form'].errors) diff --git a/siteroot/urls.py b/siteroot/urls.py index 9c7d4bb..2e1a8dd 100644 --- a/siteroot/urls.py +++ b/siteroot/urls.py @@ -25,11 +25,14 @@ urlpatterns = [ extra_context=dict(allow_registration=ALLOW_REGISTRATION)), name='login'), path('logout/', auth_views.LogoutView.as_view(), name='logout'), + path('change-password/', auth_views.PasswordChangeView.as_view(), name='change_password'), + path('password-change-done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'), path('', include('bookmarks.urls')), ] if DEBUG: import debug_toolbar + urlpatterns.append(path('__debug__/', include(debug_toolbar.urls))) if ALLOW_REGISTRATION: