from uuid import uuid4 import pytest from requests.exceptions import RequestException from flaskbb.core.exceptions import StopValidation, ValidationError from flaskbb.core.user.update import EmailUpdate, PasswordUpdate, UserDetailsChange from flaskbb.user.models import User from flaskbb.user.services import validators pytestmark = pytest.mark.usefixtures("default_settings") class TestEmailsMustBeDifferent(object): def test_raises_if_emails_match(self, Fred): matching_emails = EmailUpdate("same@email.example", Fred.email) with pytest.raises(ValidationError) as excinfo: validators.EmailsMustBeDifferent().validate(Fred, matching_emails) assert "New email address must be different" in str(excinfo.value) def test_doesnt_raise_if_emails_are_different(self, Fred): different_emails = EmailUpdate("old@email.example", "new@email.example") validators.EmailsMustBeDifferent().validate(Fred, different_emails) class TestPasswordsMustBeDifferent(object): def test_raises_if_passwords_are_the_same(self, Fred): change = PasswordUpdate("fred", "fred") with pytest.raises(ValidationError) as excinfo: validators.PasswordsMustBeDifferent().validate(Fred, change) assert "New password must be different" in str(excinfo.value) def test_doesnt_raise_if_passwords_dont_match(self, Fred): change = PasswordUpdate("fred", "actuallycompletelydifferent") validators.PasswordsMustBeDifferent().validate(Fred, change) class TestCantShareEmailValidator(object): def test_raises_if_email_is_already_registered(self, Fred, user): change = EmailUpdate("old@email.example", user.email) with pytest.raises(ValidationError) as excinfo: validators.CantShareEmailValidator(User).validate(Fred, change) assert "is already registered" in str(excinfo.value) def test_doesnt_raise_if_email_isnt_registered(self, Fred): change = EmailUpdate("old@email.example", "new@email.example") validators.CantShareEmailValidator(User).validate(Fred, change) class TestOldEmailMustMatchValidator(object): def test_raises_if_old_email_doesnt_match(self, Fred): change = EmailUpdate("not@the.same.one.bit", "probably@real.email.provider") with pytest.raises(StopValidation) as excinfo: validators.OldEmailMustMatch().validate(Fred, change) assert [("old_email", "Old email does not match")] == excinfo.value.reasons def test_doesnt_raise_if_old_email_matches(self, Fred): change = EmailUpdate(Fred.email, "probably@real.email.provider") validators.OldEmailMustMatch().validate(Fred, change) class TestOldPasswordMustMatchValidator(object): def test_raises_if_old_password_doesnt_match(self, Fred): change = PasswordUpdate(str(uuid4()), str(uuid4())) with pytest.raises(StopValidation) as excinfo: validators.OldPasswordMustMatch().validate(Fred, change) assert [("old_password", "Old password is wrong")] == excinfo.value.reasons def test_doesnt_raise_if_old_passwords_match(self, Fred): change = PasswordUpdate("fred", str(uuid4())) validators.OldPasswordMustMatch().validate(Fred, change) class TestValidateAvatarURL(object): def test_passes_if_avatar_url_is_none(self, Fred): change = UserDetailsChange() validators.ValidateAvatarURL().validate(Fred, change) def test_raises_if_check_raises_requests_error(self, Fred, responses): url = "http://notfake.example/image.png" change = UserDetailsChange(avatar=url) responses.add(responses.GET, url=url, body=RequestException()) with pytest.raises(ValidationError) as excinfo: validators.ValidateAvatarURL().validate(Fred, change) assert excinfo.value.attribute == "avatar" assert excinfo.value.reason == "Could not retrieve avatar" def test_raises_if_image_doesnt_pass_checks(self, image_too_tall, Fred, responses): change = UserDetailsChange(avatar=image_too_tall.url) responses.add(image_too_tall) with pytest.raises(ValidationError) as excinfo: validators.ValidateAvatarURL().validate(Fred, change) assert "too high" in excinfo.value.reason def tests_passes_if_image_is_just_right(self, image_just_right, Fred, responses): change = UserDetailsChange(avatar=image_just_right.url) responses.add(image_just_right) validators.ValidateAvatarURL().validate(Fred, change)