
8 changed files with 342 additions and 11 deletions
@ -0,0 +1,194 @@ |
|||||||
|
from collections import namedtuple |
||||||
|
|
||||||
|
import pytest |
||||||
|
from sqlalchemy.orm import clear_mappers |
||||||
|
|
||||||
|
from ordr3.views import RE_SIMPLE_URL |
||||||
|
|
||||||
|
ParsedMail = namedtuple("ParsedMail", ["body", "link"]) |
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture |
||||||
|
def _pyramid_app(): |
||||||
|
from ordr3 import main |
||||||
|
|
||||||
|
config = { |
||||||
|
"pyramid.includes": ["pyramid_debugtoolbar", "pyramid_mailer.testing"], |
||||||
|
"sqlalchemy.url": "sqlite:///:memory:", |
||||||
|
"retry.attempts": "3", |
||||||
|
"auth.secret": "change me for production", |
||||||
|
"session.secret": "change me for production", |
||||||
|
"session.auto_csrf": "true", |
||||||
|
"static_views.cache_max_age": "0", |
||||||
|
"mail.host": "localhost", |
||||||
|
"mail.port": "2525", |
||||||
|
"mail.default_sender": "ordr@example.com", |
||||||
|
"jinja2.filters ": [ |
||||||
|
"resource_url = pyramid_jinja2.filters:resource_url_filter", |
||||||
|
"as_date = ordr3.views:jinja_date", |
||||||
|
"as_time = ordr3.views:jinja_time", |
||||||
|
"as_datetime = ordr3.views:jinja_datetime", |
||||||
|
"view_comment = ordr3.views:jinja_view_comment", |
||||||
|
"extract_links = ordr3.views:jinja_extract_links", |
||||||
|
"nl2br = ordr3.views:jinja_nl2br", |
||||||
|
], |
||||||
|
} |
||||||
|
|
||||||
|
yield main({}, **config) |
||||||
|
clear_mappers() |
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture |
||||||
|
def _sqlite_repo(_pyramid_app): |
||||||
|
from pyramid.scripting import prepare |
||||||
|
from ordr3 import adapters |
||||||
|
|
||||||
|
with prepare() as env: |
||||||
|
with env["request"].tm: |
||||||
|
repo = env["root"].request.repo |
||||||
|
adapters.metadata.create_all(repo.session.get_bind()) |
||||||
|
yield repo |
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture |
||||||
|
def _example_data(_sqlite_repo): |
||||||
|
from ordr3 import models, security |
||||||
|
from datetime import datetime, timedelta |
||||||
|
|
||||||
|
today = datetime.utcnow() |
||||||
|
|
||||||
|
crypt_context = security.get_passlib_context() |
||||||
|
|
||||||
|
user = models.User( |
||||||
|
1, |
||||||
|
"TestUser", |
||||||
|
"Jon", |
||||||
|
"Smith", |
||||||
|
"jon@example.com", |
||||||
|
crypt_context.hash("jon"), |
||||||
|
models.UserRole.USER, |
||||||
|
) |
||||||
|
_sqlite_repo.add_user(user) |
||||||
|
|
||||||
|
admin = models.User( |
||||||
|
2, |
||||||
|
"TestAdmin", |
||||||
|
"Jane", |
||||||
|
"Doe", |
||||||
|
"jane@example.com", |
||||||
|
crypt_context.hash("jane"), |
||||||
|
models.UserRole.ADMIN, |
||||||
|
) |
||||||
|
_sqlite_repo.add_user(admin) |
||||||
|
|
||||||
|
inactive = models.User( |
||||||
|
3, |
||||||
|
"TestInactive", |
||||||
|
"Peter", |
||||||
|
"Peter", |
||||||
|
"peter@example.com", |
||||||
|
crypt_context.hash("peter"), |
||||||
|
models.UserRole.INACTIVE, |
||||||
|
) |
||||||
|
_sqlite_repo.add_user(inactive) |
||||||
|
|
||||||
|
order_1 = models.OrderItem( |
||||||
|
1, |
||||||
|
"Ethanol", |
||||||
|
"123", |
||||||
|
"VWR", |
||||||
|
models.OrderCategory.SOLVENT, |
||||||
|
"1 l", |
||||||
|
12.3, |
||||||
|
1, |
||||||
|
"EUR", |
||||||
|
"", |
||||||
|
"", |
||||||
|
) |
||||||
|
_sqlite_repo.add_order(order_1) |
||||||
|
log_entry = models.LogEntry( |
||||||
|
order_1.id, |
||||||
|
models.OrderStatus.COMPLETED, |
||||||
|
admin.username, |
||||||
|
today - timedelta(days=1), |
||||||
|
) |
||||||
|
order_1.add_to_log(log_entry) |
||||||
|
|
||||||
|
order_2 = models.OrderItem( |
||||||
|
2, |
||||||
|
"NaCl", |
||||||
|
"234", |
||||||
|
"Carl Roth", |
||||||
|
models.OrderCategory.CHEMICAL, |
||||||
|
"2 kg", |
||||||
|
23.4, |
||||||
|
2, |
||||||
|
"EUR", |
||||||
|
"Haushalt", |
||||||
|
"Kochsalz", |
||||||
|
) |
||||||
|
_sqlite_repo.add_order(order_2) |
||||||
|
log_entry = models.LogEntry( |
||||||
|
order_2.id, |
||||||
|
models.OrderStatus.APPROVAL, |
||||||
|
admin.username, |
||||||
|
today - timedelta(days=2), |
||||||
|
) |
||||||
|
order_2.add_to_log(log_entry) |
||||||
|
|
||||||
|
order_3 = models.OrderItem( |
||||||
|
3, |
||||||
|
"Eppis", |
||||||
|
"345", |
||||||
|
"VWR", |
||||||
|
models.OrderCategory.BIOLAB, |
||||||
|
"3 St", |
||||||
|
34.5, |
||||||
|
3, |
||||||
|
"USD", |
||||||
|
"Toto", |
||||||
|
"gefunden bei http://www.example.com/foo", |
||||||
|
) |
||||||
|
_sqlite_repo.add_order(order_3) |
||||||
|
log_entry = models.LogEntry( |
||||||
|
order_3.id, |
||||||
|
models.OrderStatus.COMPLETED, |
||||||
|
user.username, |
||||||
|
today - timedelta(days=3), |
||||||
|
) |
||||||
|
order_3.add_to_log(log_entry) |
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture |
||||||
|
def testapp(_pyramid_app, _example_data): |
||||||
|
from webtest import TestApp |
||||||
|
|
||||||
|
yield TestApp(_pyramid_app) |
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture |
||||||
|
def login_as(testapp): |
||||||
|
def _do_login(username, password): |
||||||
|
response = testapp.get("/login") |
||||||
|
form = response.form |
||||||
|
form["username"] = username |
||||||
|
form["password"] = password |
||||||
|
return form.submit("submit") |
||||||
|
|
||||||
|
yield _do_login |
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture |
||||||
|
def parse_latest_mail(testapp): |
||||||
|
from pyramid_mailer import get_mailer |
||||||
|
|
||||||
|
def _parse_mail(): |
||||||
|
registry = testapp.app.registry |
||||||
|
mailer = get_mailer(registry) |
||||||
|
last_mail = mailer.outbox[-1] |
||||||
|
body = last_mail.body |
||||||
|
links = RE_SIMPLE_URL.findall(body) |
||||||
|
link = links[0] if links else None |
||||||
|
return ParsedMail(body, link) |
||||||
|
|
||||||
|
yield _parse_mail |
@ -0,0 +1,45 @@ |
|||||||
|
def test_login_ok(testapp): |
||||||
|
response = testapp.get("/", status=302).follow(status=200) |
||||||
|
assert "Please Log In" in response |
||||||
|
|
||||||
|
form = response.form |
||||||
|
form["username"] = "TestAdmin" |
||||||
|
form["password"] = "jane" |
||||||
|
response = form.submit("submit").follow() |
||||||
|
assert "My Orders" in response |
||||||
|
|
||||||
|
|
||||||
|
def test_login_wrong_password(testapp): |
||||||
|
response = testapp.get("/", status=302).follow(status=200) |
||||||
|
assert "Please Log In" in response |
||||||
|
|
||||||
|
form = response.form |
||||||
|
form["username"] = "TestAdmin" |
||||||
|
form["password"] = "wrong password" |
||||||
|
response = form.submit("Log In") |
||||||
|
assert "Credentials are invalid" in response |
||||||
|
|
||||||
|
|
||||||
|
def test_login_fails_inactive_user(testapp): |
||||||
|
response = testapp.get("/", status=302).follow(status=200) |
||||||
|
assert "Please Log In" in response |
||||||
|
|
||||||
|
form = response.form |
||||||
|
form["username"] = "TestInactive" |
||||||
|
form["password"] = "peter" |
||||||
|
response = form.submit("Log In") |
||||||
|
assert "Credentials are invalid" in response |
||||||
|
|
||||||
|
|
||||||
|
def test_logout(testapp): |
||||||
|
response = testapp.get("/", status=302).follow(status=200) |
||||||
|
assert "Please Log In" in response |
||||||
|
|
||||||
|
form = response.form |
||||||
|
form["username"] = "TestAdmin" |
||||||
|
form["password"] = "jane" |
||||||
|
response = form.submit("submit").follow() |
||||||
|
assert "My Orders" in response |
||||||
|
|
||||||
|
response = testapp.get("/logout", status=302).follow(status=200) |
||||||
|
assert "Please Log In" in response |
@ -0,0 +1,42 @@ |
|||||||
|
def test_password_reset(testapp, parse_latest_mail): |
||||||
|
response = testapp.get("/", status=302).follow(status=200) |
||||||
|
assert "Please Log In" in response |
||||||
|
|
||||||
|
form = response.form |
||||||
|
form["username"] = "TestAdmin" |
||||||
|
form["password"] = "jixx" |
||||||
|
response = form.submit("Log In") |
||||||
|
assert "Credentials are invalid" in response |
||||||
|
|
||||||
|
response = testapp.get("/forgot", status=200) |
||||||
|
assert "Forgot your Password?" in response |
||||||
|
|
||||||
|
form = response.form |
||||||
|
form["email_or_username"] = "jane@example.com" |
||||||
|
response = form.submit("submit").follow() |
||||||
|
assert "An email for the password reset was sent" in response |
||||||
|
|
||||||
|
parsed = parse_latest_mail() |
||||||
|
assert "If you forgot your password" in parsed.body |
||||||
|
|
||||||
|
response = testapp.get(parsed.link) |
||||||
|
assert "You can now set a new password" in response |
||||||
|
|
||||||
|
form = response.form |
||||||
|
form["new_password"] = "jixx" |
||||||
|
response = form.submit("Reset Password").follow() |
||||||
|
assert "You changed your Password." in response |
||||||
|
|
||||||
|
response = testapp.get("/", status=302).follow(status=200) |
||||||
|
form = response.form |
||||||
|
form["username"] = "TestAdmin" |
||||||
|
form["password"] = "jane" |
||||||
|
response = form.submit("Log In") |
||||||
|
assert "Credentials are invalid" in response |
||||||
|
|
||||||
|
response = testapp.get("/", status=302).follow(status=200) |
||||||
|
form = response.form |
||||||
|
form["username"] = "TestAdmin" |
||||||
|
form["password"] = "jixx" |
||||||
|
response = form.submit("Log In").follow() |
||||||
|
assert "My Orders" in response |
@ -0,0 +1,43 @@ |
|||||||
|
def test_registration_procedure(testapp, login_as, parse_latest_mail): |
||||||
|
response = testapp.get("/", status=302).follow(status=200) |
||||||
|
assert "Please Log In" in response |
||||||
|
|
||||||
|
response = testapp.get("/registration", status=200) |
||||||
|
assert "Register a new account" in response |
||||||
|
|
||||||
|
form = response.form |
||||||
|
form["user_name"] = "TestNew" |
||||||
|
form["first_name"] = "Eric" |
||||||
|
form["last_name"] = "Idle" |
||||||
|
form["email"] = "eric@example.com" |
||||||
|
form["password"] = "eric" |
||||||
|
response = form.submit("Create account").follow() |
||||||
|
assert "The account needs to be activated" in response |
||||||
|
|
||||||
|
response = login_as("TestNew", "eric") |
||||||
|
assert "Credentials are invalid" in response |
||||||
|
|
||||||
|
login_as("TestAdmin", "jane") |
||||||
|
|
||||||
|
response = testapp.get("/users/?role=new", status=200) |
||||||
|
assert "TestNew" in response |
||||||
|
|
||||||
|
response = testapp.get("/users/TestNew/edit", status=200) |
||||||
|
assert "Edit User" in response |
||||||
|
|
||||||
|
form = response.forms[1] |
||||||
|
form["role"].select(text="User") |
||||||
|
response = form.submit("Save changes").follow() |
||||||
|
assert "TestNew" in response |
||||||
|
|
||||||
|
response = testapp.get("/users/?role=new", status=200) |
||||||
|
assert "TestNew" not in response |
||||||
|
|
||||||
|
response = testapp.get("/users/?role=user", status=200) |
||||||
|
assert "TestNew" in response |
||||||
|
|
||||||
|
parsed = parse_latest_mail() |
||||||
|
assert "Your account was activated" in parsed.body |
||||||
|
|
||||||
|
response = login_as("TestNew", "eric").follow() |
||||||
|
assert "My Orders" in response |
Loading…
Reference in new issue