|
|
|
''' Tests for ordr2.views.account '''
|
|
|
|
|
|
|
|
import deform
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
from pyramid.httpexceptions import HTTPFound
|
|
|
|
from pyramid.testing import DummyRequest, DummyResource
|
|
|
|
from pyramid_mailer import get_mailer
|
|
|
|
from webob.multidict import MultiDict
|
|
|
|
|
|
|
|
from .. import app_config, dbsession, get_user, create_users, set_deform_data
|
|
|
|
|
|
|
|
|
|
|
|
REGISTRATION_FORM_DATA = MultiDict([
|
|
|
|
('username', 'AmyMcDonald'),
|
|
|
|
('first_name', 'Amy'),
|
|
|
|
('last_name', 'McDonald'),
|
|
|
|
('email', 'mcdonald@example.com'),
|
|
|
|
('__start__', 'password:mapping'),
|
|
|
|
('password', 'Amy'),
|
|
|
|
('password-confirm', 'Amy'),
|
|
|
|
('__end__', 'password:mapping'),
|
|
|
|
])
|
|
|
|
|
|
|
|
PASSWORD_RESET_FORM_DATA = MultiDict([
|
|
|
|
('__start__', 'password:mapping'),
|
|
|
|
('password', 'Nudge'),
|
|
|
|
('password-confirm', 'Nudge'),
|
|
|
|
('__end__', 'password:mapping'),
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('rolename', ['user', 'purchaser', 'admin'])
|
|
|
|
def test_account_login_active_users(dbsession, rolename):
|
|
|
|
''' login ok for active users '''
|
|
|
|
from ordr2.views.account import login
|
|
|
|
create_users(dbsession)
|
|
|
|
|
|
|
|
user = get_user(rolename)
|
|
|
|
request = DummyRequest(
|
|
|
|
dbsession=dbsession,
|
|
|
|
post={
|
|
|
|
'username': user.username,
|
|
|
|
'password': user.first_name
|
|
|
|
}
|
|
|
|
)
|
|
|
|
result = login(None, request)
|
|
|
|
|
|
|
|
assert isinstance(result, HTTPFound)
|
|
|
|
assert result.location == 'http://example.com//orders'
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('rolename', ['unvalidated', 'new', 'inactive'])
|
|
|
|
def test_account_login_fails_inactive_users(dbsession, rolename):
|
|
|
|
''' login fails for inactive users '''
|
|
|
|
from ordr2.views.account import login
|
|
|
|
create_users(dbsession)
|
|
|
|
|
|
|
|
user = get_user(rolename)
|
|
|
|
request = DummyRequest(
|
|
|
|
dbsession=dbsession,
|
|
|
|
post={
|
|
|
|
'username': user.username,
|
|
|
|
'password': user.first_name
|
|
|
|
}
|
|
|
|
)
|
|
|
|
result = login(None, request)
|
|
|
|
|
|
|
|
assert result == {}
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
'username, password', [
|
|
|
|
('EricIdle', 'wrong password'),
|
|
|
|
('unknown user', 'Eric'),
|
|
|
|
('unknown user', 'wrong password'),
|
|
|
|
('', '')
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def test_account_login_fails_wrong_credentials(dbsession, username, password):
|
|
|
|
''' login fails for unknown or wrong credentials '''
|
|
|
|
from ordr2.views.account import login
|
|
|
|
create_users(dbsession)
|
|
|
|
|
|
|
|
request = DummyRequest(
|
|
|
|
dbsession=dbsession,
|
|
|
|
post={
|
|
|
|
'username': username,
|
|
|
|
'password': password
|
|
|
|
}
|
|
|
|
)
|
|
|
|
result = login(None, request)
|
|
|
|
|
|
|
|
assert result == {}
|
|
|
|
|
|
|
|
|
|
|
|
def test_logout(app_config):
|
|
|
|
''' logout works '''
|
|
|
|
from ordr2.views.account import logout
|
|
|
|
user = get_user('admin')
|
|
|
|
|
|
|
|
request = DummyRequest(user=user)
|
|
|
|
result = logout(None, request)
|
|
|
|
|
|
|
|
assert isinstance(result, HTTPFound)
|
|
|
|
assert result.location == 'http://example.com//'
|
|
|
|
|
|
|
|
|
|
|
|
# tests for the registration form
|
|
|
|
|
|
|
|
def test_registration_form(app_config):
|
|
|
|
''' registration form '''
|
|
|
|
from ordr2.views.account import registration_form
|
|
|
|
|
|
|
|
request = DummyRequest()
|
|
|
|
context = DummyResource()
|
|
|
|
result = registration_form(context, request)
|
|
|
|
|
|
|
|
assert isinstance(result['form'], deform.Form)
|
|
|
|
|
|
|
|
|
|
|
|
def test_registration_form_processing_ok(dbsession):
|
|
|
|
''' registration form processing with valid data'''
|
|
|
|
from ordr2.models.account import User, Role, TokenSubject
|
|
|
|
from ordr2.views.account import registration_form_processing
|
|
|
|
|
|
|
|
user = get_user('user') # intentionally not added to database
|
|
|
|
context = DummyResource(model=user)
|
|
|
|
request = DummyRequest(dbsession=dbsession, context=context)
|
|
|
|
set_deform_data(request, REGISTRATION_FORM_DATA)
|
|
|
|
result = registration_form_processing(context, request)
|
|
|
|
|
|
|
|
# return value of function call
|
|
|
|
assert isinstance(result, HTTPFound)
|
|
|
|
assert result.location == 'http://example.com/registered'
|
|
|
|
|
|
|
|
# user should be added to database
|
|
|
|
user = dbsession.query(User).first()
|
|
|
|
assert user.username == REGISTRATION_FORM_DATA['username']
|
|
|
|
assert user.first_name == REGISTRATION_FORM_DATA['first_name']
|
|
|
|
assert user.last_name == REGISTRATION_FORM_DATA['last_name']
|
|
|
|
assert user.email == REGISTRATION_FORM_DATA['email']
|
|
|
|
assert user.check_password(REGISTRATION_FORM_DATA['password'])
|
|
|
|
assert user.role == Role.UNVALIDATED
|
|
|
|
|
|
|
|
# a token should be created
|
|
|
|
token = user.tokens[0]
|
|
|
|
assert token.subject == TokenSubject.USER_REGISTRATION
|
|
|
|
|
|
|
|
# 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
|
|
|
|
|
|
|
|
|
|
|
|
def test_registration_form_processing_cancel(app_config):
|
|
|
|
''' canceling registration form processing '''
|
|
|
|
from ordr2.models.account import User, Role, TokenSubject
|
|
|
|
from ordr2.views.account import registration_form_processing
|
|
|
|
|
|
|
|
user = get_user('user') # intentionally not added to database
|
|
|
|
context = DummyResource(model=user)
|
|
|
|
request = DummyRequest(dbsession=dbsession, context=context)
|
|
|
|
set_deform_data(request, REGISTRATION_FORM_DATA, {'Cancel': 'Cancel'})
|
|
|
|
result = registration_form_processing(context, request)
|
|
|
|
|
|
|
|
assert isinstance(result, HTTPFound)
|
|
|
|
assert result.location == 'http://example.com//'
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
'key,value', [
|
|
|
|
('username', ''),
|
|
|
|
('username', 'TerryGilliam'),
|
|
|
|
('first_name', ''),
|
|
|
|
('last_name', ''),
|
|
|
|
('email', ''),
|
|
|
|
('email', 'no email'),
|
|
|
|
('email', 'gilliam@example.com'),
|
|
|
|
('password', ''),
|
|
|
|
('password-confirm', ''),
|
|
|
|
('password-confirm', 'no match')
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def test_registration_form_processing_validation_error(dbsession, key, value):
|
|
|
|
''' registration form processing with valid data'''
|
|
|
|
from ordr2.models.account import User, Role, TokenSubject
|
|
|
|
from ordr2.views.account import registration_form_processing
|
|
|
|
|
|
|
|
admin = get_user('user')
|
|
|
|
dbsession.add(admin)
|
|
|
|
context = DummyResource(model=get_user('admin'))
|
|
|
|
request = DummyRequest(dbsession=dbsession, context=context)
|
|
|
|
set_deform_data(request, REGISTRATION_FORM_DATA, {key: value})
|
|
|
|
result = registration_form_processing(context, request)
|
|
|
|
|
|
|
|
assert isinstance(result['form'], deform.Form)
|
|
|
|
|
|
|
|
|
|
|
|
def test_registration_confirmation():
|
|
|
|
''' registration, awaiting confirmation of email address '''
|
|
|
|
from ordr2.views.account import registration_confirmation
|
|
|
|
|
|
|
|
result = registration_confirmation(None, None)
|
|
|
|
|
|
|
|
assert result == {}
|
|
|
|
|
|
|
|
|
|
|
|
def test_registration_completed(dbsession):
|
|
|
|
''' registration, confirmation of email address successful '''
|
|
|
|
from ordr2.models.account import User, Role, Token, TokenSubject
|
|
|
|
from ordr2.views.account import registration_completed
|
|
|
|
|
|
|
|
request = DummyRequest(dbsession=dbsession)
|
|
|
|
user = get_user('unvalidated')
|
|
|
|
user.issue_token(request, TokenSubject.USER_REGISTRATION)
|
|
|
|
dbsession.add(user)
|
|
|
|
dbsession.flush()
|
|
|
|
token = user.tokens[0]
|
|
|
|
context = DummyResource(model=token)
|
|
|
|
result = registration_completed(context, request)
|
|
|
|
|
|
|
|
assert result == {}
|
|
|
|
assert user.role == Role.NEW
|
|
|
|
assert dbsession.query(Token).count() == 0
|
|
|
|
assert dbsession.query(User).count() == 1
|
|
|
|
|
|
|
|
|
|
|
|
# tests for password reset
|
|
|
|
|
|
|
|
def test_forgot_password_form():
|
|
|
|
''' display the forgot password form '''
|
|
|
|
from ordr2.views.account import forgot_password_form
|
|
|
|
|
|
|
|
result = forgot_password_form(None, None)
|
|
|
|
|
|
|
|
assert result == {}
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('who', ['TerryGilliam', 'gilliam@example.com'])
|
|
|
|
def test_forgot_password_form_processing_ok(dbsession, who):
|
|
|
|
''' process the forgot password form '''
|
|
|
|
from ordr2.views.account import forgot_password_form_processing
|
|
|
|
|
|
|
|
dbsession.add(get_user('user'))
|
|
|
|
request = DummyRequest(
|
|
|
|
dbsession=dbsession,
|
|
|
|
POST={'username_or_email': who}
|
|
|
|
)
|
|
|
|
result = forgot_password_form_processing(None, request)
|
|
|
|
|
|
|
|
assert isinstance(result, HTTPFound)
|
|
|
|
assert result.location == 'http://example.com//forgot-password-email'
|
|
|
|
|
|
|
|
|
|
|
|
def test_forgot_password_form_processing_cancel(dbsession):
|
|
|
|
''' forgot password form was canceled '''
|
|
|
|
from ordr2.views.account import forgot_password_form_processing
|
|
|
|
|
|
|
|
dbsession.add(get_user('user'))
|
|
|
|
request = DummyRequest(
|
|
|
|
dbsession=dbsession,
|
|
|
|
POST={'username_or_email': 'gilliam@example.com', 'cancel': 'Cancel'}
|
|
|
|
)
|
|
|
|
result = forgot_password_form_processing(None, request)
|
|
|
|
|
|
|
|
assert isinstance(result, HTTPFound)
|
|
|
|
assert result.location == 'http://example.com//'
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
'who',
|
|
|
|
['unknown user', 'unknown@example.com', '']
|
|
|
|
)
|
|
|
|
def test_forgot_password_form_processing_error(dbsession, who):
|
|
|
|
''' process the forgot password form '''
|
|
|
|
from ordr2.views.account import forgot_password_form_processing
|
|
|
|
|
|
|
|
dbsession.add(get_user('user'))
|
|
|
|
request = DummyRequest(
|
|
|
|
dbsession=dbsession,
|
|
|
|
POST = {'username_or_email': who}
|
|
|
|
)
|
|
|
|
result = forgot_password_form_processing(None, request)
|
|
|
|
|
|
|
|
assert result == {}
|
|
|
|
|
|
|
|
|
|
|
|
def test_forgot_password_email_sent():
|
|
|
|
''' message that a password reset link was sent '''
|
|
|
|
from ordr2.views.account import forgot_password_email_sent
|
|
|
|
|
|
|
|
result = forgot_password_email_sent(None, None)
|
|
|
|
|
|
|
|
assert result == {}
|
|
|
|
|
|
|
|
|
|
|
|
def test_reset_password_form():
|
|
|
|
''' reset password form display '''
|
|
|
|
from ordr2.views.account import reset_password_form
|
|
|
|
|
|
|
|
request = DummyRequest()
|
|
|
|
result = reset_password_form(None, request)
|
|
|
|
|
|
|
|
assert isinstance(result['form'], deform.Form)
|
|
|
|
|
|
|
|
|
|
|
|
def test_reset_password_form_processing_ok(dbsession):
|
|
|
|
''' reset password form processing is ok '''
|
|
|
|
from ordr2.models.account import Token, TokenSubject, User
|
|
|
|
from ordr2.views.account import reset_password_form_processing
|
|
|
|
|
|
|
|
request = DummyRequest(dbsession=dbsession)
|
|
|
|
set_deform_data(request, REGISTRATION_FORM_DATA)
|
|
|
|
account = get_user('user')
|
|
|
|
token = account.issue_token(request, TokenSubject.RESET_PASSWORD)
|
|
|
|
dbsession.add(account)
|
|
|
|
dbsession.flush()
|
|
|
|
context = DummyResource(model=token)
|
|
|
|
result = reset_password_form_processing(context, request)
|
|
|
|
|
|
|
|
assert isinstance(result, HTTPFound)
|
|
|
|
assert result.location == 'http://example.com//login'
|
|
|
|
assert account.check_password(REGISTRATION_FORM_DATA['password'])
|
|
|
|
assert dbsession.query(Token).count() == 0
|
|
|
|
assert dbsession.query(User).count() == 1
|
|
|
|
|
|
|
|
|
|
|
|
def test_reset_password_form_processing_cancel():
|
|
|
|
''' reset password form processing is canceled '''
|
|
|
|
from ordr2.views.account import reset_password_form_processing
|
|
|
|
|
|
|
|
request = DummyRequest(dbsession=dbsession, POST={'Cancel': 'cancel'})
|
|
|
|
result = reset_password_form_processing(None, request)
|
|
|
|
|
|
|
|
assert isinstance(result, HTTPFound)
|
|
|
|
assert result.location == 'http://example.com//'
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
'pw, confirm', [
|
|
|
|
('', ''),
|
|
|
|
('no', 'match'),
|
|
|
|
('one is empty', ''),
|
|
|
|
('', 'one is empty'),
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def test_reset_password_form_processing_invalid(pw, confirm):
|
|
|
|
''' validation error in reset password form '''
|
|
|
|
from ordr2.views.account import reset_password_form_processing
|
|
|
|
|
|
|
|
request = DummyRequest(dbsession=dbsession)
|
|
|
|
modifier = {'password': pw, 'password-confim': confirm}
|
|
|
|
set_deform_data(request, REGISTRATION_FORM_DATA, modifier)
|
|
|
|
result = reset_password_form_processing(None, request)
|
|
|
|
|
|
|
|
assert isinstance(result['form'], deform.Form)
|