diff --git a/ordr2/views/account.py b/ordr2/views/account.py index 2fd2ea7..4695f7d 100644 --- a/ordr2/views/account.py +++ b/ordr2/views/account.py @@ -366,4 +366,4 @@ def email_change_confirmed(context, request): context.model.owner.email = context.model.payload['new_email'] request.dbsession.delete(context.model) request.session.flash('Email change sucessful', 'success') - return HTTPFound(request.resource_url(request.root, 'login')) + return HTTPFound(request.resource_url(request.root)) diff --git a/tests/_functional/account_settings.py b/tests/_functional/account_settings.py new file mode 100644 index 0000000..90a997b --- /dev/null +++ b/tests/_functional/account_settings.py @@ -0,0 +1,62 @@ +''' tests for the login, logout, registration and account settings''' + +import pytest + +from pyramid_mailer import get_mailer + +from . import testapp, get_token_url +from .. import get_user + + +def test_account_settings(testapp): + ''' changing password and email address ''' + + # log in + testapp.login('user') + + # change the password + response = testapp.get('/account/settings') + form = response.forms[0] + form['new_password'] = 'The Spanish Inquisition' + form['new_password-confirm'] = 'The Spanish Inquisition' + form['password'] = 'Terry' + response = form.submit() + assert response.location == 'http://localhost/' + + response = testapp.get('/account/login') + assert 'Password updated sucessfully' in response + + # login with new password + testapp.logout() + response = testapp.get('/account/login') + form = response.forms[0] + form['username'] = 'TerryGilliam' + form['password'] = 'The Spanish Inquisition' + form.submit() + response = testapp.get('/account/login') + assert '' in response + + # change the email address + response = testapp.get('/account/settings') + form = response.forms[0] + form['email'] = 'amy@example.com' + form['password'] = 'The Spanish Inquisition' + response = form.submit().follow() + assert 'Verify Your Email Address' in response + + # check the email with verification token + mailer = get_mailer(testapp.app.registry) + email = mailer.outbox[-1] + assert email.subject == '[ordr] Please verify your email address' + + # click the email verification token + token_link = get_token_url(email) + response = testapp.get(token_link) + assert response.location == 'http://localhost/' + + response = testapp.get('/account/login') + assert 'Email change sucessful' in response + + # check tat the email address was changed + response = testapp.get('/account/settings') + assert 'value="amy@example.com"' in response diff --git a/tests/views/account.py b/tests/views/account.py index c642e8b..4fed142 100644 --- a/tests/views/account.py +++ b/tests/views/account.py @@ -112,6 +112,10 @@ def test_account_login_fails_wrong_credentials(dbsession, username, password): result = login(None, request) assert result == {} + assert request.session.pop_flash('error') == [ + 'You entered the wrong username or password' + ] + def test_logout(app_config): @@ -167,6 +171,11 @@ def test_registration_form_processing_ok(dbsession): token = user.tokens[0] assert token.subject == TokenSubject.USER_REGISTRATION + # warning about a short password + assert request.session.pop_flash('warning') == [ + 'You should really consider a longer password' + ] + # and a verification email should be sent # this is tested in the functional test since request.registry.notify # doesn't know about event subscribers in the unittest @@ -303,6 +312,9 @@ def test_forgot_password_form_processing_error(dbsession, who): result = forgot_password_form_processing(None, request) assert result == {} + assert request.session.pop_flash('error') == [ + 'Username or email address unknown' + ] def test_forgot_password_email_sent(): @@ -343,6 +355,12 @@ def test_reset_password_form_processing_ok(dbsession): assert account.check_password(REGISTRATION_FORM_DATA['password']) assert dbsession.query(Token).count() == 0 assert dbsession.query(User).count() == 1 + assert request.session.pop_flash('warning') == [ + 'You should really consider a longer password' + ] + assert request.session.pop_flash('success') == [ + 'Your password was changed' + ] def test_reset_password_form_processing_cancel(dbsession): @@ -408,6 +426,7 @@ def test_settings_form_processing_change_name(dbsession): from ordr2.views.account import settings_form_processing user = get_user('user') + dbsession.add(user) context = DummyResource(model=user) request = DummyRequest(dbsession=dbsession, user=user, context=context) changes = { @@ -447,3 +466,94 @@ def test_settings_form_processing_change_password(dbsession): assert isinstance(result, HTTPFound) assert result.location == 'http://example.com//' assert user.check_password('Amy') + assert request.session.pop_flash('warning') == [ + 'You should really consider a longer password' + ] + assert request.session.pop_flash('success') == [ + 'Password updated sucessfully' + ] + + +def test_settings_change_email(dbsession): + ''' settings form processing change name only ''' + from ordr2.views.account import settings_form_processing + from ordr2.models.account import TokenSubject + + user = get_user('user') + dbsession.add(user) + context = DummyResource(model=user) + request = DummyRequest(dbsession=dbsession, user=user, context=context) + changes = { + 'email': 'amy@example.com', + } + set_deform_data(request, SETTINGS_FORM_DATA, changes) + result = settings_form_processing(context, request) + + assert isinstance(result, HTTPFound) + assert result.location == 'http://example.com/verify-new-email' + token = user.tokens[0] + assert token.subject == TokenSubject.CHANGE_EMAIL + assert token.payload == {'new_email': 'amy@example.com'} + assert user.email == 'gilliam@example.com' + + +@pytest.mark.parametrize( + 'key, value', [ + ('first_name', ''), + ('last_name', ''), + ('email', ''), + ('email', 'not an email address'), + ('email', 'jones@example.com'), + ('password', ''), + ('password', 'wrong password'), + ] + ) +def test_settings_form_processing_validation_error(dbsession, key, value): + ''' settings form processing with validation error ''' + from ordr2.views.account import settings_form_processing + + admin = get_user('admin') + user = get_user('user') + dbsession.add(admin) + dbsession.add(user) + context = DummyResource(model=user) + request = DummyRequest(dbsession=dbsession, user=user, context=context) + set_deform_data(request, SETTINGS_FORM_DATA, {key: value}) + result = settings_form_processing(context, request) + + assert isinstance(result['form'], deform.Form) + + +def test_email_confirmation(): + ''' awaiting confirmation of new email address ''' + from ordr2.views.account import email_confirmation + + result = email_confirmation(None, None) + + assert result == {} + + +def test_email_change_confirmed(dbsession): + ''' new email address is verified ''' + from ordr2.views.account import email_change_confirmed + from ordr2.models.account import User, Token, TokenSubject + + + user = get_user('user') + token = user.issue_token( + DummyRequest(dbsession=dbsession), + TokenSubject.CHANGE_EMAIL, + {'new_email': 'amy@example.com'} + ) + dbsession.add(user) + dbsession.flush() + context = DummyResource(model=token) + request = DummyRequest(dbsession=dbsession, context=context) + + result = email_change_confirmed(context, request) + + assert isinstance(result, HTTPFound) + assert result.location == 'http://example.com//' + assert user.email == 'amy@example.com' + assert dbsession.query(Token).count() == 0 + assert request.session.pop_flash('success') == ['Email change sucessful']