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.

187 lines
5.5 KiB

''' Test package for ordr2.models.account '''
import pytest
from datetime import datetime, timedelta
from pyramid.testing import DummyRequest
from .. import get_user, app_config
# tests for account.Role
def test_role_principals():
''' test Role.principal, a caluclated property '''
from ordr2.models.account import Role
assert Role.UNVALIDATED.principal == 'role:unvalidated'
assert Role.NEW.principal == 'role:new'
assert Role.USER.principal == 'role:user'
assert Role.PURCHASER.principal == 'role:purchaser'
assert Role.ADMIN.principal == 'role:admin'
assert Role.INACTIVE.principal == 'role:inactive'
def test_role_str():
''' test the string representation of roles '''
from ordr2.models.account import Role
assert str(Role.UNVALIDATED) == 'Unvalidated'
assert str(Role.NEW) == 'New'
assert str(Role.USER) == 'User'
assert str(Role.PURCHASER) == 'Purchaser'
assert str(Role.ADMIN) == 'Admin'
assert str(Role.INACTIVE) == 'Inactive'
# tests for account.User
def test_user_principal():
''' test the user principal calculated property '''
from ordr2.models.account import User
user = User(id=3)
assert user.principal == 'user:3'
@pytest.mark.parametrize(
'role_name, principals', [
('UNVALIDATED', ['role:unvalidated']),
('NEW', ['role:new']),
('USER', ['role:user']),
('PURCHASER', ['role:purchaser', 'role:user']),
('ADMIN', ['role:admin', 'role:purchaser', 'role:user']),
('INACTIVE', ['role:inactive'])
]
)
def test_user_role_principals(role_name, principals):
''' test the user's role principals calculated property '''
from ordr2.models.account import User, Role
role = Role[role_name]
user = User(role=role)
assert user.role_principals == principals
@pytest.mark.parametrize(
'role_name, is_active', [
('UNVALIDATED', False),
('NEW', False),
('USER', True),
('PURCHASER', True),
('ADMIN', True),
('INACTIVE', False)
]
)
def test_user_is_active(role_name, is_active):
''' test if is_active returns correct value based on the user's role '''
from ordr2.models.account import User, Role
role = Role[role_name]
user = User(role=role)
assert user.is_active == is_active
def test_user_set_password():
''' test password hash generation '''
from ordr2.models.account import User, passlib_context
passlib_context.update(schemes=['argon2', 'bcrypt'])
user = User(password_hash=None)
password = 'Fish Slapping Dance'
user.set_password(password)
assert user.password_hash.startswith('$argon2')
assert password not in user.password_hash
def test_user_check_password_ok():
''' test password check succeeds'''
from ordr2.models.account import User, passlib_context
passlib_context.update(schemes=['argon2', 'bcrypt'], deprecated='auto')
user = User(password_hash=None)
user.set_password('Fish Slapping Dance')
assert user.check_password('Fish Slapping Dance') is True
def test_user_check_password_fails():
''' test password check fails '''
from ordr2.models.account import User, passlib_context
passlib_context.update(schemes=['argon2', 'bcrypt'], deprecated='auto')
user = User(password_hash=None)
user.set_password('Fish Slapping Dance')
assert user.check_password('Argument Clininc') is False
def test_user_check_password_deprecated_hash():
''' test password check updates deprecated hash with new algorithm '''
from ordr2.models.account import User
from ordr2.security import passlib_context
passlib_context.update(schemes=['argon2', 'bcrypt'], deprecated='auto')
password = 'Fish Slapping Dance'
bcrypt_hash = passlib_context.hash(password, scheme='bcrypt')
user = User(password_hash=bcrypt_hash)
assert user.check_password(password)
assert user.password_hash != bcrypt_hash
assert user.password_hash.startswith('$argon2')
def test_user_string_representation():
''' test the string representation of the user '''
from ordr2.models.account import User, Role
user = User(username='FooBar')
assert str(user) == 'FooBar'
def test_user_issue_token(app_config):
from ordr2.models.account import Token, TokenSubject
request = DummyRequest()
request.registry.settings['token_expiry.change_email'] = 10
user = get_user('user')
payload = {'test-key': 'test-data'}
7 years ago
token = user.issue_token(request, TokenSubject.CHANGE_EMAIL, payload)
expected_expires = datetime.utcnow() + timedelta(minutes=10)
# one second drift is still considered ok
assert token.expires.timestamp() == pytest.approx(
expected_expires.timestamp(),
abs=1
)
assert token.owner == user
assert token.payload == payload
assert token.subject == TokenSubject.CHANGE_EMAIL
def test_token_issue(app_config):
from ordr2.models.account import Token, TokenSubject
request = DummyRequest()
request.registry.settings['token_expiry.change_email'] = 10
user = get_user('user')
payload = {'test-key': 'test-data'}
result = Token.issue(request, user, TokenSubject.CHANGE_EMAIL, payload)
expected_expires = datetime.utcnow() + timedelta(minutes=10)
# one second drift is still considered ok
assert result.expires.timestamp() == pytest.approx(
expected_expires.timestamp(),
abs=1
)
assert len(result.hash) == 32
assert result.owner == user
assert result.payload == payload
assert result.subject == TokenSubject.CHANGE_EMAIL
assert user.tokens[0] == result