Browse Source

linting and documentation

rework
Holger Frey 7 years ago
parent
commit
8503f27c66
  1. 3
      ordr/__init__.py
  2. 10
      ordr/models/__init__.py
  3. 12
      ordr/models/account.py
  4. 2
      ordr/resources/account.py
  5. 1
      ordr/schemas/__init__.py
  6. 14
      ordr/templates/errors/404.jinja2
  7. 35
      ordr/templates/errors/registration_verify.jinja2
  8. 1
      ordr/views/errors.py
  9. 4
      ordr/views/pages.py
  10. 2
      ordr/views/registration.py
  11. 2
      tests/_functional/__init__.py
  12. 1
      tests/_functional/errors.py
  13. 2
      tests/_functional/layout.py
  14. 12
      tests/_functional/login_logout.py
  15. 2
      tests/_functional/pages.py
  16. 11
      tests/_functional/registration.py
  17. 1
      tests/events.py
  18. 1
      tests/models/__init__.py
  19. 83
      tests/models/account.py
  20. 3
      tests/models/meta.py
  21. 28
      tests/resources/account.py
  22. 6
      tests/resources/base_child_resource.py
  23. 4
      tests/resources/root.py
  24. 7
      tests/security.py
  25. 3
      tests/views/errors.py
  26. 7
      tests/views/pages.py
  27. 7
      tests/views/registration.py

3
ordr/__init__.py

@ -6,8 +6,7 @@ __version__ = '0.0.1'
def main(global_config, **settings): def main(global_config, **settings):
""" This function returns a Pyramid WSGI application. ''' This function returns a Pyramid WSGI application. '''
"""
config = Configurator(settings=settings) config = Configurator(settings=settings)
session_factory = SignedCookieSessionFactory(settings['session.secret']) session_factory = SignedCookieSessionFactory(settings['session.secret'])

10
ordr/models/__init__.py

@ -23,7 +23,7 @@ def get_session_factory(engine):
def get_tm_session(session_factory, transaction_manager): def get_tm_session(session_factory, transaction_manager):
""" '''
Get a ``sqlalchemy.orm.Session`` instance backed by a transaction. Get a ``sqlalchemy.orm.Session`` instance backed by a transaction.
This function will hook the session to the transaction manager which This function will hook the session to the transaction manager which
@ -41,8 +41,7 @@ def get_tm_session(session_factory, transaction_manager):
session_factory = get_session_factory(engine) session_factory = get_session_factory(engine)
with transaction.manager: with transaction.manager:
dbsession = get_tm_session(session_factory, transaction.manager) dbsession = get_tm_session(session_factory, transaction.manager)
'''
"""
dbsession = session_factory() dbsession = session_factory()
zope.sqlalchemy.register( zope.sqlalchemy.register(
dbsession, transaction_manager=transaction_manager) dbsession, transaction_manager=transaction_manager)
@ -50,12 +49,11 @@ def get_tm_session(session_factory, transaction_manager):
def includeme(config): def includeme(config):
""" '''
Initialize the model for a Pyramid app. Initialize the model for a Pyramid app.
Activate this setup using ``config.include('ordr.models')``. Activate this setup using ``config.include('ordr.models')``.
'''
"""
settings = config.get_settings() settings = config.get_settings()
settings['tm.manager_hook'] = 'pyramid_tm.explicit_manager' settings['tm.manager_hook'] = 'pyramid_tm.explicit_manager'

12
ordr/models/account.py

@ -4,6 +4,7 @@ import enum
import uuid import uuid
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pyramid import httpexceptions
from sqlalchemy import ( from sqlalchemy import (
Column, Column,
Date, Date,
@ -16,10 +17,17 @@ from sqlalchemy import (
) )
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from .meta import Base, JsonEncoder from .meta import Base, JsonEncoder
# custom exceptions
class TokenExpired(httpexceptions.HTTPGone):
pass
# enumerations
class Role(enum.Enum): class Role(enum.Enum):
''' roles of user accounts ''' ''' roles of user accounts '''
@ -221,5 +229,5 @@ class Token(Base):
return None return None
elif token.expires < datetime.utcnow(): elif token.expires < datetime.utcnow():
request.dbsession.delete(token) request.dbsession.delete(token)
return None raise TokenExpired('Token has expired')
return token return token

2
ordr/resources/account.py

@ -18,6 +18,8 @@ class RegistrationTokenResource(BaseChildResource):
:param parent: the parent resouce :param parent: the parent resouce
''' '''
nav_active = 'registration'
def __acl__(self): def __acl__(self):
''' access controll list for the resource ''' ''' access controll list for the resource '''
return [(Allow, Everyone, 'view'), DENY_ALL] return [(Allow, Everyone, 'view'), DENY_ALL]

1
ordr/schemas/__init__.py

@ -48,7 +48,6 @@ def includeme(config):
Initialize the form schemas Initialize the form schemas
Activate this setup using ``config.include('ordr.schemas')``. Activate this setup using ``config.include('ordr.schemas')``.
''' '''
# Make Deform widgets aware of our widget template paths # Make Deform widgets aware of our widget template paths
configure_zpt_renderer(['ordr:templates/deform']) configure_zpt_renderer(['ordr:templates/deform'])

14
ordr/templates/errors/404.jinja2

@ -1,8 +1,14 @@
{% extends "ordr:templates/layout.jinja2" %} {% extends "ordr:templates/layout.jinja2" %}
{% block title %} Ordr | Error {% endblock title %}
{% block content %} {% block content %}
<div class="content"> <div class="row justify-content-md-center mt-3">
<h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> <div class="col-8">
<p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> <h1 class="mt-3">An Error has occured</h1>
</div> <p class="mt-4">The page you are looking for could not be found</p>
<small class="text-secondary">404 - Page not found</small>
</div>
</div>
{% endblock content %} {% endblock content %}

35
ordr/templates/errors/registration_verify.jinja2

@ -0,0 +1,35 @@
{% extends "ordr:templates/layout.jinja2" %}
{% block title %} Ordr | Registration {% endblock title %}
{% block content %}
<div class="row justify-content-md-center mt-3">
<div class="col-6">
<h1>Registration</h1>
</div>
</div>
<div class="row justify-content-md-center mt-3">
<div class="col-2">
<p class="text-secondary">
Step 1: Registration
</p>
</div>
<div class="col-2">
<p class="text-primary">
Step 2: Validate Email
</p>
</div>
<div class="col-2">
<p class="text-secondary">
Step 3: Finished
</p>
</div>
</div>
<div class="row justify-content-md-center mt-3">
<div class="col-6">
<h3>Verify Your Email Address</h3>
<p class="mt-3">To complete the registration process an email has been sent to you.</p>
<p>Please follow the link in the email to verify your address and complete the registration process.</p>
</div>
</div>
{% endblock content %}

1
ordr/views/errors.py

@ -3,5 +3,6 @@ from pyramid.view import notfound_view_config
@notfound_view_config(renderer='ordr:templates/errors/404.jinja2') @notfound_view_config(renderer='ordr:templates/errors/404.jinja2')
def notfound_view(context, request): def notfound_view(context, request):
''' display a file not found page '''
request.response.status = 404 request.response.status = 404
return {} return {}

4
ordr/views/pages.py

@ -10,6 +10,7 @@ from ordr.models import User
permission='view', permission='view',
) )
def welcome(context, request): def welcome(context, request):
''' web root redirects '''
next = 'orders' if request.user else 'login' next = 'orders' if request.user else 'login'
redirect_to = request.resource_url(context, next) redirect_to = request.resource_url(context, next)
return HTTPFound(redirect_to) return HTTPFound(redirect_to)
@ -22,6 +23,7 @@ def welcome(context, request):
renderer='ordr:templates/pages/faq.jinja2' renderer='ordr:templates/pages/faq.jinja2'
) )
def faq(context, request): def faq(context, request):
''' displays the FAQ page '''
return {} return {}
@ -33,6 +35,7 @@ def faq(context, request):
renderer='ordr:templates/pages/login.jinja2', renderer='ordr:templates/pages/login.jinja2',
) )
def login(context, request): def login(context, request):
''' shows the login page '''
return {'loginerror': False} return {'loginerror': False}
@ -44,6 +47,7 @@ def login(context, request):
renderer='ordr:templates/pages/login.jinja2', renderer='ordr:templates/pages/login.jinja2',
) )
def check_login(context, request): def check_login(context, request):
''' check user credentials '''
username = request.POST.get('username') username = request.POST.get('username')
password = request.POST.get('password') password = request.POST.get('password')
user = ( user = (

2
ordr/views/registration.py

@ -78,7 +78,7 @@ def verify(context, request):
renderer='ordr:templates/account/registration_completed.jinja2' renderer='ordr:templates/account/registration_completed.jinja2'
) )
def completed(context, request): def completed(context, request):
''' show email verification text ''' ''' registration is completed, awaiting activation by admin '''
token = context.model token = context.model
account = token.owner account = token.owner
account.role = Role.NEW account.role = Role.NEW

2
tests/_functional/__init__.py

@ -57,7 +57,7 @@ def get_token_url(email, prefix='/'):
@pytest.fixture(scope='module') @pytest.fixture(scope='module')
def testappsetup(): def testappsetup():
''' fixture for using webtest ''' setup of fixture for using webtest
this fixture just sets up the testapp. please use the testapp() fixture this fixture just sets up the testapp. please use the testapp() fixture
below for real tests. below for real tests.

1
tests/_functional/errors.py

@ -4,5 +4,6 @@ from . import testappsetup, testapp # noqa: F401
def test_404(testapp): # noqa: F811 def test_404(testapp): # noqa: F811
''' test the 404 page '''
response = testapp.get('/unknown', status=404) response = testapp.get('/unknown', status=404)
assert '404' in response assert '404' in response

2
tests/_functional/layout.py

@ -10,6 +10,7 @@ from . import testappsetup, testapp # noqa: F401
def test_navbar_no_user(testapp): # noqa: F811 def test_navbar_no_user(testapp): # noqa: F811
''' test the navigation on top of the page for an unauthenticated user '''
response = testapp.get('/faq') response = testapp.get('/faq')
navbar = response.html.find('nav', class_='navbar-dark') navbar = response.html.find('nav', class_='navbar-dark')
expected = ['/', '/', '/faq', '/register'] expected = ['/', '/', '/faq', '/register']
@ -28,6 +29,7 @@ def test_navbar_no_user(testapp): # noqa: F811
] ]
) )
def test_navbar_with_user(testapp, username, password, extras): def test_navbar_with_user(testapp, username, password, extras):
''' test the navigation on top of the page for an authenticated user '''
testapp.login(username, password) testapp.login(username, password)
response = testapp.get('/faq') response = testapp.get('/faq')
navbar = response.html.find('nav', class_='navbar-dark') navbar = response.html.find('nav', class_='navbar-dark')

12
tests/_functional/login_logout.py

@ -6,6 +6,7 @@ from . import testappsetup, testapp # noqa: F401
def test_login_get(testapp): # noqa: F811 def test_login_get(testapp): # noqa: F811
''' test the login form '''
response = testapp.get('/login') response = testapp.get('/login')
active = response.html.find('li', class_='active') active = response.html.find('li', class_='active')
assert active.a['href'] == '/' assert active.a['href'] == '/'
@ -13,18 +14,10 @@ def test_login_get(testapp): # noqa: F811
expected = {'/', '/faq', '/register', '/forgot', '/register'} expected = {'/', '/faq', '/register', '/forgot', '/register'}
hrefs = {a['href'] for a in response.html.find_all('a')} hrefs = {a['href'] for a in response.html.find_all('a')}
assert expected == hrefs assert expected == hrefs
forms = response.html.find_all('form')
assert len(forms) == 1
login_form = forms[0]
assert login_form['action'] == '/login'
assert login_form['method'] == 'POST'
assert 'account is not activated' not in response
def test_login_ok(testapp): # noqa: F811 def test_login_ok(testapp): # noqa: F811
''' test login form with valid credentials '''
response = testapp.get('/login') response = testapp.get('/login')
login_form = response.forms[0] login_form = response.forms[0]
@ -40,6 +33,7 @@ def test_login_ok(testapp): # noqa: F811
[('John', 'Cleese'), ('unknown user', 'wrong password')] [('John', 'Cleese'), ('unknown user', 'wrong password')]
) )
def test_login_denied(testapp, username, password): def test_login_denied(testapp, username, password):
''' test login form with invalid credentials '''
response = testapp.get('/login') response = testapp.get('/login')
login_form = response.forms[0] login_form = response.forms[0]

2
tests/_functional/pages.py

@ -4,6 +4,7 @@ from . import testappsetup, testapp # noqa: F401
def test_welcome(testapp): # noqa: F811 def test_welcome(testapp): # noqa: F811
''' test the redirects on web root '''
response = testapp.get('/') response = testapp.get('/')
assert response.location == 'http://localhost/login' assert response.location == 'http://localhost/login'
@ -14,6 +15,7 @@ def test_welcome(testapp): # noqa: F811
def test_faq(testapp): # noqa: F811 def test_faq(testapp): # noqa: F811
''' test the faq page '''
response = testapp.get('/faq') response = testapp.get('/faq')
active = response.html.find('li', class_='active') active = response.html.find('li', class_='active')
assert active.a['href'] == '/faq' assert active.a['href'] == '/faq'

11
tests/_functional/registration.py

@ -6,12 +6,15 @@ from . import testappsetup, testapp, get_token_url # noqa: F401
def test_registration_form(testapp): # noqa: F811 def test_registration_form(testapp): # noqa: F811
''' test the registration form '''
response = testapp.get('/register') response = testapp.get('/register')
active = response.html.find('li', class_='active') active = response.html.find('li', class_='active')
assert active.a['href'] == '/register' assert active.a['href'] == '/register'
assert 'Registration' in response.html.title.text
def test_registration_form_invalid(testapp): # noqa: F811 def test_registration_form_invalid(testapp): # noqa: F811
''' test the registration form with invalid data '''
response = testapp.get('/register') response = testapp.get('/register')
form = response.form form = response.form
@ -19,9 +22,11 @@ def test_registration_form_invalid(testapp): # noqa: F811
response = form.submit(name='create') response = form.submit(name='create')
assert 'Invalid email address' in response assert 'Invalid email address' in response
assert 'Registration' in response.html.title.text
def test_registration_process(testapp): # noqa: F811 def test_registration_process(testapp): # noqa: F811
''' test the registration process with valid data '''
response = testapp.get('/register') response = testapp.get('/register')
form = response.form form = response.form
@ -35,7 +40,10 @@ def test_registration_process(testapp): # noqa: F811
assert response.location == 'http://localhost/register/verify' assert response.location == 'http://localhost/register/verify'
response = response.follow() response = response.follow()
active = response.html.find('li', class_='active')
assert active.a['href'] == '/register'
assert 'Please follow the link in the email' in response assert 'Please follow the link in the email' in response
assert 'Registration' in response.html.title.text
# click the email verification token # click the email verification token
mailer = get_mailer(testapp.app.registry) mailer = get_mailer(testapp.app.registry)
@ -44,4 +52,7 @@ def test_registration_process(testapp): # noqa: F811
token_link = get_token_url(email, prefix='/register/') token_link = get_token_url(email, prefix='/register/')
response = testapp.get(token_link) response = testapp.get(token_link)
active = response.html.find('li', class_='active')
assert active.a['href'] == '/register'
assert 'Registration Completed' in response assert 'Registration Completed' in response
assert 'Registration' in response.html.title.text

1
tests/events.py

@ -21,6 +21,7 @@ def test_user_notification_init(app_config): # noqa: F811
def test_notify_user(app_config): # noqa: F811 def test_notify_user(app_config): # noqa: F811
''' test the user notification '''
from ordr.events import RegistrationNotification, notify_user from ordr.events import RegistrationNotification, notify_user
from ordr.models.account import Token, Role from ordr.models.account import Token, Role

1
tests/models/__init__.py

@ -0,0 +1 @@
''' test (sub) package for views '''

83
tests/models/account.py

@ -3,13 +3,14 @@ import pytest
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pyramid.testing import DummyRequest from pyramid.testing import DummyRequest
from .. import app_config # noqa: F401 from .. import app_config, dbsession, get_example_user # noqa: F401
@pytest.mark.parametrize( @pytest.mark.parametrize(
'key,result', [('NEW', 'role:new'), ('USER', 'role:user')] 'key,result', [('NEW', 'role:new'), ('USER', 'role:user')]
) )
def test_role_principal(key, result): def test_role_principal(key, result):
''' test the principal representation of a role '''
from ordr.models.account import Role from ordr.models.account import Role
subject = Role[key] subject = Role[key]
assert subject.principal == result assert subject.principal == result
@ -19,6 +20,7 @@ def test_role_principal(key, result):
'key,result', [('NEW', 'New'), ('USER', 'User')] 'key,result', [('NEW', 'New'), ('USER', 'User')]
) )
def test_role__str__(key, result): def test_role__str__(key, result):
''' test the string representation of a role '''
from ordr.models.account import Role from ordr.models.account import Role
subject = Role[key] subject = Role[key]
assert str(subject) == result assert str(subject) == result
@ -26,6 +28,7 @@ def test_role__str__(key, result):
@pytest.mark.parametrize('id_', [1, 2, 5, 123]) @pytest.mark.parametrize('id_', [1, 2, 5, 123])
def test_user_principal(id_): def test_user_principal(id_):
''' test the principal representation of a user '''
from ordr.models.account import User from ordr.models.account import User
user = User(id=id_) user = User(id=id_)
assert user.principal == f'user:{id_}' assert user.principal == f'user:{id_}'
@ -42,6 +45,7 @@ def test_user_principal(id_):
] ]
) )
def test_user_principals(name, principals): def test_user_principals(name, principals):
''' test all principals of a user '''
from ordr.models.account import User, Role from ordr.models.account import User, Role
user = User(id=1, role=Role[name]) user = User(id=1, role=Role[name])
@ -62,12 +66,14 @@ def test_user_principals(name, principals):
] ]
) )
def test_user_is_active(name, expected): def test_user_is_active(name, expected):
''' test the calculated property 'active' of a user '''
from ordr.models.account import User, Role from ordr.models.account import User, Role
user = User(id=1, role=Role[name]) user = User(id=1, role=Role[name])
assert expected == user.is_active assert expected == user.is_active
def test_user_set_password(): def test_user_set_password():
''' test 'set_password()' method of a user '''
from ordr.models.account import User from ordr.models.account import User
from ordr.security import password_context from ordr.security import password_context
@ -87,6 +93,7 @@ def test_user_set_password():
] ]
) )
def test_user_check_password(password, expected): def test_user_check_password(password, expected):
''' test the 'check_password()' method of a user '''
from ordr.models.account import User from ordr.models.account import User
from ordr.security import password_context from ordr.security import password_context
@ -100,6 +107,7 @@ def test_user_check_password(password, expected):
def test_user_check_password_updates_old_sheme(): def test_user_check_password_updates_old_sheme():
''' test that 'check_password()' updates the hash off an old scheme '''
from ordr.models.account import User from ordr.models.account import User
from ordr.security import password_context from ordr.security import password_context
@ -117,12 +125,14 @@ def test_user_check_password_updates_old_sheme():
def test_user__str__(): def test_user__str__():
''' test the string representation of a user '''
from ordr.models.account import User from ordr.models.account import User
user = User(username='Eric Idle') user = User(username='Eric Idle')
assert str(user) == 'Eric Idle' assert str(user) == 'Eric Idle'
def test_user_issue_token(app_config): # noqa: F811 def test_user_issue_token(app_config): # noqa: F811
''' test the 'issue_token()' method of a user '''
from ordr.models.account import User, Token, TokenSubject from ordr.models.account import User, Token, TokenSubject
request = DummyRequest() request = DummyRequest()
@ -137,6 +147,7 @@ def test_user_issue_token(app_config): # noqa: F811
def test_token_issue_token(app_config): # noqa: F811 def test_token_issue_token(app_config): # noqa: F811
''' test the 'issue()' class method of the token class '''
from ordr.models.account import User, Token, TokenSubject from ordr.models.account import User, Token, TokenSubject
request = DummyRequest() request = DummyRequest()
@ -159,6 +170,7 @@ def test_token_issue_token(app_config): # noqa: F811
'subject,delta', [('REGISTRATION', 5), ('RESET_PASSWORD', 10)] 'subject,delta', [('REGISTRATION', 5), ('RESET_PASSWORD', 10)]
) )
def test_token_issue_token_time_from_settings(app_config, subject, delta): def test_token_issue_token_time_from_settings(app_config, subject, delta):
''' test that 'issue()' uses the exiration time from setting '''
from ordr.models.account import User, Token, TokenSubject from ordr.models.account import User, Token, TokenSubject
request = DummyRequest() request = DummyRequest()
@ -172,3 +184,72 @@ def test_token_issue_token_time_from_settings(app_config, subject, delta):
expected_expires.timestamp(), expected_expires.timestamp(),
abs=1 abs=1
) )
@pytest.mark.parametrize('use_subject', [True, False]) # noqa: F811
def test_registration_token_retrieve_ok(dbsession, use_subject):
''' test 'retrieve()' class method returns token instance '''
from ordr.models.account import Role, Token, TokenSubject
request = DummyRequest(dbsession=dbsession)
user = get_example_user(Role.NEW)
token = user.issue_token(request, TokenSubject.REGISTRATION)
dbsession.add(user)
dbsession.flush()
subject = TokenSubject.REGISTRATION if use_subject else None
result = Token.retrieve(request, token.hash, subject=subject)
assert result == token
def test_registration_token_retrieve_not_found(dbsession): # noqa: F811
''' test 'retrieve()' class method returns None if token not found '''
from ordr.models.account import Role, Token, TokenSubject
request = DummyRequest(dbsession=dbsession)
user = get_example_user(Role.NEW)
user.issue_token(request, TokenSubject.REGISTRATION)
dbsession.add(user)
dbsession.flush()
result = Token.retrieve(request, 'unknown hash')
assert result is None
def test_registration_token_retrieve_wrong_subject(dbsession): # noqa: F811
''' test 'retrieve()' class method returns None if wrong subject used '''
from ordr.models.account import Role, Token, TokenSubject
request = DummyRequest(dbsession=dbsession)
user = get_example_user(Role.NEW)
token = user.issue_token(request, TokenSubject.REGISTRATION)
dbsession.add(user)
dbsession.flush()
result = Token.retrieve(
request,
token.hash,
subject=TokenSubject.RESET_PASSWORD
)
assert result is None
def test_registration_token_expired_raises_exception(dbsession): # noqa: F811
''' test 'retrieve()' class method raises exception if token is expired '''
from ordr.models.account import Role, Token, TokenSubject, TokenExpired
request = DummyRequest(dbsession=dbsession)
user = get_example_user(Role.NEW)
token = user.issue_token(request, TokenSubject.REGISTRATION)
token.expires = datetime.utcnow() - timedelta(weeks=1)
dbsession.add(user)
dbsession.flush()
with pytest.raises(TokenExpired):
Token.retrieve(request, token.hash)
dbsession.flush()
assert dbsession.query(Token).count() == 0

3
tests/models/meta.py

@ -9,6 +9,7 @@ import pytest
] ]
) )
def test_json_encoder_bind(value, expected): def test_json_encoder_bind(value, expected):
''' test encoding json '''
from ordr.models.meta import JsonEncoder from ordr.models.meta import JsonEncoder
encoder = JsonEncoder() encoder = JsonEncoder()
assert encoder.process_bind_param(value, None) == expected assert encoder.process_bind_param(value, None) == expected
@ -22,6 +23,7 @@ def test_json_encoder_bind(value, expected):
] ]
) )
def test_json_encoder_result(value, expected): def test_json_encoder_result(value, expected):
''' test decoding json '''
from ordr.models.meta import JsonEncoder from ordr.models.meta import JsonEncoder
encoder = JsonEncoder() encoder = JsonEncoder()
assert encoder.process_result_value(value, None) == expected assert encoder.process_result_value(value, None) == expected
@ -29,6 +31,7 @@ def test_json_encoder_result(value, expected):
@pytest.mark.parametrize('value', [None, [1, 2, 3], {'a': 1, 'b': 2}]) @pytest.mark.parametrize('value', [None, [1, 2, 3], {'a': 1, 'b': 2}])
def test_json_encoder_bind_and_result(value): def test_json_encoder_bind_and_result(value):
''' encoding and later decoding json should provide not change value '''
from ordr.models.meta import JsonEncoder from ordr.models.meta import JsonEncoder
encoder = JsonEncoder() encoder = JsonEncoder()
result = encoder.process_bind_param(value, None) result = encoder.process_bind_param(value, None)

28
tests/resources/account.py

@ -2,13 +2,13 @@
import pytest import pytest
from datetime import datetime, timedelta
from pyramid.testing import DummyRequest, DummyResource from pyramid.testing import DummyRequest, DummyResource
from .. import app_config, dbsession, get_example_user # noqa: F401 from .. import app_config, dbsession, get_example_user # noqa: F401
def test_registration_token_acl(): def test_registration_token_acl():
''' test access controll list for RegistrationTokenResource '''
from pyramid.security import Allow, Everyone, DENY_ALL from pyramid.security import Allow, Everyone, DENY_ALL
from ordr.resources.account import RegistrationTokenResource from ordr.resources.account import RegistrationTokenResource
@ -19,6 +19,7 @@ def test_registration_token_acl():
def test_registration_acl(): def test_registration_acl():
''' test access controll list for RegistrationResource '''
from pyramid.security import Allow, Everyone, DENY_ALL from pyramid.security import Allow, Everyone, DENY_ALL
from ordr.resources.account import RegistrationResource from ordr.resources.account import RegistrationResource
@ -29,6 +30,7 @@ def test_registration_acl():
def test_registration_get_registration_form(): def test_registration_get_registration_form():
''' test 'get_registration_form()' method of RegistrationResource '''
from pyramid.security import Allow, Everyone, DENY_ALL from pyramid.security import Allow, Everyone, DENY_ALL
from ordr.resources.account import RegistrationResource from ordr.resources.account import RegistrationResource
import deform import deform
@ -45,6 +47,7 @@ def test_registration_get_registration_form():
def test_registration_getitem_found(dbsession): # noqa: F811 def test_registration_getitem_found(dbsession): # noqa: F811
''' test '__getitem__()' method returns child resource '''
from ordr.models.account import Role, TokenSubject from ordr.models.account import Role, TokenSubject
from ordr.resources.account import ( from ordr.resources.account import (
RegistrationResource, RegistrationResource,
@ -69,6 +72,7 @@ def test_registration_getitem_found(dbsession): # noqa: F811
def test_registration_getitem_not_found(dbsession): # noqa: F811 def test_registration_getitem_not_found(dbsession): # noqa: F811
''' test '__getitem__()' method raises KeyError '''
from ordr.models.account import Role, TokenSubject from ordr.models.account import Role, TokenSubject
from ordr.resources.account import RegistrationResource from ordr.resources.account import RegistrationResource
@ -84,25 +88,3 @@ def test_registration_getitem_not_found(dbsession): # noqa: F811
with pytest.raises(KeyError): with pytest.raises(KeyError):
resource['unknown hash'] resource['unknown hash']
def test_registration_getitem_expired(dbsession): # noqa: F811
from ordr.models.account import Role, Token, TokenSubject
from ordr.resources.account import RegistrationResource
request = DummyRequest(dbsession=dbsession)
user = get_example_user(Role.NEW)
token = user.issue_token(request, TokenSubject.REGISTRATION)
token.expires = datetime.utcnow() - timedelta(weeks=1)
dbsession.add(user)
dbsession.flush()
parent = DummyResource(request=request)
resource = RegistrationResource('a name', parent)
with pytest.raises(KeyError):
resource[token.hash]
dbsession.flush()
assert dbsession.query(Token).count() == 0

6
tests/resources/base_child_resource.py

@ -6,6 +6,7 @@ from pyramid.testing import DummyRequest, DummyResource
def test_base_child_init(): def test_base_child_init():
''' test initilization of BaseChildResource '''
from ordr.resources.helpers import BaseChildResource from ordr.resources.helpers import BaseChildResource
parent = DummyResource(request='some request') parent = DummyResource(request='some request')
@ -17,6 +18,7 @@ def test_base_child_init():
def test_base_child_acl(): def test_base_child_acl():
''' test access controll list of BaseChildResource '''
from ordr.resources.helpers import BaseChildResource from ordr.resources.helpers import BaseChildResource
parent = DummyResource(request='some request') parent = DummyResource(request='some request')
@ -27,6 +29,7 @@ def test_base_child_acl():
def test_base_child_prepare_form(): def test_base_child_prepare_form():
''' test '_prepare_form()' method of BaseChildResource '''
from ordr.resources.helpers import BaseChildResource from ordr.resources.helpers import BaseChildResource
from ordr.schemas.account import RegistrationSchema from ordr.schemas.account import RegistrationSchema
import deform import deform
@ -42,6 +45,7 @@ def test_base_child_prepare_form():
def test_base_child_prepare_form_url(): def test_base_child_prepare_form_url():
''' test '_prepare_form()' method sets correct url '''
from ordr.resources.helpers import BaseChildResource from ordr.resources.helpers import BaseChildResource
from ordr.schemas.account import RegistrationSchema from ordr.schemas.account import RegistrationSchema
@ -54,6 +58,7 @@ def test_base_child_prepare_form_url():
def test_base_child_prepare_form_settings(): def test_base_child_prepare_form_settings():
''' test '_prepare_form()' method uses additional settings '''
from ordr.resources.helpers import BaseChildResource from ordr.resources.helpers import BaseChildResource
from ordr.schemas.account import RegistrationSchema from ordr.schemas.account import RegistrationSchema
import deform import deform
@ -70,6 +75,7 @@ def test_base_child_prepare_form_settings():
def test_base_child_prepare_form_prefill(): def test_base_child_prepare_form_prefill():
''' test '_prepare_form()' method can prefill a form '''
from ordr.resources.helpers import BaseChildResource from ordr.resources.helpers import BaseChildResource
from ordr.schemas.account import RegistrationSchema from ordr.schemas.account import RegistrationSchema

4
tests/resources/root.py

@ -4,6 +4,7 @@ import pytest
def test_root_init(): def test_root_init():
''' test RootResource initialization '''
from ordr.resources import RootResource from ordr.resources import RootResource
root = RootResource('request') root = RootResource('request')
assert root.__name__ is None assert root.__name__ is None
@ -12,6 +13,7 @@ def test_root_init():
def test_root_acl(): def test_root_acl():
''' test access controll list for RootResource '''
from pyramid.security import Allow, Everyone, DENY_ALL from pyramid.security import Allow, Everyone, DENY_ALL
from ordr.resources import RootResource from ordr.resources import RootResource
root = RootResource(None) root = RootResource(None)
@ -19,6 +21,7 @@ def test_root_acl():
def test_root_getitem(): def test_root_getitem():
''' test '__getitem__()' method of RootResource '''
from ordr.resources import RootResource from ordr.resources import RootResource
from ordr.resources.account import RegistrationResource from ordr.resources.account import RegistrationResource
@ -32,6 +35,7 @@ def test_root_getitem():
def test_root_getitem_raises_error(): def test_root_getitem_raises_error():
''' test '__getitem__()' method raises KeyError '''
from ordr.resources import RootResource from ordr.resources import RootResource
root = RootResource(None) root = RootResource(None)
with pytest.raises(KeyError): with pytest.raises(KeyError):

7
tests/security.py

@ -6,6 +6,7 @@ from . import app_config, dbsession, get_example_user # noqa: F401
def test_crypt_context_to_settings(): def test_crypt_context_to_settings():
''' test the transformation of .ini styles from pyramid to passlib '''
from ordr.security import crypt_context_settings_to_string from ordr.security import crypt_context_settings_to_string
settings = { settings = {
@ -26,6 +27,7 @@ def test_crypt_context_to_settings():
def test_authentication_policy_authenticated_user_id_no_user(): def test_authentication_policy_authenticated_user_id_no_user():
''' test 'authenticated_userid()' returns None if no user is logged in '''
from ordr.security import AuthenticationPolicy from ordr.security import AuthenticationPolicy
ap = AuthenticationPolicy('') ap = AuthenticationPolicy('')
@ -35,6 +37,7 @@ def test_authentication_policy_authenticated_user_id_no_user():
def test_authentication_policy_authenticated_user_id_with_user(): def test_authentication_policy_authenticated_user_id_with_user():
''' test 'authenticated_userid()' returns id if user is logged in '''
from ordr.security import AuthenticationPolicy from ordr.security import AuthenticationPolicy
from ordr.models import User from ordr.models import User
@ -45,6 +48,7 @@ def test_authentication_policy_authenticated_user_id_with_user():
def test_authentication_policy_effective_principals_no_user(): def test_authentication_policy_effective_principals_no_user():
''' test 'effective_principals()' if not user is logged in '''
from ordr.security import AuthenticationPolicy from ordr.security import AuthenticationPolicy
from pyramid.security import Everyone from pyramid.security import Everyone
@ -56,6 +60,7 @@ def test_authentication_policy_effective_principals_no_user():
def test_authentication_policy_effective_principals_with_user(): def test_authentication_policy_effective_principals_with_user():
''' test 'effective_principals()' if user is logged in '''
from ordr.security import AuthenticationPolicy from ordr.security import AuthenticationPolicy
from ordr.models import User, Role from ordr.models import User, Role
from pyramid.security import Authenticated, Everyone from pyramid.security import Authenticated, Everyone
@ -83,6 +88,7 @@ def test_authentication_policy_effective_principals_with_user():
] ]
) )
def test_get_user_returns_user(dbsession, uauid, role_name): def test_get_user_returns_user(dbsession, uauid, role_name):
''' test 'get_user()' returns active user '''
from ordr.security import get_user from ordr.security import get_user
from ordr.models import Role from ordr.models import Role
@ -109,6 +115,7 @@ def test_get_user_returns_user(dbsession, uauid, role_name):
] ]
) )
def test_get_user_returns_none(dbsession, uauid, role_name): def test_get_user_returns_none(dbsession, uauid, role_name):
''' test 'get_user()' returns None for an inactive user '''
from ordr.security import get_user from ordr.security import get_user
from ordr.models import Role from ordr.models import Role

3
tests/views/errors.py

@ -1,7 +1,8 @@
from pyramid.testing import DummyRequest from pyramid.testing import DummyRequest
def test_welcome(): def test_404():
''' test the file not found view '''
from ordr.views.errors import notfound_view from ordr.views.errors import notfound_view
request = DummyRequest() request = DummyRequest()

7
tests/views/pages.py

@ -13,6 +13,7 @@ from .. import app_config, dbsession, get_example_user # noqa: F401
[(None, '/login'), ('someone', '/orders')] [(None, '/login'), ('someone', '/orders')]
) )
def test_welcome(user, location): def test_welcome(user, location):
''' test redirects on web root '''
from ordr.views.pages import welcome from ordr.views.pages import welcome
request = DummyRequest(user=user) request = DummyRequest(user=user)
@ -23,12 +24,14 @@ def test_welcome(user, location):
def test_faq(): def test_faq():
''' test the view for the faq page '''
from ordr.views.pages import faq from ordr.views.pages import faq
result = faq(None, None) result = faq(None, None)
assert result == {} assert result == {}
def test_login(): def test_login():
''' test the view for the login form '''
from ordr.views.pages import login from ordr.views.pages import login
result = login(None, None) result = login(None, None)
assert result == {'loginerror': False} assert result == {'loginerror': False}
@ -38,6 +41,7 @@ def test_login():
'role', [Role.USER, Role.PURCHASER, Role.ADMIN] 'role', [Role.USER, Role.PURCHASER, Role.ADMIN]
) )
def test_check_login_ok(dbsession, role): def test_check_login_ok(dbsession, role):
''' test the processing of the login form with valid credentials '''
from ordr.views.pages import check_login from ordr.views.pages import check_login
user = get_example_user(role) user = get_example_user(role)
@ -54,6 +58,7 @@ def test_check_login_ok(dbsession, role):
'role', [Role.UNVALIDATED, Role.NEW, Role.INACTIVE] 'role', [Role.UNVALIDATED, Role.NEW, Role.INACTIVE]
) )
def test_check_login_not_activated(dbsession, role): def test_check_login_not_activated(dbsession, role):
''' test the processing of the login form with an inactive user '''
from ordr.views.pages import check_login from ordr.views.pages import check_login
user = get_example_user(role) user = get_example_user(role)
@ -75,6 +80,7 @@ def test_check_login_not_activated(dbsession, role):
] ]
) )
def test_check_login_invalid_credentials(dbsession, username, password): def test_check_login_invalid_credentials(dbsession, username, password):
''' test the processing of the login form with invalid credentials '''
from ordr.views.pages import check_login from ordr.views.pages import check_login
user = get_example_user(Role.USER) user = get_example_user(Role.USER)
@ -87,6 +93,7 @@ def test_check_login_invalid_credentials(dbsession, username, password):
def test_logout(): def test_logout():
''' test the logout view '''
from ordr.views.pages import logout from ordr.views.pages import logout
request = DummyRequest() request = DummyRequest()

7
tests/views/registration.py

@ -1,4 +1,3 @@
import pytest
import deform import deform
from pyramid.httpexceptions import HTTPFound from pyramid.httpexceptions import HTTPFound
@ -26,6 +25,7 @@ REGISTRATION_FORM_DATA = {
def test_registration_form(): def test_registration_form():
''' test the view for the registration form '''
from ordr.resources.account import RegistrationResource from ordr.resources.account import RegistrationResource
from ordr.schemas.account import RegistrationSchema from ordr.schemas.account import RegistrationSchema
from ordr.views.registration import registration_form from ordr.views.registration import registration_form
@ -41,6 +41,7 @@ def test_registration_form():
def test_registration_form_valid(dbsession): # noqa: F811 def test_registration_form_valid(dbsession): # noqa: F811
''' test processing the registration form with valid data '''
from ordr.models.account import User, Role, TokenSubject from ordr.models.account import User, Role, TokenSubject
from ordr.resources.account import RegistrationResource from ordr.resources.account import RegistrationResource
from ordr.views.registration import registration_form_processing from ordr.views.registration import registration_form_processing
@ -74,6 +75,7 @@ def test_registration_form_valid(dbsession): # noqa: F811
def test_registration_form_invalid(dbsession): # noqa: F811 def test_registration_form_invalid(dbsession): # noqa: F811
''' test processing registration form with invalid data '''
from ordr.views.registration import registration_form_processing from ordr.views.registration import registration_form_processing
from ordr.resources.account import RegistrationResource from ordr.resources.account import RegistrationResource
@ -88,6 +90,7 @@ def test_registration_form_invalid(dbsession): # noqa: F811
def test_registration_form_no_create_button(dbsession): # noqa: F811 def test_registration_form_no_create_button(dbsession): # noqa: F811
''' test processing registration form, create button not clicked '''
from ordr.views.registration import registration_form_processing from ordr.views.registration import registration_form_processing
from ordr.resources.account import RegistrationResource from ordr.resources.account import RegistrationResource
@ -102,12 +105,14 @@ def test_registration_form_no_create_button(dbsession): # noqa: F811
def test_registration_verify(): def test_registration_verify():
''' test the view displaying that a verifcation email has been sent '''
from ordr.views.registration import verify from ordr.views.registration import verify
result = verify(None, None) result = verify(None, None)
assert result == {} assert result == {}
def test_registration_completed(dbsession): # noqa: F811 def test_registration_completed(dbsession): # noqa: F811
''' test the view for the completed registration process '''
from ordr.models.account import User, Role, Token, TokenSubject from ordr.models.account import User, Role, Token, TokenSubject
from ordr.views.registration import completed from ordr.views.registration import completed