123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- from datetime import date
- import pytest
- from flask import get_flashed_messages, url_for
- from flask_login import current_user, login_user
- from werkzeug.datastructures import MultiDict
- from flaskbb.core.exceptions import PersistenceError, StopValidation
- from flaskbb.core.changesets import ChangeSetHandler
- from flaskbb.core.user.update import (
- EmailUpdate,
- PasswordUpdate,
- SettingsUpdate,
- UserDetailsChange,
- )
- from flaskbb.user.forms import (
- ChangeEmailForm,
- ChangePasswordForm,
- ChangeUserDetailsForm,
- GeneralSettingsForm,
- )
- from flaskbb.user.views import (
- ChangeEmail,
- ChangePassword,
- ChangeUserDetails,
- UserSettings,
- )
- @pytest.fixture(scope="function", autouse=True)
- def setup_request(user, default_settings, post_request_context):
- login_user(user)
- class TestUserSettingsView(object):
- def test_renders_get_okay(self, mock):
- form = self.produce_form({})
- handler = mock.Mock(spec=ChangeSetHandler)
- handler = UserSettings(form=form, settings_update_handler=handler)
- handler.get()
- def test_update_user_settings_successfully(self, user, mock):
- form = self.produce_form(data={"language": "python", "theme": "solarized"})
- handler = mock.Mock(spec=ChangeSetHandler)
- view = UserSettings(form=form, settings_update_handler=handler)
- result = view.post()
- flashed = get_flashed_messages(with_categories=True)
- assert len(flashed) == 1
- assert flashed[0] == ("success", "Settings updated.")
- assert result.status_code == 302
- assert result.headers["Location"] == url_for("user.settings")
- handler.apply_changeset.assert_called_once_with(
- user, SettingsUpdate(language="python", theme="solarized")
- )
- def test_update_user_settings_fail_with_not_valid(self, mock):
- form = self.produce_form(data={"language": "ruby", "theme": "solarized"})
- handler = mock.Mock(spec=ChangeSetHandler)
- view = UserSettings(form=form, settings_update_handler=handler)
- view.post()
- flashed = get_flashed_messages()
- assert not len(flashed)
- handler.apply_changeset.assert_not_called()
- assert form.errors
- def test_update_user_settings_fail_with_stopvalidation_error(self, mock):
- form = self.produce_form(data={"language": "python", "theme": "molokai"})
- handler = mock.Mock(spec=ChangeSetHandler)
- handler.apply_changeset.side_effect = StopValidation(
- [("theme", "Solarized is better")]
- )
- view = UserSettings(form=form, settings_update_handler=handler)
- view.post()
- flashed = get_flashed_messages()
- assert not (len(flashed))
- assert form.errors["theme"] == ["Solarized is better"]
- def test_update_user_settings_fails_with_persistence_error(self, mock):
- form = self.produce_form(data={"language": "python", "theme": "molokai"})
- handler = mock.Mock(spec=ChangeSetHandler)
- handler.apply_changeset.side_effect = PersistenceError("Nope")
- view = UserSettings(form=form, settings_update_handler=handler)
- result = view.post()
- flashed = get_flashed_messages(with_categories=True)
- assert len(flashed) == 1
- assert flashed[0] == ("danger", "Error while updating user settings")
- assert result.status_code == 302
- assert result.headers["Location"] == url_for("user.settings")
- def produce_form(self, data):
- form = GeneralSettingsForm(formdata=MultiDict(data), meta={"csrf": False})
- form.language.choices = [("python", "python"), ("ecmascript", "ecmascript")]
- form.theme.choices = [("molokai", "molokai"), ("solarized", "solarized")]
- return form
- class TestChangePasswordView(object):
- def test_renders_get_okay(self, mock):
- form = self.produce_form()
- handler = mock.Mock(spec=ChangeSetHandler)
- view = ChangePassword(form=form, password_update_handler=handler)
- view.get()
- def test_updates_user_password_okay(self, user, mock):
- form = self.produce_form(
- old_password="password",
- new_password="newpassword",
- confirm_new_password="newpassword",
- )
- handler = mock.Mock(spec=ChangeSetHandler)
- view = ChangePassword(form=form, password_update_handler=handler)
- result = view.post()
- flashed = get_flashed_messages(with_categories=True)
- assert len(flashed) == 1
- assert flashed[0] == ("success", "Password updated.")
- assert result.status_code == 302
- assert result.headers["Location"] == url_for("user.change_password")
- handler.apply_changeset.assert_called_once_with(
- user, PasswordUpdate(old_password="password", new_password="newpassword")
- )
- def test_updates_user_password_fails_with_invalid_inpit(self, mock, user):
- form = self.produce_form(
- old_password="password",
- new_password="newpassword",
- confirm_new_password="whoops",
- )
- handler = mock.Mock(spec=ChangeSetHandler)
- view = ChangePassword(form=form, password_update_handler=handler)
- view.post()
- handler.apply_changeset.assert_not_called()
- assert "new_password" in form.errors
- def test_update_user_password_fails_with_stopvalidation_error(self, mock):
- form = self.produce_form(
- old_password="password",
- new_password="newpassword",
- confirm_new_password="newpassword",
- )
- handler = mock.Mock(spec=ChangeSetHandler)
- handler.apply_changeset.side_effect = StopValidation(
- [("new_password", "That's not a very strong password")]
- )
- view = ChangePassword(form=form, password_update_handler=handler)
- view.post()
- assert form.errors["new_password"] == ["That's not a very strong password"]
- def test_update_user_password_fails_with_persistence_error(self, mock):
- form = self.produce_form(
- old_password="password",
- new_password="newpassword",
- confirm_new_password="newpassword",
- )
- handler = mock.Mock(spec=ChangeSetHandler)
- handler.apply_changeset.side_effect = PersistenceError("no")
- view = ChangePassword(form=form, password_update_handler=handler)
- result = view.post()
- flashed = get_flashed_messages(with_categories=True)
- assert flashed == [("danger", "Error while changing password")]
- assert result.status_code == 302
- assert result.headers["Location"] == url_for("user.change_password")
- def produce_form(self, **kwargs):
- return ChangePasswordForm(
- formdata=MultiDict(kwargs), meta={"csrf": False}, obj=current_user
- )
- class TestChangeEmailView(object):
- def test_renders_get_okay(self, mock):
- form = self.produce_form()
- handler = mock.Mock(spec=ChangeSetHandler)
- view = ChangeEmail(form=form, update_email_handler=handler)
- view.get()
- def test_update_user_email_successfully(self, user, mock):
- form = self.produce_form(
- old_email=user.email,
- new_email="new@email.mail",
- confirm_new_email="new@email.mail",
- )
- handler = mock.Mock(spec=ChangeSetHandler)
- view = ChangeEmail(form=form, update_email_handler=handler)
- result = view.post()
- flashed = get_flashed_messages(with_categories=True)
- assert flashed == [("success", "Email address updated.")]
- handler.apply_changeset.assert_called_once_with(
- user, EmailUpdate(old_email=user.email, new_email="new@email.mail")
- )
- assert result.status_code == 302
- assert result.headers["Location"] == url_for("user.change_email")
- def test_update_user_email_fails_with_invalid_input(self, user, mock):
- form = self.produce_form(old_email=user.email, new_email="new@e.mail")
- handler = mock.Mock(spec=ChangeSetHandler)
- view = ChangeEmail(form=form, update_email_handler=handler)
- view.post()
- assert form.errors
- handler.apply_changeset.assert_not_called()
- def test_update_user_email_fails_with_stopvalidation(self, user, mock):
- form = self.produce_form(
- old_email=user.email, new_email="new@e.mail", confirm_new_email="new@e.mail"
- )
- handler = mock.Mock(spec=ChangeSetHandler)
- handler.apply_changeset.side_effect = StopValidation(
- [("new_email", "bad email")]
- )
- view = ChangeEmail(form=form, update_email_handler=handler)
- view.post()
- assert form.errors == {"new_email": ["bad email"]}
- def test_update_email_fails_with_persistence_error(self, user, mock):
- form = self.produce_form(
- old_email=user.email, new_email="new@e.mail", confirm_new_email="new@e.mail"
- )
- handler = mock.Mock(spec=ChangeSetHandler)
- handler.apply_changeset.side_effect = PersistenceError("nope")
- view = ChangeEmail(form=form, update_email_handler=handler)
- result = view.post()
- flashed = get_flashed_messages(with_categories=True)
- assert flashed == [("danger", "Error while updating email")]
- assert result.status_code == 302
- assert result.headers["Location"] == url_for("user.change_email")
- def produce_form(self, **data):
- return ChangeEmailForm(
- formdata=MultiDict(data), user=current_user, meta={"csrf": False}
- )
- class TestChangeUserDetailsView(object):
- def test_renders_get_okay(self, mock):
- form = self.produce_form()
- handler = mock.Mock(spec=ChangeSetHandler)
- view = ChangeUserDetails(form=form, details_update_handler=handler)
- view.get()
- def test_update_user_details_successfully_updates(self, user, mock):
- form = self.produce_form(
- birthday="25 04 2000",
- gender="awesome",
- location="here",
- website="http://web.site",
- avatar="http://web.site/avatar.png",
- signature="use a cursive font",
- notes="got 'em",
- )
- handler = mock.Mock(spec=ChangeSetHandler)
- view = ChangeUserDetails(form=form, details_update_handler=handler)
- result = view.post()
- flashed = get_flashed_messages(with_categories=True)
- assert flashed == [("success", "User details updated.")]
- assert result.status_code == 302
- assert result.headers["Location"] == url_for("user.change_user_details")
- handler.apply_changeset.assert_called_once_with(
- user,
- UserDetailsChange(
- birthday=date(2000, 4, 25),
- gender="awesome",
- location="here",
- website="http://web.site",
- avatar="http://web.site/avatar.png",
- signature="use a cursive font",
- notes="got 'em",
- ),
- )
- def test_update_user_fails_with_invalid_input(self, mock):
- form = self.produce_form(birthday="99 99 999999")
- handler = mock.Mock(spec=ChangeSetHandler)
- view = ChangeUserDetails(form=form, details_update_handler=handler)
- view.post()
- assert form.errors == {"birthday": ["Not a valid date value"]}
- def test_update_user_fails_with_stopvalidation(self, mock):
- form = self.produce_form(birthday="25 04 2000")
- handler = mock.Mock(spec=ChangeSetHandler)
- handler.apply_changeset.side_effect = StopValidation(
- [("birthday", "I just want you to know that's a great birthday")]
- )
- view = ChangeUserDetails(form=form, details_update_handler=handler)
- view.post()
- assert form.errors == {
- "birthday": ["I just want you to know that's a great birthday"]
- }
- def test_update_user_fails_with_persistence_error(self, mock):
- form = self.produce_form(birthday="25 04 2000")
- handler = mock.Mock(spec=ChangeSetHandler)
- handler.apply_changeset.side_effect = PersistenceError("no")
- view = ChangeUserDetails(form=form, details_update_handler=handler)
- result = view.post()
- flashed = get_flashed_messages(with_categories=True)
- assert flashed == [("danger", "Error while updating user details")]
- assert result.status_code == 302
- assert result.headers["Location"] == url_for("user.change_user_details")
- def produce_form(self, **kwargs):
- return ChangeUserDetailsForm(
- obj=current_user, formdata=MultiDict(kwargs), meta={"csrf": False}
- )
|