Files
orion/tests/unit/models/schema/test_order.py
Samir Boulahtit ca9f17fc37 refactor: split database model tests into organized modules
Split the monolithic test_database_models.py into focused test modules:

Database model tests (tests/unit/models/database/):
- test_customer.py: Customer model and authentication tests
- test_inventory.py: Inventory model tests
- test_marketplace_import_job.py: Import job model tests
- test_marketplace_product.py: Marketplace product model tests
- test_order.py: Order and OrderItem model tests
- test_product.py: Product model tests
- test_team.py: Team invitation and membership tests
- test_user.py: User model tests
- test_vendor.py: Vendor model tests

Schema validation tests (tests/unit/models/schema/):
- test_auth.py: Auth schema validation tests
- test_customer.py: Customer schema validation tests
- test_inventory.py: Inventory schema validation tests
- test_marketplace_import_job.py: Import job schema tests
- test_order.py: Order schema validation tests
- test_product.py: Product schema validation tests

This improves test organization and makes it easier to find
and maintain tests for specific models.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 21:42:26 +01:00

367 lines
12 KiB
Python

# tests/unit/models/schema/test_order.py
"""Unit tests for order Pydantic schemas."""
import pytest
from pydantic import ValidationError
from models.schema.order import (
OrderItemCreate,
OrderItemResponse,
OrderAddressCreate,
OrderAddressResponse,
OrderCreate,
OrderUpdate,
OrderResponse,
OrderDetailResponse,
OrderListResponse,
)
@pytest.mark.unit
@pytest.mark.schema
class TestOrderItemCreateSchema:
"""Test OrderItemCreate schema validation."""
def test_valid_order_item(self):
"""Test valid order item creation."""
item = OrderItemCreate(
product_id=1,
quantity=2,
)
assert item.product_id == 1
assert item.quantity == 2
def test_product_id_required(self):
"""Test product_id is required."""
with pytest.raises(ValidationError) as exc_info:
OrderItemCreate(quantity=2)
assert "product_id" in str(exc_info.value).lower()
def test_quantity_required(self):
"""Test quantity is required."""
with pytest.raises(ValidationError) as exc_info:
OrderItemCreate(product_id=1)
assert "quantity" in str(exc_info.value).lower()
def test_quantity_must_be_at_least_1(self):
"""Test quantity must be >= 1."""
with pytest.raises(ValidationError) as exc_info:
OrderItemCreate(
product_id=1,
quantity=0,
)
assert "quantity" in str(exc_info.value).lower()
def test_negative_quantity_invalid(self):
"""Test negative quantity is invalid."""
with pytest.raises(ValidationError):
OrderItemCreate(
product_id=1,
quantity=-1,
)
@pytest.mark.unit
@pytest.mark.schema
class TestOrderAddressCreateSchema:
"""Test OrderAddressCreate schema validation."""
def test_valid_address(self):
"""Test valid order address creation."""
address = OrderAddressCreate(
first_name="John",
last_name="Doe",
address_line_1="123 Main St",
city="Luxembourg",
postal_code="L-1234",
country="Luxembourg",
)
assert address.first_name == "John"
assert address.city == "Luxembourg"
def test_required_fields(self):
"""Test required fields validation."""
with pytest.raises(ValidationError):
OrderAddressCreate(
first_name="John",
# missing required fields
)
def test_optional_company(self):
"""Test optional company field."""
address = OrderAddressCreate(
first_name="John",
last_name="Doe",
company="Tech Corp",
address_line_1="123 Main St",
city="Luxembourg",
postal_code="L-1234",
country="Luxembourg",
)
assert address.company == "Tech Corp"
def test_optional_address_line_2(self):
"""Test optional address_line_2 field."""
address = OrderAddressCreate(
first_name="John",
last_name="Doe",
address_line_1="123 Main St",
address_line_2="Suite 500",
city="Luxembourg",
postal_code="L-1234",
country="Luxembourg",
)
assert address.address_line_2 == "Suite 500"
def test_first_name_min_length(self):
"""Test first_name minimum length."""
with pytest.raises(ValidationError):
OrderAddressCreate(
first_name="",
last_name="Doe",
address_line_1="123 Main St",
city="Luxembourg",
postal_code="L-1234",
country="Luxembourg",
)
def test_country_min_length(self):
"""Test country minimum length (2)."""
with pytest.raises(ValidationError):
OrderAddressCreate(
first_name="John",
last_name="Doe",
address_line_1="123 Main St",
city="Luxembourg",
postal_code="L-1234",
country="L",
)
@pytest.mark.unit
@pytest.mark.schema
class TestOrderCreateSchema:
"""Test OrderCreate schema validation."""
def test_valid_order(self):
"""Test valid order creation."""
order = OrderCreate(
items=[
OrderItemCreate(product_id=1, quantity=2),
OrderItemCreate(product_id=2, quantity=1),
],
shipping_address=OrderAddressCreate(
first_name="John",
last_name="Doe",
address_line_1="123 Main St",
city="Luxembourg",
postal_code="L-1234",
country="Luxembourg",
),
)
assert len(order.items) == 2
assert order.customer_id is None # Optional for guest checkout
def test_items_required(self):
"""Test items are required."""
with pytest.raises(ValidationError) as exc_info:
OrderCreate(
shipping_address=OrderAddressCreate(
first_name="John",
last_name="Doe",
address_line_1="123 Main St",
city="Luxembourg",
postal_code="L-1234",
country="Luxembourg",
),
)
assert "items" in str(exc_info.value).lower()
def test_items_must_not_be_empty(self):
"""Test items list must have at least 1 item."""
with pytest.raises(ValidationError) as exc_info:
OrderCreate(
items=[],
shipping_address=OrderAddressCreate(
first_name="John",
last_name="Doe",
address_line_1="123 Main St",
city="Luxembourg",
postal_code="L-1234",
country="Luxembourg",
),
)
assert "items" in str(exc_info.value).lower()
def test_shipping_address_required(self):
"""Test shipping_address is required."""
with pytest.raises(ValidationError) as exc_info:
OrderCreate(
items=[OrderItemCreate(product_id=1, quantity=1)],
)
assert "shipping_address" in str(exc_info.value).lower()
def test_optional_billing_address(self):
"""Test billing_address is optional."""
order = OrderCreate(
items=[OrderItemCreate(product_id=1, quantity=1)],
shipping_address=OrderAddressCreate(
first_name="John",
last_name="Doe",
address_line_1="123 Main St",
city="Luxembourg",
postal_code="L-1234",
country="Luxembourg",
),
billing_address=OrderAddressCreate(
first_name="Jane",
last_name="Doe",
address_line_1="456 Other St",
city="Esch",
postal_code="L-4321",
country="Luxembourg",
),
)
assert order.billing_address is not None
assert order.billing_address.first_name == "Jane"
def test_optional_customer_notes(self):
"""Test optional customer_notes."""
order = OrderCreate(
items=[OrderItemCreate(product_id=1, quantity=1)],
shipping_address=OrderAddressCreate(
first_name="John",
last_name="Doe",
address_line_1="123 Main St",
city="Luxembourg",
postal_code="L-1234",
country="Luxembourg",
),
customer_notes="Please leave at door",
)
assert order.customer_notes == "Please leave at door"
@pytest.mark.unit
@pytest.mark.schema
class TestOrderUpdateSchema:
"""Test OrderUpdate schema validation."""
def test_status_update(self):
"""Test valid status update."""
update = OrderUpdate(status="processing")
assert update.status == "processing"
def test_valid_status_values(self):
"""Test all valid status values."""
valid_statuses = ["pending", "processing", "shipped", "delivered", "cancelled", "refunded"]
for status in valid_statuses:
update = OrderUpdate(status=status)
assert update.status == status
def test_invalid_status(self):
"""Test invalid status raises ValidationError."""
with pytest.raises(ValidationError) as exc_info:
OrderUpdate(status="invalid_status")
assert "status" in str(exc_info.value).lower()
def test_tracking_number_update(self):
"""Test tracking number update."""
update = OrderUpdate(tracking_number="TRACK123456")
assert update.tracking_number == "TRACK123456"
def test_internal_notes_update(self):
"""Test internal notes update."""
update = OrderUpdate(internal_notes="Customer requested expedited shipping")
assert update.internal_notes == "Customer requested expedited shipping"
def test_empty_update_is_valid(self):
"""Test empty update is valid."""
update = OrderUpdate()
assert update.model_dump(exclude_unset=True) == {}
@pytest.mark.unit
@pytest.mark.schema
class TestOrderResponseSchema:
"""Test OrderResponse schema."""
def test_from_dict(self):
"""Test creating response from dict."""
from datetime import datetime
data = {
"id": 1,
"vendor_id": 1,
"customer_id": 1,
"order_number": "ORD-001",
"status": "pending",
"subtotal": 100.00,
"tax_amount": 20.00,
"shipping_amount": 10.00,
"discount_amount": 5.00,
"total_amount": 125.00,
"currency": "EUR",
"shipping_method": "standard",
"tracking_number": None,
"customer_notes": None,
"internal_notes": None,
"created_at": datetime.now(),
"updated_at": datetime.now(),
"paid_at": None,
"shipped_at": None,
"delivered_at": None,
"cancelled_at": None,
}
response = OrderResponse(**data)
assert response.id == 1
assert response.order_number == "ORD-001"
assert response.total_amount == 125.00
@pytest.mark.unit
@pytest.mark.schema
class TestOrderItemResponseSchema:
"""Test OrderItemResponse schema."""
def test_from_dict(self):
"""Test creating response from dict."""
from datetime import datetime
data = {
"id": 1,
"order_id": 1,
"product_id": 1,
"product_name": "Test Product",
"product_sku": "SKU-001",
"quantity": 2,
"unit_price": 50.00,
"total_price": 100.00,
"inventory_reserved": True,
"inventory_fulfilled": False,
"created_at": datetime.now(),
"updated_at": datetime.now(),
}
response = OrderItemResponse(**data)
assert response.id == 1
assert response.quantity == 2
assert response.total_price == 100.00
@pytest.mark.unit
@pytest.mark.schema
class TestOrderListResponseSchema:
"""Test OrderListResponse schema."""
def test_valid_list_response(self):
"""Test valid list response structure."""
response = OrderListResponse(
orders=[],
total=0,
skip=0,
limit=10,
)
assert response.orders == []
assert response.total == 0
assert response.skip == 0
assert response.limit == 10