Files
g2s-aggregator/tests/repositories/order/test_repository.py
T
2026-04-18 00:33:45 +03:00

146 lines
4.9 KiB
Python

import asyncio
from collections.abc import Awaitable, Callable
from typing import Any
import pytest
from sqlalchemy import select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from sqlalchemy.ext.asyncio import create_async_engine
from app.repositories.order import OrderData, OrderRepository
from app.repositories.order.models import Base, Order
def _make_order_data(**overrides: object) -> OrderData:
payload: dict[str, Any] = {
"order_uuid": "order-uuid-1",
"payment_url": "https://pay.test/payment/1",
"price": 125000,
"delivery_type": 2,
"tariff_code": 535,
"comment": "Test payment",
"sender": {
"name": "Petr Petrov",
"email": "sender@example.com",
"phone": {"number": "+79009876543"},
},
"recipient": {
"name": "Ivan Ivanov",
"email": "ivan@example.com",
"phone": {"number": "+79001234567"},
},
"from_location": {
"address": "Lenina 1",
"city": "Moscow",
"country_code": "RU",
},
"to_location": {
"address": "Pushkina 10",
"city": "Novosibirsk",
"country_code": "RU",
},
"services": [{"code": "INSURANCE", "parameter": "1000"}],
"packages": [
{
"number": "1",
"weight": 1,
"length": 20,
"width": 15,
"height": 10,
"comment": "Package 1",
}
],
}
payload.update(overrides)
return OrderData(**payload)
async def _with_repository(
test_fn: Callable[
[OrderRepository, async_sessionmaker[AsyncSession]],
Awaitable[None],
],
) -> None:
engine = create_async_engine("sqlite+aiosqlite:///:memory:")
try:
async with engine.begin() as connection:
await connection.run_sync(Base.metadata.create_all)
session_factory = async_sessionmaker(engine, expire_on_commit=False)
await test_fn(OrderRepository(session_factory=session_factory), session_factory)
finally:
await engine.dispose()
def test_create_order_persists_all_required_fields() -> None:
async def run(
repository: OrderRepository,
session_factory: async_sessionmaker[AsyncSession],
) -> None:
order_data = _make_order_data()
async with repository.session() as session:
order = await repository.create_order(session, order_data)
async with session_factory() as session:
result = await session.execute(
select(Order).where(Order.order_uuid == "order-uuid-1")
)
persisted_order = result.scalar_one()
assert order.id == persisted_order.id
assert persisted_order.order_uuid == "order-uuid-1"
assert persisted_order.payment_url == "https://pay.test/payment/1"
assert persisted_order.price == 125000
assert persisted_order.delivery_type == 2
assert persisted_order.tariff_code == 535
assert persisted_order.sender == order_data.sender
assert persisted_order.recipient == order_data.recipient
assert persisted_order.from_location == order_data.from_location
assert persisted_order.to_location == order_data.to_location
assert persisted_order.packages == order_data.packages
assert persisted_order.services == order_data.services
assert persisted_order.comment == "Test payment"
assert persisted_order.created_at is not None
asyncio.run(_with_repository(run))
def test_create_order_persists_nullable_services_and_comment() -> None:
async def run(
repository: OrderRepository,
session_factory: async_sessionmaker[AsyncSession],
) -> None:
order_data = _make_order_data(services=None, comment=None)
async with repository.session() as session:
await repository.create_order(session, order_data)
async with session_factory() as session:
result = await session.execute(
select(Order).where(Order.order_uuid == "order-uuid-1")
)
persisted_order = result.scalar_one()
assert persisted_order.services is None
assert persisted_order.comment is None
asyncio.run(_with_repository(run))
def test_create_order_rejects_duplicate_order_uuid() -> None:
async def run(
repository: OrderRepository,
_session_factory: async_sessionmaker[AsyncSession],
) -> None:
order_data = _make_order_data()
async with repository.session() as session:
await repository.create_order(session, order_data)
with pytest.raises(IntegrityError):
async with repository.session() as session:
await repository.create_order(session, order_data)
asyncio.run(_with_repository(run))