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.
164 lines
5.4 KiB
164 lines
5.4 KiB
from datetime import datetime, timedelta |
|
|
|
import pytest |
|
|
|
from ordr3.repo import AbstractOrderRepository |
|
|
|
|
|
class FakeOrderRepository(AbstractOrderRepository): |
|
""" Repository implementation for testing """ |
|
|
|
def __init__(self, session): |
|
self._orders = set() |
|
self._users = set() |
|
|
|
def add_order(self, order): |
|
""" add an order to the datastore """ |
|
self._orders.add(order) |
|
|
|
def get_order(self, reference): |
|
""" retrieve an order from the datastore """ |
|
return next(o for o in self._orders if o.id == reference) |
|
|
|
def list_orders(self): |
|
return sorted(self._orders, reverse=True, key=lambda x: x.created_on) |
|
|
|
def add_user(self, user): |
|
""" add a user to the datastore """ |
|
self._users.add(user) |
|
|
|
def get_user(self, reference): |
|
""" retrieve a user from the datastore """ |
|
return next(o for o in self._users if o.id == reference) |
|
|
|
def get_user_by_username(self, reference): |
|
""" retrieve a user from the datastore by username """ |
|
return next(o for o in self._users if o.username == reference) |
|
|
|
def get_user_by_email(self, reference): |
|
""" retrieve a user from the datastore by email """ |
|
return next(o for o in self._users if o.email == reference) |
|
|
|
def list_users(self): |
|
return sorted(self._users, key=lambda x: x.username) |
|
|
|
|
|
class FakePasslibContext: |
|
def __init__(self, needs_update): |
|
self.needs_update = needs_update |
|
|
|
def verify_and_update(self, password, hash): |
|
if password != hash: |
|
return False, None |
|
if self.needs_update: |
|
return True, password[::-1] |
|
else: |
|
return True, None |
|
|
|
|
|
@pytest.fixture |
|
def prefilled_repo(): |
|
from itertools import count |
|
from ordr3.models import OrderItem, OrderStatus |
|
|
|
i = count() |
|
catalog = { |
|
1: "Ethanol", |
|
2: "Aceton", |
|
3: "NaOH", |
|
4: "Coffee", |
|
5: "Water", |
|
} |
|
|
|
def _create_order(item, date, status): |
|
order = OrderItem(next(i), catalog[item], item, "", "", "", "", "") |
|
order.created_on = date |
|
order.status = status |
|
return order |
|
|
|
month = timedelta(days=30) |
|
today = datetime.now() |
|
|
|
repo = FakeOrderRepository(session=None) |
|
# should be consumables |
|
repo.add_order(_create_order(1, today - month * 1, OrderStatus.ORDERED)) |
|
repo.add_order(_create_order(1, today - month * 2, OrderStatus.ORDERED)) |
|
repo.add_order(_create_order(1, today - month * 3, OrderStatus.COMPLETED)) |
|
repo.add_order(_create_order(2, today - month * 1, OrderStatus.ORDERED)) |
|
repo.add_order(_create_order(2, today - month * 2, OrderStatus.ORDERED)) |
|
repo.add_order(_create_order(2, today - month * 3, OrderStatus.COMPLETED)) |
|
# no consumable, only two repeats |
|
repo.add_order(_create_order(3, today - month * 1, OrderStatus.ORDERED)) |
|
repo.add_order(_create_order(3, today - month * 2, OrderStatus.ORDERED)) |
|
# no consumable, only two repeats in the last two years |
|
repo.add_order(_create_order(4, today - month * 1, OrderStatus.ORDERED)) |
|
repo.add_order(_create_order(4, today - month * 2, OrderStatus.ORDERED)) |
|
repo.add_order(_create_order(4, today - month * 50, OrderStatus.ORDERED)) |
|
# no consumable, one order on hold |
|
repo.add_order(_create_order(5, today - month * 1, OrderStatus.ORDERED)) |
|
repo.add_order(_create_order(5, today - month * 2, OrderStatus.ORDERED)) |
|
repo.add_order(_create_order(5, today - month * 3, OrderStatus.HOLD)) |
|
|
|
return repo |
|
|
|
|
|
def test_service_find_consumables(prefilled_repo): |
|
from ordr3.services import find_consumables |
|
|
|
result = find_consumables(prefilled_repo) |
|
|
|
assert len(result) == 2 |
|
assert [o.id for o in result] == [3, 0] |
|
|
|
|
|
def test_create_log_entry(prefilled_repo): |
|
from ordr3.services import create_log_entry |
|
from ordr3.models import OrderStatus, User |
|
|
|
order = prefilled_repo.get_order(1) |
|
user = User(*list("ABCDEFG")) |
|
|
|
create_log_entry(order, OrderStatus.APPROVAL, user) |
|
|
|
assert len(order.log) == 1 |
|
log_entry = order.log[0] |
|
assert log_entry.order_id == order.id |
|
assert log_entry.status == OrderStatus.APPROVAL |
|
assert log_entry.by == "B" |
|
assert log_entry.user_id == "A" |
|
assert isinstance(log_entry.date, datetime) |
|
assert order.status == log_entry.status |
|
assert order.created_by == log_entry.by |
|
assert order.created_on == log_entry.date |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"update,new_hash", [(False, "1234"), (True, "4321"),], # noqa: E231 |
|
) |
|
def test_verify_username_and_password_valid(update, new_hash): |
|
from ordr3.models import User, UserRole |
|
from ordr3.services import verify_credentials |
|
|
|
user = User(2, "Me", "Jane", "Doe", "jane.doe", "1234", UserRole.USER) |
|
repo = FakeOrderRepository(None) |
|
repo.add_user(user) |
|
pass_ctx = FakePasslibContext(update) |
|
|
|
user = verify_credentials(repo, pass_ctx, user.username, user.password) |
|
assert user is not None |
|
assert user.password == new_hash |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"name,pwd", [("You", "1234"), ("Me", "abcd"),], # noqa: E231 |
|
) |
|
def test_verify_username_and_password_invalid(name, pwd): |
|
from ordr3.models import User, UserRole |
|
from ordr3.services import verify_credentials |
|
|
|
user = User(2, "Me", "Jane", "Doe", "jane.doe", "1234", UserRole.USER) |
|
repo = FakeOrderRepository(None) |
|
repo.add_user(user) |
|
pass_ctx = FakePasslibContext(False) |
|
|
|
assert verify_credentials(repo, pass_ctx, name, pwd) is None
|
|
|