CPI Ordering System (the old version)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

560 lines
18 KiB

''' 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'),
])
7 years ago
PASSWORD_RESET_FORM_DATA = MultiDict([
('__start__', 'password:mapping'),
('password', 'Nudge'),
('password-confirm', 'Nudge'),
('__end__', 'password:mapping'),
])
SETTINGS_FORM_DATA = MultiDict([
('__start__', 'general:mapping'),
('username', 'TerryGilliam'),
('first_name', 'Terry'),
('last_name', 'Gilliam'),
('email', 'gilliam@example.com'),
('role', 'USER'),
('__end__', 'general:mapping'),
('__start__', 'change_password:mapping'),
('__start__', 'new_password:mapping'),
('new_password', 'Amy'),
('new_password-confirm', 'Amy'),
('__end__', 'new_password:mapping'),
('__end__', 'change_password:mapping'),
('__start__', 'confirm_changes:mapping'),
('password', 'Terry'),
('__end__', 'confirm_changes: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 == {}
assert request.session.pop_flash('error') == [
'You entered the wrong username or password'
]
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
# 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
def test_registration_form_processing_cancel(dbsession):
''' 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 == {}
assert request.session.pop_flash('error') == [
'Username or email address unknown'
]
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)
7 years ago
def test_reset_password_form_processing_ok(dbsession):
''' reset password form processing is ok '''
7 years ago
from ordr2.models.account import Token, TokenSubject, User
from ordr2.views.account import reset_password_form_processing
7 years ago
request = DummyRequest(dbsession=dbsession)
set_deform_data(request, REGISTRATION_FORM_DATA)
account = get_user('user')
7 years ago
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)
7 years ago
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
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):
''' 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'),
]
)
7 years ago
def test_reset_password_form_processing_invalid(pw, confirm):
''' validation error in reset password form '''
from ordr2.views.account import reset_password_form_processing
7 years ago
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)
# settings
def test_settings_form(dbsession):
''' settings form display '''
from ordr2.views.account import settings_form
user = get_user('user')
context = DummyResource(model=user)
request = DummyRequest()
result = settings_form(context, request)
assert isinstance(result['form'], deform.Form)
def test_settings_form_processing_cancel(dbsession):
''' settings form processing is canceled '''
from ordr2.views.account import settings_form_processing
user = get_user('user')
context = DummyResource(model=user)
request = DummyRequest(dbsession=dbsession, POST={'Cancel': 'cancel'})
result = settings_form_processing(None, request)
assert isinstance(result, HTTPFound)
assert result.location == 'http://example.com//'
def test_settings_form_processing_change_name(dbsession):
''' settings form processing change name only '''
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 = {
'username': 'AmyMcDonald',
'first_name': 'Amy',
'last_name': 'McDonald',
'role': 'ADMIN',
'new_password': '',
'new_password-confirm': '',
}
set_deform_data(request, SETTINGS_FORM_DATA, changes)
result = settings_form_processing(context, request)
assert isinstance(result, HTTPFound)
assert result.location == 'http://example.com//'
assert user.username == 'TerryGilliam'
assert user.first_name == 'Amy'
assert user.last_name == 'McDonald'
assert user.email == 'gilliam@example.com'
assert user.check_password('Terry')
def test_settings_form_processing_change_password(dbsession):
''' settings form processing change name only '''
from ordr2.views.account import settings_form_processing
user = get_user('user')
context = DummyResource(model=user)
request = DummyRequest(dbsession=dbsession, user=user, context=context)
changes = {
'new_password': 'Amy',
'new_password-confirm': 'Amy',
}
set_deform_data(request, SETTINGS_FORM_DATA, changes)
result = settings_form_processing(context, request)
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']