Files
website-v2/users/tests/test_forms.py

210 lines
6.8 KiB
Python

import io
import pytest
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.files.images import ImageFile
from PIL import Image
from ..forms import (
CustomResetPasswordFromKeyForm,
PreferencesForm,
UserProfileForm,
UserProfilePhotoForm,
)
from ..models import Preferences
from news.models import NEWS_MODELS
def test_custom_reset_password_form(user):
user.claimed = False
user.save()
user.refresh_from_db()
reset_key = "your_reset_key"
form = CustomResetPasswordFromKeyForm(
data={
"key": reset_key,
"email": user.email,
"password1": "new_password",
"password2": "new_password",
},
user=user,
)
assert form.is_valid()
form.save()
user.refresh_from_db()
assert user.claimed is True
def test_preferences_form_fields_no_user():
form = PreferencesForm()
assert sorted(form.fields.keys()) == [
"allow_notification_others_news_posted",
"allow_notification_own_news_approved",
"allow_notification_terms_changed",
]
all_news = sorted(m.news_type for m in NEWS_MODELS)
assert form.initial == {
"allow_notification_others_news_posted": all_news,
"allow_notification_own_news_approved": all_news,
"allow_notification_terms_changed": False,
}
def test_preferences_form_fields_regular_user(user):
instance = user.preferences
form = PreferencesForm(instance=user.preferences)
assert sorted(form.fields.keys()) == [
"allow_notification_others_news_posted",
"allow_notification_own_news_approved",
"allow_notification_terms_changed",
]
assert form.initial == {i: getattr(instance, i) for i in form.fields}
def test_preferences_form_fields_moderator_user(moderator_user):
instance = moderator_user.preferences
form = PreferencesForm(instance=moderator_user.preferences)
assert sorted(form.fields.keys()) == [
"allow_notification_others_news_needs_moderation",
"allow_notification_others_news_posted",
"allow_notification_own_news_approved",
"allow_notification_terms_changed",
]
assert form.initial == {i: getattr(instance, i) for i in form.fields}
@pytest.mark.parametrize("form_field", PreferencesForm.Meta.fields)
@pytest.mark.parametrize("model_class", NEWS_MODELS)
def test_preferences_form_model_modifies_instance_empty_list_no_moderator(
user, form_field, model_class
):
original = Preferences.ALL_NEWS_TYPES
expected = []
if form_field == "allow_notification_terms_changed":
original = False
expected = True
setattr(user.preferences, form_field, original)
form = PreferencesForm(instance=user.preferences, data={form_field: expected})
assert form.is_valid(), form.errors
result = form.save()
# Since the user is not moderator, the value for
# allow_notification_others_news_needs_moderation should not change.
if form_field == "allow_notification_others_news_needs_moderation":
expected = original
assert getattr(result, form_field) == expected
user.refresh_from_db()
assert getattr(user.preferences, form_field) == expected
if form_field == "allow_notification_terms_changed":
# No further testing needed for this field
return
# Now, set a single item.
expected = [model_class.news_type]
form = PreferencesForm(instance=user.preferences, data={form_field: expected})
assert form.is_valid(), form.errors
result = form.save()
# Since the user is not moderator, the value for
# allow_notification_others_news_needs_moderation should not change.
if form_field == "allow_notification_others_news_needs_moderation":
expected = original
assert getattr(result, form_field) == expected
user.refresh_from_db()
assert getattr(user.preferences, form_field) == expected
@pytest.mark.parametrize("form_field", PreferencesForm.Meta.fields)
@pytest.mark.parametrize("model_class", NEWS_MODELS)
def test_preferences_form_model_modifies_instance_empty_list_user_moderator(
moderator_user, form_field, model_class
):
if form_field == "allow_notification_terms_changed":
# this test doesn't make sense for this preference
return
setattr(moderator_user.preferences, form_field, Preferences.ALL_NEWS_TYPES)
expected = []
form = PreferencesForm(
instance=moderator_user.preferences, data={form_field: expected}
)
assert form.is_valid(), form.errors
result = form.save()
assert getattr(result, form_field) == expected
moderator_user.refresh_from_db()
assert getattr(moderator_user.preferences, form_field) == expected
# Now, set a single item.
expected = [model_class.news_type]
form = PreferencesForm(
instance=moderator_user.preferences, data={form_field: expected}
)
assert form.is_valid(), form.errors
result = form.save()
assert getattr(result, form_field) == expected
moderator_user.refresh_from_db()
assert getattr(moderator_user.preferences, form_field) == expected
def test_user_profile_form(user):
form = UserProfileForm(instance=user)
assert set(form.fields.keys()) == {
"display_name",
"email",
"indicate_last_login_method",
"is_commit_author_name_overridden",
}
assert form.initial == {
"display_name": user.display_name,
"email": user.email,
"indicate_last_login_method": user.indicate_last_login_method,
"is_commit_author_name_overridden": user.is_commit_author_name_overridden,
}
form = UserProfileForm(instance=user, data={"email": "test@example.com"})
assert form.is_valid()
form.save()
user.refresh_from_db()
assert user.email == "test@example.com"
def test_user_profile_photo_form_save(user):
"""
Test that the UserProfilePhotoForm deletes the old image and saves the new one.
"""
def create_test_image_file(filename="test.png"):
file = io.BytesIO()
image = Image.new("RGBA", size=(100, 100), color=(155, 0, 0))
image.save(file, "png")
file.name = filename
file.seek(0)
return file
old_image = ImageFile(create_test_image_file(filename="initial_image.png"))
user.profile_image.save("initial_image.png", old_image)
# Make sure the initial image was saved
initial_path = user.profile_image.path
assert initial_path is not None
# Create new image for upload
new_image = SimpleUploadedFile(
"new_image.jpeg",
create_test_image_file(filename="new_image.jpeg").read(),
content_type="image/jpeg",
)
form = UserProfilePhotoForm({"profile_image": new_image}, instance=user)
assert form.is_valid()
updated_user = form.save()
updated_user.refresh_from_db()
assert str(user.pk) in updated_user.profile_image.path