mirror of
https://github.com/boostorg/website-v2.git
synced 2026-01-19 04:42:17 +00:00
Add a single-page profile update form
- Add password reset form to single-page profile - Add profile photo form to single-page profile - Add button to import photo from GitHub - Add preferences form to single-page profile - Add tests for unauthenticated/authenticated users - Add tests that forms are present - Add tests that the forms submit, without changing other data
This commit is contained in:
committed by
Greg Newman
parent
539ad3bd48
commit
ea2b45b49e
@@ -1,6 +1,12 @@
|
||||
import pytest
|
||||
import tempfile
|
||||
|
||||
from ..forms import PreferencesForm
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
|
||||
from allauth.account.forms import ChangePasswordForm
|
||||
from PIL import Image
|
||||
|
||||
from ..forms import PreferencesForm, UserProfilePhotoForm
|
||||
from ..models import Preferences
|
||||
|
||||
|
||||
@@ -57,3 +63,122 @@ def test_preferences_post_clears_options(
|
||||
assert_messages(
|
||||
response, [("success", "Your preferences were successfully updated.")]
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_new_current_user_profile_not_authenticated(tp, user):
|
||||
tp.assertLoginRequired("profile-account-new")
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_new_current_user_profile_view_get(user, tp):
|
||||
with tp.login(user):
|
||||
response = tp.assertGoodView(tp.reverse("profile-account-new"), verbose=True)
|
||||
assert isinstance(response.context["change_password_form"], ChangePasswordForm)
|
||||
assert isinstance(response.context["profile_photo_form"], UserProfilePhotoForm)
|
||||
assert isinstance(response.context["profile_preferences_form"], PreferencesForm)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_new_current_user_profile_view_post_valid_password(user, tp):
|
||||
with tp.login(user):
|
||||
response = tp.post(
|
||||
tp.reverse("profile-account-new"),
|
||||
data={
|
||||
"email": user.email,
|
||||
"oldpassword": "password",
|
||||
"password1": "new_password",
|
||||
"password2": "new_password",
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
user.refresh_from_db()
|
||||
user.check_password("new_password")
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_new_current_user_profile_view_post_invalid_password(user, tp):
|
||||
old_password = "password"
|
||||
with tp.login(user):
|
||||
response = tp.post(
|
||||
tp.reverse("profile-account-new"),
|
||||
data={
|
||||
"email": user.email,
|
||||
"oldpassword": "not the right password",
|
||||
"password1": "new_password",
|
||||
"password2": "new_password",
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
user.refresh_from_db()
|
||||
user.check_password(old_password)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_new_current_user_profile_view_post_valid_photo(user, tp):
|
||||
"""Test that a user can upload a new profile picture."""
|
||||
# Create a temporary image file for testing
|
||||
with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as temp_image:
|
||||
image = Image.new("RGB", (200, 200))
|
||||
image.save(temp_image, "jpeg")
|
||||
temp_image.seek(0)
|
||||
|
||||
# Wrap temp_image in Django's File object
|
||||
uploaded_file = SimpleUploadedFile(
|
||||
name="test_image.jpg", content=temp_image.read(), content_type="image/jpeg"
|
||||
)
|
||||
|
||||
with tp.login(user):
|
||||
response = tp.post(
|
||||
tp.reverse("profile-account-new"),
|
||||
data={
|
||||
"image": uploaded_file,
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
user.refresh_from_db()
|
||||
assert user.image
|
||||
# confirm that password was not changed, as these are on the same screen
|
||||
assert user.check_password("password")
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize("user_type", ["user", "moderator_user"])
|
||||
@pytest.mark.parametrize("form_field", PreferencesForm.Meta.fields)
|
||||
def test_new_current_user_profile_view_post_valid_preferences(
|
||||
user_type, form_field, tp, request, assert_messages
|
||||
):
|
||||
user = request.getfixturevalue(user_type)
|
||||
original_preferences = {
|
||||
field: getattr(user.preferences, field) for field in PreferencesForm.Meta.fields
|
||||
}
|
||||
new_preferences = {
|
||||
field: [] for field in PreferencesForm.Meta.fields
|
||||
} # Clear all options
|
||||
|
||||
with tp.login(user):
|
||||
response = tp.post(
|
||||
tp.reverse("profile-account-new"),
|
||||
data={**new_preferences, "update_preferences": "Update Preeferences"},
|
||||
follow=True,
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
user.refresh_from_db()
|
||||
for field in PreferencesForm.Meta.fields:
|
||||
if (
|
||||
field == "allow_notification_others_news_needs_moderation"
|
||||
and user_type != "moderator_user"
|
||||
):
|
||||
assert (
|
||||
getattr(user.preferences, field) == original_preferences[field]
|
||||
) # Field should be unchanged for non-moderators
|
||||
else:
|
||||
assert getattr(user.preferences, field) == [] # Field should be cleared
|
||||
|
||||
assert_messages(
|
||||
response, [("success", "Your preferences were successfully updated.")]
|
||||
)
|
||||
|
||||
@@ -5,6 +5,9 @@ from django.http import HttpResponseRedirect
|
||||
from django.urls import reverse_lazy
|
||||
from django.views.generic import DetailView, UpdateView
|
||||
from django.views.generic.edit import FormView
|
||||
from django.views.generic.base import TemplateView
|
||||
|
||||
from allauth.account.forms import ChangePasswordForm
|
||||
|
||||
from rest_framework import generics
|
||||
from rest_framework import viewsets
|
||||
@@ -123,3 +126,79 @@ class ProfilePreferencesView(LoginRequiredMixin, SuccessMessageMixin, UpdateView
|
||||
|
||||
def get_object(self):
|
||||
return self.request.user.preferences
|
||||
|
||||
|
||||
class NewCurrentUserProfileView(LoginRequiredMixin, SuccessMessageMixin, TemplateView):
|
||||
template_name = "users/profile_new.html"
|
||||
success_message = "Your profile was successfully updated."
|
||||
success_url = reverse_lazy("profile-account-new")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["change_password_form"] = ChangePasswordForm(user=self.request.user)
|
||||
context["profile_photo_form"] = UserProfilePhotoForm(instance=self.request.user)
|
||||
context["profile_preferences_form"] = PreferencesForm(
|
||||
instance=self.request.user.preferences
|
||||
)
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
Process each form submission individually if present
|
||||
"""
|
||||
if "change_password" in request.POST:
|
||||
change_password_form = ChangePasswordForm(
|
||||
data=request.POST, user=self.request.user
|
||||
)
|
||||
self.change_password(change_password_form, request)
|
||||
|
||||
if "update_photo" in request.POST:
|
||||
profile_photo_form = UserProfilePhotoForm(
|
||||
self.request.POST, self.request.FILES, instance=self.request.user
|
||||
)
|
||||
self.update_photo(profile_photo_form, request)
|
||||
|
||||
if "update_github_photo" in request.POST:
|
||||
self.update_github_photo(request)
|
||||
|
||||
if "update_preferences" in request.POST:
|
||||
profile_preferences_form = PreferencesForm(
|
||||
self.request.POST, instance=request.user.preferences
|
||||
)
|
||||
self.update_preferences(profile_preferences_form, request)
|
||||
|
||||
return HttpResponseRedirect(self.success_url)
|
||||
|
||||
def change_password(self, form, request):
|
||||
"""Change the password of the user."""
|
||||
if form.is_valid():
|
||||
self.object = request.user
|
||||
self.object.set_password(form.cleaned_data["password1"])
|
||||
self.object.save()
|
||||
messages.success(request, "Your password was successfully updated.")
|
||||
else:
|
||||
for error in form.errors.values():
|
||||
messages.error(request, f"{error}")
|
||||
|
||||
def update_photo(self, form, request):
|
||||
"""Update the profile photo of the user."""
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, "Your profile photo was successfully updated.")
|
||||
else:
|
||||
for error in form.errors.values():
|
||||
messages.error(request, f"{error}")
|
||||
|
||||
def update_github_photo(self, request):
|
||||
"""Update the GitHub photo of the user."""
|
||||
tasks.update_user_github_photo(str(request.user.pk))
|
||||
messages.success(request, "Your GitHub photo has been retrieved.")
|
||||
|
||||
def update_preferences(self, form, request):
|
||||
"""Update the preferences of the user."""
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, "Your preferences were successfully updated.")
|
||||
else:
|
||||
for error in form.errors.values():
|
||||
messages.error(request, f"{error}")
|
||||
|
||||
Reference in New Issue
Block a user