urban-meal-delivery/tests/db/fake_data/fixture_makers.py
Alexander Hess e4e543bd40
Add ORM models for the simulation data
- add new ORM models `ReplaySimulation` and `ReplayedOrder`
  to store the data generated by the routing simulations
- add migrations script to create the corresponding database tables
  + create "replay_simulations" and "replayed_orders" tables
  + add missing check constraints to "orders" table
  + add unique constraint to "orders" table to enable compound key
  + drop unnecessary check constraints from the "orders" table
- add tests for the new ORM models
  + add `simulation`, `replayed_order`, `make_replay_order()`, and
    `pre_order` fixtures
  + add `ReplayedOrderFactor` faker class
- fix some typos
2021-09-16 11:58:55 +02:00

143 lines
4.3 KiB
Python

"""Fixture factories for testing the ORM layer with fake data."""
import pytest
from tests.db.fake_data import factories
@pytest.fixture
def make_address(city):
"""Replaces `AddressFactory.build()`: Create an `Address` in the `city`."""
# Reset the identifiers before every test.
factories.AddressFactory.reset_sequence(1)
def func(**kwargs):
"""Create an `Address` object in the `city`."""
return factories.AddressFactory.build(city=city, **kwargs)
return func
@pytest.fixture
def make_courier():
"""Replaces `CourierFactory.build()`: Create a `Courier`."""
# Reset the identifiers before every test.
factories.CourierFactory.reset_sequence(1)
def func(**kwargs):
"""Create a new `Courier` object."""
return factories.CourierFactory.build(**kwargs)
return func
@pytest.fixture
def make_customer():
"""Replaces `CustomerFactory.build()`: Create a `Customer`."""
# Reset the identifiers before every test.
factories.CustomerFactory.reset_sequence(1)
def func(**kwargs):
"""Create a new `Customer` object."""
return factories.CustomerFactory.build(**kwargs)
return func
@pytest.fixture
def make_restaurant(make_address):
"""Replaces `RestaurantFactory.build()`: Create a `Restaurant`."""
# Reset the identifiers before every test.
factories.RestaurantFactory.reset_sequence(1)
def func(address=None, **kwargs):
"""Create a new `Restaurant` object.
If no `address` is provided, a new `Address` is created.
"""
if address is None:
address = make_address()
return factories.RestaurantFactory.build(address=address, **kwargs)
return func
@pytest.fixture
def make_order(make_address, make_courier, make_customer, make_restaurant):
"""Replaces `OrderFactory.build()`: Create a `Order`."""
# Reset the identifiers before every test.
factories.AdHocOrderFactory.reset_sequence(1)
def func(scheduled=False, restaurant=None, courier=None, **kwargs):
"""Create a new `Order` object.
Each `Order` is made by a new `Customer` with a unique `Address` for delivery.
Args:
scheduled: if an `Order` is a pre-order
restaurant: who receives the `Order`; defaults to a new `Restaurant`
courier: who delivered the `Order`; defaults to a new `Courier`
kwargs: additional keyword arguments forwarded to the `OrderFactory`
Returns:
order
"""
if scheduled:
factory_cls = factories.ScheduledOrderFactory
else:
factory_cls = factories.AdHocOrderFactory
if restaurant is None:
restaurant = make_restaurant()
if courier is None:
courier = make_courier()
return factory_cls.build(
customer=make_customer(), # assume a unique `Customer` per order
restaurant=restaurant,
courier=courier,
pickup_address=restaurant.address, # no `Address` history
delivery_address=make_address(), # unique `Customer` => new `Address`
**kwargs,
)
return func
@pytest.fixture
def make_replay_order(make_order, simulation):
"""Replaces `ReplayedOrderFactory.build()`: Create a `ReplayedOrder`."""
# Reset the identifiers before every test.
factories.ReplayedOrderFactory.reset_sequence(1)
def func(scheduled=False, order=None, **kwargs):
"""Create a new `ReplayedOrder` object.
Each `ReplayOrder` is made by a new `Customer` with a unique `Address`.
Args:
scheduled: if an `Order` is a pre-order
order: the `Order` that is replayed
kwargs: keyword arguments forwarded to the `ReplayedOrderFactory`
Returns:
order
Raises:
RuntimeError: if `scheduled=True` is passed in
together with an ad-hoc `order`
"""
if scheduled:
if order and order.ad_hoc is False:
raise RuntimeError('`order` must be scheduled')
elif order is None:
order = make_order(scheduled=True)
elif order is None:
order = make_order()
return factories.ReplayedOrderFactory.build(
simulation=simulation, actual=order, courier=order.courier, **kwargs,
)
return func