Holger Frey
7 years ago
29 changed files with 1011 additions and 48 deletions
@ -0,0 +1,16 @@ |
|||||||
|
{% extends "ordr:templates/layout.jinja2" %} |
||||||
|
|
||||||
|
{% block content %} |
||||||
|
<div class="row justify-content-md-center mt-3"> |
||||||
|
<div class="col-6"> |
||||||
|
<h1>Change Your Password</h1> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row justify-content-md-center"> |
||||||
|
<div class="col-6"> |
||||||
|
<h3>Your password was changed successfully</h3> |
||||||
|
<p class="mt-3">You can now log in with your new password.</p> |
||||||
|
<p>Happy <a href="{{ request.resource_url(request.root) }}">ordering</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock content %} |
@ -0,0 +1,14 @@ |
|||||||
|
{% extends "ordr:templates/layout.jinja2" %} |
||||||
|
|
||||||
|
{% block content %} |
||||||
|
<div class="row justify-content-md-center mt-3"> |
||||||
|
<div class="col-6"> |
||||||
|
<h1>Change Your Password</h1> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row justify-content-md-center"> |
||||||
|
<div class="col-6 mt-3"> |
||||||
|
{{ form.render()|safe }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock content %} |
@ -0,0 +1,14 @@ |
|||||||
|
{% extends "ordr:templates/layout.jinja2" %} |
||||||
|
|
||||||
|
{% block content %} |
||||||
|
<div class="row justify-content-md-center mt-3"> |
||||||
|
<div class="col-6"> |
||||||
|
<h1>Change Settings</h1> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row justify-content-md-center"> |
||||||
|
<div class="col-6 mt-3"> |
||||||
|
{{ form.render()|safe }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock content %} |
@ -0,0 +1,16 @@ |
|||||||
|
{% extends "ordr:templates/layout.jinja2" %} |
||||||
|
|
||||||
|
{% block content %} |
||||||
|
<div class="row justify-content-md-center mt-3"> |
||||||
|
<div class="col-6"> |
||||||
|
<h1>Change Settings</h1> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row justify-content-md-center"> |
||||||
|
<div class="col-6"> |
||||||
|
<h3>Your email was changed successfully</h3> |
||||||
|
<p class="mt-3">New notifications will be sent to {{request.user.email}}.</p> |
||||||
|
<p>Happy <a href="{{ request.resource_url(request.root) }}">ordering</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock content %} |
@ -0,0 +1,18 @@ |
|||||||
|
<span tal:define="name name|field.name; |
||||||
|
css_class css_class|field.widget.css_class; |
||||||
|
oid oid|field.oid; |
||||||
|
required required|'required' if field.required else None; |
||||||
|
mask mask|field.widget.mask; |
||||||
|
mask_placeholder mask_placeholder|field.widget.mask_placeholder; |
||||||
|
style style|field.widget.style; |
||||||
|
was_validated True if field.get_root().error else False; |
||||||
|
is_invalid is_invalid|field.error and not field.widget.hidden and not field.typ.__class__.__name__=='Mapping'; |
||||||
|
is_valid was_validated and not is_invalid; |
||||||
|
" |
||||||
|
tal:omit-tag=""> |
||||||
|
<input type="password" name="${name}" value="${cstruct}" |
||||||
|
tal:attributes="class string: form-control ${css_class or ''} ${'is-invalid' if is_invalid else ''} ${'is-valid' if is_valid else ''}; |
||||||
|
style style; |
||||||
|
required required" |
||||||
|
id="${oid}"/> |
||||||
|
</span> |
@ -0,0 +1,25 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
||||||
|
<title>[ordr] verify your new email address</title> |
||||||
|
<link href='http://fonts.googleapis.com/css?family=Anton&subset=latin,latin-ext' rel='stylesheet' type='text/css'> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<h1>Hi there!</h1> |
||||||
|
<p> |
||||||
|
Please verify your new email address for the account "{{ user.username }}" by following this link |
||||||
|
<a href="{{ request.resource_url(context, data.token.hash) }}">{{ request.resource_url(context, data.token.hash) }}</a> |
||||||
|
</p> |
||||||
|
<p> The link will expire on {{ data.token.expires.strftime('%d.%m.%y at %H:%M') }}. |
||||||
|
<p class="signature"> |
||||||
|
Regards, |
||||||
|
<br/> |
||||||
|
<span class="brand">ordr</span> |
||||||
|
</p> |
||||||
|
<p class="footprint"> |
||||||
|
<small>Please don't respont to this email! This is an automatically generated notification by the system.</small> |
||||||
|
<a href="http://distractedbysquirrels.com/" target="_blank" title="This software was originally written by Sebastian Sebald." class="icon-dbs"></a> |
||||||
|
</p> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,142 @@ |
|||||||
|
import deform |
||||||
|
|
||||||
|
from pyramid.httpexceptions import HTTPFound |
||||||
|
from pyramid.view import view_config |
||||||
|
|
||||||
|
from ordr.events import ChangeEmailNotification |
||||||
|
from ordr.models.account import TokenSubject |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context='ordr.resources.account.AccountResource', |
||||||
|
permission='edit' |
||||||
|
) |
||||||
|
def account(context, request): |
||||||
|
''' redirect if '/account' was requested directly ''' |
||||||
|
return HTTPFound(request.resource_url(request.root)) |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context='ordr.resources.account.AccountResource', |
||||||
|
permission='edit', |
||||||
|
name='settings', |
||||||
|
request_method='GET', |
||||||
|
renderer='ordr:templates/account/settings_form.jinja2' |
||||||
|
) |
||||||
|
def settings_form(context, request): |
||||||
|
''' show the settings form ''' |
||||||
|
prefill = { |
||||||
|
'username': request.user.username, |
||||||
|
'first_name': request.user.first_name, |
||||||
|
'last_name': request.user.last_name, |
||||||
|
'email': request.user.email, |
||||||
|
} |
||||||
|
form = context.get_settings_form(prefill=prefill) |
||||||
|
return {'form': form} |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context='ordr.resources.account.AccountResource', |
||||||
|
permission='edit', |
||||||
|
name='settings', |
||||||
|
request_method='POST', |
||||||
|
renderer='ordr:templates/account/settings_form.jinja2' |
||||||
|
) |
||||||
|
def settings_form_processing(context, request): |
||||||
|
''' process the settings form ''' |
||||||
|
if 'change' not in request.POST: |
||||||
|
return HTTPFound(request.resource_url(request.root)) |
||||||
|
|
||||||
|
form = context.get_settings_form() |
||||||
|
data = request.POST.items() |
||||||
|
try: |
||||||
|
appstruct = form.validate(data) |
||||||
|
except deform.ValidationFailure as e: |
||||||
|
return {'form': form} |
||||||
|
|
||||||
|
# form validation successfull, change user |
||||||
|
request.user.first_name = appstruct['first_name'] |
||||||
|
request.user.last_name = appstruct['last_name'] |
||||||
|
|
||||||
|
if appstruct['email'] == request.user.email: |
||||||
|
# email was not changed |
||||||
|
return HTTPFound(request.resource_url(request.root)) |
||||||
|
|
||||||
|
# create a verify-new-email token and send email |
||||||
|
token = request.user.issue_token( |
||||||
|
request, |
||||||
|
TokenSubject.CHANGE_EMAIL, |
||||||
|
payload={'email': appstruct['email']} |
||||||
|
) |
||||||
|
notification = ChangeEmailNotification( |
||||||
|
request, |
||||||
|
account, |
||||||
|
{'token': token}, |
||||||
|
send_to=appstruct['email'] |
||||||
|
) |
||||||
|
request.registry.notify(notification) |
||||||
|
|
||||||
|
return HTTPFound(request.resource_url(context, 'verify')) |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context='ordr.resources.account.ChangeEmailTokenResource', |
||||||
|
permission='edit', |
||||||
|
request_method='GET', |
||||||
|
renderer='ordr:templates/account/settings_mail_changed.jinja2' |
||||||
|
) |
||||||
|
def verify_email(context, request): |
||||||
|
''' show email verification text ''' |
||||||
|
payload = context.model.payload |
||||||
|
request.user.email = payload['email'] |
||||||
|
request.dbsession.delete(context.model) |
||||||
|
return {} |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context='ordr.resources.account.AccountResource', |
||||||
|
permission='edit', |
||||||
|
name='password', |
||||||
|
request_method='GET', |
||||||
|
renderer='ordr:templates/account/password_form.jinja2' |
||||||
|
) |
||||||
|
def password_form(context, request): |
||||||
|
''' show the change password form ''' |
||||||
|
form = context.get_password_form() |
||||||
|
return {'form': form} |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context='ordr.resources.account.AccountResource', |
||||||
|
permission='edit', |
||||||
|
name='password', |
||||||
|
request_method='POST', |
||||||
|
renderer='ordr:templates/account/password_form.jinja2' |
||||||
|
) |
||||||
|
def password_form_processing(context, request): |
||||||
|
''' process the change password form ''' |
||||||
|
if 'change' not in request.POST: |
||||||
|
return HTTPFound(request.resource_url(request.root)) |
||||||
|
|
||||||
|
form = context.get_password_form() |
||||||
|
data = request.POST.items() |
||||||
|
try: |
||||||
|
appstruct = form.validate(data) |
||||||
|
except deform.ValidationFailure as e: |
||||||
|
return {'form': form} |
||||||
|
|
||||||
|
# form validation successfull, change the password |
||||||
|
request.user.set_password(appstruct['password']) |
||||||
|
return HTTPFound(request.resource_url(context, 'changed')) |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context='ordr.resources.account.AccountResource', |
||||||
|
permission='edit', |
||||||
|
name='changed', |
||||||
|
request_method='GET', |
||||||
|
renderer='ordr:templates/account/password_changed.jinja2' |
||||||
|
) |
||||||
|
def password_changed(context, request): |
||||||
|
''' the password changed message ''' |
||||||
|
return {} |
@ -0,0 +1,132 @@ |
|||||||
|
''' functional tests for ordr2.views.account.py ''' |
||||||
|
|
||||||
|
from pyramid_mailer import get_mailer |
||||||
|
|
||||||
|
from . import testappsetup, testapp, get_token_url # noqa: F401 |
||||||
|
|
||||||
|
|
||||||
|
def test_account_root(testapp): # noqa: F811 |
||||||
|
''' check the redirect if '/account' is requested ''' |
||||||
|
testapp.login('TerryGilliam', 'Terry') |
||||||
|
response = testapp.get('/account') |
||||||
|
assert response.location == 'http://localhost/' |
||||||
|
|
||||||
|
|
||||||
|
def test_account_change_settings(testapp): # noqa: F811 |
||||||
|
testapp.login('TerryGilliam', 'Terry') |
||||||
|
|
||||||
|
response = testapp.get('/account/settings') |
||||||
|
active_nav = response.html.find('li', class_='active') |
||||||
|
assert active_nav is None |
||||||
|
assert 'Change Settings' in response |
||||||
|
assert 'value="gilliam@example.com"' in response |
||||||
|
assert 'Wrong Password' not in response |
||||||
|
|
||||||
|
# fill out the form without confirmation password |
||||||
|
form = response.form |
||||||
|
form['first_name'] = 'Amy' |
||||||
|
form['last_name'] = 'McDonald' |
||||||
|
response = form.submit(name='change') |
||||||
|
active_nav = response.html.find('li', class_='active') |
||||||
|
assert active_nav is None |
||||||
|
assert 'Change Settings' in response |
||||||
|
assert 'required' in response |
||||||
|
|
||||||
|
# fill out the form with invalid data but correct password |
||||||
|
response = testapp.get('/account/settings') |
||||||
|
form = response.form |
||||||
|
form['first_name'] = 'Amy' |
||||||
|
form['last_name'] = 'McDonald' |
||||||
|
form['email'] = 'this is not an email address' |
||||||
|
form['confirmation'] = 'Terry' |
||||||
|
response = form.submit(name='change') |
||||||
|
active_nav = response.html.find('li', class_='active') |
||||||
|
assert active_nav is None |
||||||
|
assert 'Change Settings' in response |
||||||
|
assert 'Invalid email address' in response |
||||||
|
|
||||||
|
# fill out the form with valid data and correct password |
||||||
|
response = testapp.get('/account/settings') |
||||||
|
form = response.form |
||||||
|
form['first_name'] = 'Amy' |
||||||
|
form['last_name'] = 'McDonald' |
||||||
|
form['confirmation'] = 'Terry' |
||||||
|
response = form.submit(name='change') |
||||||
|
assert response.location == 'http://localhost/' |
||||||
|
|
||||||
|
response = testapp.get('/account/settings') |
||||||
|
assert 'value="Amy"' in response |
||||||
|
|
||||||
|
|
||||||
|
def test_account_change_email(testapp): # noqa: F811 |
||||||
|
testapp.login('TerryGilliam', 'Terry') |
||||||
|
response = testapp.get('/account/settings') |
||||||
|
|
||||||
|
# fill out the form with valid data and correct password |
||||||
|
form = response.form |
||||||
|
form['email'] = 'amy@example.com' |
||||||
|
form['confirmation'] = 'Terry' |
||||||
|
response = form.submit(name='change') |
||||||
|
assert response.location == 'http://localhost/account/verify' |
||||||
|
|
||||||
|
# click the email verification token |
||||||
|
mailer = get_mailer(testapp.app.registry) |
||||||
|
email = mailer.outbox[-1] |
||||||
|
assert email.subject == '[ordr] Verify New Email Address' |
||||||
|
assert email.recipients == ['amy@example.com'] |
||||||
|
|
||||||
|
token_link = get_token_url(email, prefix='/account/') |
||||||
|
response = testapp.get(token_link) |
||||||
|
active_nav = response.html.find('li', class_='active') |
||||||
|
assert active_nav is None |
||||||
|
assert 'Change Settings' in response |
||||||
|
assert 'changed sucessfully' not in response |
||||||
|
|
||||||
|
|
||||||
|
def test_account_change_password(testapp): # noqa: F811 |
||||||
|
testapp.login('TerryGilliam', 'Terry') |
||||||
|
|
||||||
|
response = testapp.get('/account/password') |
||||||
|
active_nav = response.html.find('li', class_='active') |
||||||
|
assert active_nav is None |
||||||
|
assert 'Change Password' in response |
||||||
|
assert 'Wrong Password' not in response |
||||||
|
|
||||||
|
# fill out the form with incorrect confirmation password |
||||||
|
form = response.form |
||||||
|
form['password'] = 'Lost in La Mancha' |
||||||
|
form['password-confirm'] = 'Lost in La Mancha' |
||||||
|
form['confirmation'] = 'Unknown Password' |
||||||
|
response = form.submit(name='change') |
||||||
|
active_nav = response.html.find('li', class_='active') |
||||||
|
assert active_nav is None |
||||||
|
assert 'Change Password' in response |
||||||
|
assert 'Wrong password' in response |
||||||
|
|
||||||
|
# fill out the form with invalid data but correct password |
||||||
|
response = testapp.get('/account/password') |
||||||
|
form = response.form |
||||||
|
form['password'] = 'Lost in La Mancha' |
||||||
|
form['password-confirm'] = 'confirmation does not match' |
||||||
|
form['confirmation'] = 'Terry' |
||||||
|
response = form.submit(name='change') |
||||||
|
active_nav = response.html.find('li', class_='active') |
||||||
|
assert active_nav is None |
||||||
|
assert 'Change Password' in response |
||||||
|
assert 'Password did not match confirm' in response |
||||||
|
|
||||||
|
# fill out the form with valid data and correct password |
||||||
|
response = testapp.get('/account/password') |
||||||
|
form = response.form |
||||||
|
form['password'] = 'Lost in La Mancha' |
||||||
|
form['password-confirm'] = 'Lost in La Mancha' |
||||||
|
form['confirmation'] = 'Terry' |
||||||
|
response = form.submit(name='change') |
||||||
|
assert response.location == 'http://localhost/account/changed' |
||||||
|
|
||||||
|
response = response.follow() |
||||||
|
active_nav = response.html.find('li', class_='active') |
||||||
|
assert active_nav is None |
||||||
|
assert 'Your password was changed successfully' in response |
||||||
|
|
||||||
|
assert testapp.login('TerryGilliam', 'Lost in La Mancha') |
@ -0,0 +1,311 @@ |
|||||||
|
import deform |
||||||
|
|
||||||
|
from pyramid.httpexceptions import HTTPFound |
||||||
|
from pyramid.testing import DummyRequest, DummyResource |
||||||
|
|
||||||
|
from .. import ( # noqa: F401 |
||||||
|
app_config, |
||||||
|
dbsession, |
||||||
|
get_example_user, |
||||||
|
get_post_request |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
def test_account_redirect(): |
||||||
|
''' redirect on root of account resource ''' |
||||||
|
from ordr.views.account import account |
||||||
|
|
||||||
|
request = DummyRequest() |
||||||
|
result = account(None, request) |
||||||
|
|
||||||
|
assert isinstance(result, HTTPFound) |
||||||
|
assert result.location == 'http://example.com//' |
||||||
|
|
||||||
|
|
||||||
|
def test_settings_form(): |
||||||
|
''' tests for displaying the settings form ''' |
||||||
|
from ordr.models.account import Role |
||||||
|
from ordr.resources.account import AccountResource |
||||||
|
from ordr.schemas.account import SettingsSchema |
||||||
|
from ordr.views.account import settings_form |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
request = DummyRequest(user=user) |
||||||
|
parent = DummyResource(request=request) |
||||||
|
context = AccountResource(None, parent) |
||||||
|
result = settings_form(context, request) |
||||||
|
form = result['form'] |
||||||
|
|
||||||
|
assert isinstance(form, deform.Form) |
||||||
|
assert isinstance(form.schema, SettingsSchema) |
||||||
|
|
||||||
|
|
||||||
|
def test_settings_form_processing_valid_data(dbsession): # noqa: F811 |
||||||
|
''' tests for processing the settings form |
||||||
|
|
||||||
|
The data is valid, but no email change requested |
||||||
|
''' |
||||||
|
from ordr.models.account import Role, Token, User |
||||||
|
from ordr.resources.account import AccountResource |
||||||
|
from ordr.views.account import settings_form_processing |
||||||
|
|
||||||
|
data = { |
||||||
|
'username': 'TerryG', |
||||||
|
'first_name': 'Amy', |
||||||
|
'last_name': 'McDonald', |
||||||
|
'email': 'gilliam@example.com', |
||||||
|
'confirmation': 'Terry', |
||||||
|
'change': 'Change Settings' |
||||||
|
} |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
dbsession.add(user) |
||||||
|
dbsession.flush() |
||||||
|
request = get_post_request(data=data, dbsession=dbsession, user=user) |
||||||
|
parent = DummyResource(request=request) |
||||||
|
context = AccountResource(None, parent) |
||||||
|
request.context = context |
||||||
|
result = settings_form_processing(context, request) |
||||||
|
|
||||||
|
assert isinstance(result, HTTPFound) |
||||||
|
assert result.location == 'http://example.com//' |
||||||
|
|
||||||
|
account = dbsession.query(User).first() |
||||||
|
assert account.username == 'TerryGilliam' |
||||||
|
assert account.first_name == 'Amy' |
||||||
|
assert account.last_name == 'McDonald' |
||||||
|
assert account.email == 'gilliam@example.com' |
||||||
|
assert dbsession.query(Token).count() == 0 |
||||||
|
|
||||||
|
|
||||||
|
def test_settings_form_processing_mail_change(dbsession): # noqa: F811 |
||||||
|
''' tests for processing the settings form |
||||||
|
|
||||||
|
The data is valid and an email change is requested |
||||||
|
''' |
||||||
|
from ordr.models.account import Role, Token, TokenSubject, User |
||||||
|
from ordr.resources.account import AccountResource |
||||||
|
from ordr.views.account import settings_form_processing |
||||||
|
|
||||||
|
data = { |
||||||
|
'username': 'TerryG', |
||||||
|
'first_name': 'Amy', |
||||||
|
'last_name': 'McDonald', |
||||||
|
'email': 'amy@example.com', |
||||||
|
'confirmation': 'Terry', |
||||||
|
'change': 'Change Settings' |
||||||
|
} |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
dbsession.add(user) |
||||||
|
request = get_post_request(data=data, dbsession=dbsession, user=user) |
||||||
|
parent = DummyResource(request=request) |
||||||
|
context = AccountResource(None, parent) |
||||||
|
request.context = context |
||||||
|
result = settings_form_processing(context, request) |
||||||
|
|
||||||
|
assert isinstance(result, HTTPFound) |
||||||
|
assert result.location == 'http://example.com//verify' |
||||||
|
|
||||||
|
account = dbsession.query(User).first() |
||||||
|
assert account.username == 'TerryGilliam' |
||||||
|
assert account.first_name == 'Amy' |
||||||
|
assert account.last_name == 'McDonald' |
||||||
|
assert account.email == 'gilliam@example.com' |
||||||
|
|
||||||
|
token = dbsession.query(Token).first() |
||||||
|
assert token.subject == TokenSubject.CHANGE_EMAIL |
||||||
|
assert token.payload == {'email': 'amy@example.com'} |
||||||
|
|
||||||
|
# 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_settings_form_processing_invalid_data(dbsession): # noqa: F811 |
||||||
|
''' tests for processing the settings form with invalid data ''' |
||||||
|
from ordr.models.account import Role |
||||||
|
from ordr.resources.account import AccountResource |
||||||
|
from ordr.schemas.account import SettingsSchema |
||||||
|
from ordr.views.account import settings_form_processing |
||||||
|
|
||||||
|
data = { |
||||||
|
'username': 'TerryG', |
||||||
|
'first_name': 'Amy', |
||||||
|
'last_name': 'McDonald', |
||||||
|
'email': 'this is not an email address', |
||||||
|
'confirmation': 'Terry', |
||||||
|
'change': 'Change Settings' |
||||||
|
} |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
dbsession.add(user) |
||||||
|
request = get_post_request(data=data, dbsession=dbsession, user=user) |
||||||
|
parent = DummyResource(request=request) |
||||||
|
context = AccountResource(None, parent) |
||||||
|
request.context = context |
||||||
|
result = settings_form_processing(context, request) |
||||||
|
form = result['form'] |
||||||
|
|
||||||
|
assert isinstance(form, deform.Form) |
||||||
|
assert isinstance(form.schema, SettingsSchema) |
||||||
|
|
||||||
|
|
||||||
|
def test_settings_form_processing_cancel(dbsession): # noqa: F811 |
||||||
|
''' tests for processing the settings form with invalid data ''' |
||||||
|
from ordr.models.account import Role, User |
||||||
|
from ordr.resources.account import AccountResource |
||||||
|
from ordr.views.account import settings_form_processing |
||||||
|
|
||||||
|
data = { |
||||||
|
'username': 'TerryG', |
||||||
|
'first_name': 'Amy', |
||||||
|
'last_name': 'McDonald', |
||||||
|
'email': 'this is not an email address', |
||||||
|
'confirmation': 'Terry', |
||||||
|
'cancel': 'cancel' |
||||||
|
} |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
dbsession.add(user) |
||||||
|
request = get_post_request(data=data, dbsession=dbsession, user=user) |
||||||
|
parent = DummyResource(request=request) |
||||||
|
context = AccountResource(None, parent) |
||||||
|
request.context = context |
||||||
|
result = settings_form_processing(context, request) |
||||||
|
|
||||||
|
assert isinstance(result, HTTPFound) |
||||||
|
assert result.location == 'http://example.com//' |
||||||
|
|
||||||
|
account = dbsession.query(User).first() |
||||||
|
assert account.first_name == 'Terry' |
||||||
|
|
||||||
|
|
||||||
|
def test_verify_email(dbsession): # noqa: F811 |
||||||
|
''' tests for processing the change password form ''' |
||||||
|
from ordr.models.account import Role, Token, TokenSubject |
||||||
|
from ordr.views.account import verify_email |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
request = DummyRequest(dbsession=dbsession, user=user) |
||||||
|
|
||||||
|
user.issue_token( |
||||||
|
request, |
||||||
|
TokenSubject.CHANGE_EMAIL, |
||||||
|
{'email': 'amy@example.com'} |
||||||
|
) |
||||||
|
dbsession.add(user) |
||||||
|
dbsession.flush() |
||||||
|
token = dbsession.query(Token).first() |
||||||
|
context = DummyResource(model=token) |
||||||
|
|
||||||
|
result = verify_email(context, request) |
||||||
|
assert result == {} |
||||||
|
assert user.email == 'amy@example.com' |
||||||
|
assert dbsession.query(Token).count() == 0 |
||||||
|
|
||||||
|
|
||||||
|
def test_password_form(): |
||||||
|
''' tests for displaying the change password form ''' |
||||||
|
from ordr.models.account import Role |
||||||
|
from ordr.resources.account import AccountResource |
||||||
|
from ordr.schemas.account import ChangePasswordSchema |
||||||
|
from ordr.views.account import password_form |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
request = DummyRequest(user=user) |
||||||
|
parent = DummyResource(request=request) |
||||||
|
context = AccountResource(None, parent) |
||||||
|
result = password_form(context, request) |
||||||
|
form = result['form'] |
||||||
|
|
||||||
|
assert isinstance(form, deform.Form) |
||||||
|
assert isinstance(form.schema, ChangePasswordSchema) |
||||||
|
|
||||||
|
|
||||||
|
def test_password_form_processing_valid(dbsession): # noqa: F811 |
||||||
|
''' tests for processing the change password form ''' |
||||||
|
from ordr.models.account import Role |
||||||
|
from ordr.resources.account import AccountResource |
||||||
|
from ordr.views.account import password_form_processing |
||||||
|
|
||||||
|
data = { |
||||||
|
'__start__': 'password:mapping', |
||||||
|
'password': 'Make Amy McDonald A Rich Girl Fund', |
||||||
|
'password-confirm': 'Make Amy McDonald A Rich Girl Fund', |
||||||
|
'__end__': 'password:mapping', |
||||||
|
'confirmation': 'Terry', |
||||||
|
'change': 'Change Password' |
||||||
|
} |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
request = get_post_request(data=data, user=user) |
||||||
|
parent = DummyResource(request=request) |
||||||
|
context = AccountResource(None, parent) |
||||||
|
result = password_form_processing(context, request) |
||||||
|
|
||||||
|
assert isinstance(result, HTTPFound) |
||||||
|
assert result.location == 'http://example.com//changed' |
||||||
|
assert not user.check_password('Terry') |
||||||
|
assert user.check_password('Make Amy McDonald A Rich Girl Fund') |
||||||
|
|
||||||
|
|
||||||
|
def test_password_form_processing_invalid(dbsession): # noqa: F811 |
||||||
|
''' tests for processing the change password form ''' |
||||||
|
from ordr.models.account import Role |
||||||
|
from ordr.resources.account import AccountResource |
||||||
|
from ordr.schemas.account import ChangePasswordSchema |
||||||
|
from ordr.views.account import password_form_processing |
||||||
|
|
||||||
|
data = { |
||||||
|
'__start__': 'password:mapping', |
||||||
|
'password': 'Make Amy McDonald A Rich Girl Fund', |
||||||
|
'password-confirm': 'Make Amy McDonald A Rich Girl Fund', |
||||||
|
'__end__': 'password:mapping', |
||||||
|
'confirmation': 'not the right password for confirmation', |
||||||
|
'change': 'Change Password' |
||||||
|
} |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
request = get_post_request(data=data, user=user) |
||||||
|
parent = DummyResource(request=request) |
||||||
|
context = AccountResource(None, parent) |
||||||
|
result = password_form_processing(context, request) |
||||||
|
form = result['form'] |
||||||
|
|
||||||
|
assert isinstance(form, deform.Form) |
||||||
|
assert isinstance(form.schema, ChangePasswordSchema) |
||||||
|
assert user.check_password('Terry') |
||||||
|
|
||||||
|
|
||||||
|
def test_password_form_processing_cancel(dbsession): # noqa: F811 |
||||||
|
''' tests canceling the change password form ''' |
||||||
|
from ordr.models.account import Role |
||||||
|
from ordr.resources.account import AccountResource |
||||||
|
from ordr.views.account import password_form_processing |
||||||
|
|
||||||
|
data = { |
||||||
|
'__start__': 'password:mapping', |
||||||
|
'password': 'Make Amy McDonald A Rich Girl Fund', |
||||||
|
'password-confirm': 'Make Amy McDonald A Rich Girl Fund', |
||||||
|
'__end__': 'password:mapping', |
||||||
|
'confirmation': 'Terry', |
||||||
|
'cancel': 'cancel' |
||||||
|
} |
||||||
|
|
||||||
|
user = get_example_user(Role.USER) |
||||||
|
request = get_post_request(data=data, user=user) |
||||||
|
parent = DummyResource(request=request) |
||||||
|
context = AccountResource(None, parent) |
||||||
|
result = password_form_processing(context, request) |
||||||
|
|
||||||
|
assert isinstance(result, HTTPFound) |
||||||
|
assert result.location == 'http://example.com//' |
||||||
|
assert user.check_password('Terry') |
||||||
|
|
||||||
|
|
||||||
|
def test_password_changed(): |
||||||
|
''' show password has changed message ''' |
||||||
|
from ordr.views.account import password_changed |
||||||
|
result = password_changed(None, None) |
||||||
|
assert result == {} |
Reference in new issue