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>
This commit is contained in:
2
tests/unit/models/database/__init__.py
Normal file
2
tests/unit/models/database/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# tests/unit/models/database/__init__.py
|
||||
"""Database model unit tests."""
|
||||
240
tests/unit/models/database/test_customer.py
Normal file
240
tests/unit/models/database/test_customer.py
Normal file
@@ -0,0 +1,240 @@
|
||||
# tests/unit/models/database/test_customer.py
|
||||
"""Unit tests for Customer and CustomerAddress database models."""
|
||||
import pytest
|
||||
|
||||
from models.database.customer import Customer, CustomerAddress
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestCustomerModel:
|
||||
"""Test Customer model."""
|
||||
|
||||
def test_customer_creation(self, db, test_vendor):
|
||||
"""Test Customer model with vendor isolation."""
|
||||
customer = Customer(
|
||||
vendor_id=test_vendor.id,
|
||||
email="customer@example.com",
|
||||
hashed_password="hashed_password",
|
||||
first_name="John",
|
||||
last_name="Doe",
|
||||
customer_number="CUST001",
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
db.add(customer)
|
||||
db.commit()
|
||||
db.refresh(customer)
|
||||
|
||||
assert customer.id is not None
|
||||
assert customer.vendor_id == test_vendor.id
|
||||
assert customer.email == "customer@example.com"
|
||||
assert customer.customer_number == "CUST001"
|
||||
assert customer.first_name == "John"
|
||||
assert customer.last_name == "Doe"
|
||||
assert customer.vendor.vendor_code == test_vendor.vendor_code
|
||||
|
||||
def test_customer_default_values(self, db, test_vendor):
|
||||
"""Test Customer model default values."""
|
||||
customer = Customer(
|
||||
vendor_id=test_vendor.id,
|
||||
email="defaults@example.com",
|
||||
hashed_password="hash",
|
||||
customer_number="CUST_DEFAULTS",
|
||||
)
|
||||
db.add(customer)
|
||||
db.commit()
|
||||
db.refresh(customer)
|
||||
|
||||
assert customer.is_active is True # Default
|
||||
assert customer.marketing_consent is False # Default
|
||||
assert customer.total_orders == 0 # Default
|
||||
assert customer.total_spent == 0 # Default
|
||||
|
||||
def test_customer_full_name_property(self, db, test_vendor):
|
||||
"""Test Customer full_name computed property."""
|
||||
customer = Customer(
|
||||
vendor_id=test_vendor.id,
|
||||
email="fullname@example.com",
|
||||
hashed_password="hash",
|
||||
customer_number="CUST_FULLNAME",
|
||||
first_name="Jane",
|
||||
last_name="Smith",
|
||||
)
|
||||
db.add(customer)
|
||||
db.commit()
|
||||
db.refresh(customer)
|
||||
|
||||
assert customer.full_name == "Jane Smith"
|
||||
|
||||
def test_customer_full_name_fallback_to_email(self, db, test_vendor):
|
||||
"""Test Customer full_name falls back to email when names not set."""
|
||||
customer = Customer(
|
||||
vendor_id=test_vendor.id,
|
||||
email="noname@example.com",
|
||||
hashed_password="hash",
|
||||
customer_number="CUST_NONAME",
|
||||
)
|
||||
db.add(customer)
|
||||
db.commit()
|
||||
db.refresh(customer)
|
||||
|
||||
assert customer.full_name == "noname@example.com"
|
||||
|
||||
def test_customer_optional_fields(self, db, test_vendor):
|
||||
"""Test Customer with optional fields."""
|
||||
customer = Customer(
|
||||
vendor_id=test_vendor.id,
|
||||
email="optional@example.com",
|
||||
hashed_password="hash",
|
||||
customer_number="CUST_OPT",
|
||||
phone="+352123456789",
|
||||
preferences={"language": "en", "currency": "EUR"},
|
||||
marketing_consent=True,
|
||||
)
|
||||
db.add(customer)
|
||||
db.commit()
|
||||
db.refresh(customer)
|
||||
|
||||
assert customer.phone == "+352123456789"
|
||||
assert customer.preferences == {"language": "en", "currency": "EUR"}
|
||||
assert customer.marketing_consent is True
|
||||
|
||||
def test_customer_vendor_relationship(self, db, test_vendor):
|
||||
"""Test Customer-Vendor relationship."""
|
||||
customer = Customer(
|
||||
vendor_id=test_vendor.id,
|
||||
email="relationship@example.com",
|
||||
hashed_password="hash",
|
||||
customer_number="CUST_REL",
|
||||
)
|
||||
db.add(customer)
|
||||
db.commit()
|
||||
db.refresh(customer)
|
||||
|
||||
assert customer.vendor is not None
|
||||
assert customer.vendor.id == test_vendor.id
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestCustomerAddressModel:
|
||||
"""Test CustomerAddress model."""
|
||||
|
||||
def test_customer_address_creation(self, db, test_vendor, test_customer):
|
||||
"""Test CustomerAddress model."""
|
||||
address = CustomerAddress(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
address_type="shipping",
|
||||
first_name="John",
|
||||
last_name="Doe",
|
||||
address_line_1="123 Main St",
|
||||
city="Luxembourg",
|
||||
postal_code="L-1234",
|
||||
country="Luxembourg",
|
||||
is_default=True,
|
||||
)
|
||||
|
||||
db.add(address)
|
||||
db.commit()
|
||||
db.refresh(address)
|
||||
|
||||
assert address.id is not None
|
||||
assert address.vendor_id == test_vendor.id
|
||||
assert address.customer_id == test_customer.id
|
||||
assert address.address_type == "shipping"
|
||||
assert address.is_default is True
|
||||
|
||||
def test_customer_address_types(self, db, test_vendor, test_customer):
|
||||
"""Test CustomerAddress with different address types."""
|
||||
shipping_address = CustomerAddress(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
address_type="shipping",
|
||||
first_name="John",
|
||||
last_name="Doe",
|
||||
address_line_1="123 Shipping St",
|
||||
city="Luxembourg",
|
||||
postal_code="L-1234",
|
||||
country="Luxembourg",
|
||||
)
|
||||
db.add(shipping_address)
|
||||
|
||||
billing_address = CustomerAddress(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
address_type="billing",
|
||||
first_name="John",
|
||||
last_name="Doe",
|
||||
address_line_1="456 Billing Ave",
|
||||
city="Luxembourg",
|
||||
postal_code="L-5678",
|
||||
country="Luxembourg",
|
||||
)
|
||||
db.add(billing_address)
|
||||
db.commit()
|
||||
|
||||
assert shipping_address.address_type == "shipping"
|
||||
assert billing_address.address_type == "billing"
|
||||
|
||||
def test_customer_address_optional_fields(self, db, test_vendor, test_customer):
|
||||
"""Test CustomerAddress with optional fields."""
|
||||
address = CustomerAddress(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
address_type="shipping",
|
||||
first_name="John",
|
||||
last_name="Doe",
|
||||
company="ACME Corp",
|
||||
address_line_1="123 Main St",
|
||||
address_line_2="Suite 100",
|
||||
city="Luxembourg",
|
||||
postal_code="L-1234",
|
||||
country="Luxembourg",
|
||||
)
|
||||
db.add(address)
|
||||
db.commit()
|
||||
db.refresh(address)
|
||||
|
||||
assert address.company == "ACME Corp"
|
||||
assert address.address_line_2 == "Suite 100"
|
||||
|
||||
def test_customer_address_default_values(self, db, test_vendor, test_customer):
|
||||
"""Test CustomerAddress default values."""
|
||||
address = CustomerAddress(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
address_type="shipping",
|
||||
first_name="John",
|
||||
last_name="Doe",
|
||||
address_line_1="123 Main St",
|
||||
city="Luxembourg",
|
||||
postal_code="L-1234",
|
||||
country="Luxembourg",
|
||||
)
|
||||
db.add(address)
|
||||
db.commit()
|
||||
db.refresh(address)
|
||||
|
||||
assert address.is_default is False # Default
|
||||
|
||||
def test_customer_address_relationships(self, db, test_vendor, test_customer):
|
||||
"""Test CustomerAddress relationships."""
|
||||
address = CustomerAddress(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
address_type="shipping",
|
||||
first_name="John",
|
||||
last_name="Doe",
|
||||
address_line_1="123 Main St",
|
||||
city="Luxembourg",
|
||||
postal_code="L-1234",
|
||||
country="Luxembourg",
|
||||
)
|
||||
db.add(address)
|
||||
db.commit()
|
||||
db.refresh(address)
|
||||
|
||||
assert address.customer is not None
|
||||
assert address.customer.id == test_customer.id
|
||||
143
tests/unit/models/database/test_inventory.py
Normal file
143
tests/unit/models/database/test_inventory.py
Normal file
@@ -0,0 +1,143 @@
|
||||
# tests/unit/models/database/test_inventory.py
|
||||
"""Unit tests for Inventory database model."""
|
||||
import pytest
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from models.database.inventory import Inventory
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestInventoryModel:
|
||||
"""Test Inventory model."""
|
||||
|
||||
def test_inventory_creation_with_product(self, db, test_vendor, test_product):
|
||||
"""Test Inventory model linked to product."""
|
||||
inventory = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
location="WAREHOUSE_A",
|
||||
quantity=150,
|
||||
reserved_quantity=10,
|
||||
gtin=test_product.marketplace_product.gtin,
|
||||
)
|
||||
|
||||
db.add(inventory)
|
||||
db.commit()
|
||||
db.refresh(inventory)
|
||||
|
||||
assert inventory.id is not None
|
||||
assert inventory.product_id == test_product.id
|
||||
assert inventory.vendor_id == test_vendor.id
|
||||
assert inventory.location == "WAREHOUSE_A"
|
||||
assert inventory.quantity == 150
|
||||
assert inventory.reserved_quantity == 10
|
||||
assert inventory.available_quantity == 140 # 150 - 10
|
||||
|
||||
def test_inventory_unique_product_location(self, db, test_vendor, test_product):
|
||||
"""Test unique constraint on product_id + location."""
|
||||
inventory1 = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
location="WAREHOUSE_A",
|
||||
quantity=100,
|
||||
)
|
||||
db.add(inventory1)
|
||||
db.commit()
|
||||
|
||||
# Same product + location should fail
|
||||
with pytest.raises(IntegrityError):
|
||||
inventory2 = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
location="WAREHOUSE_A",
|
||||
quantity=50,
|
||||
)
|
||||
db.add(inventory2)
|
||||
db.commit()
|
||||
|
||||
def test_inventory_same_product_different_location(self, db, test_vendor, test_product):
|
||||
"""Test same product can have inventory in different locations."""
|
||||
inventory1 = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
location="WAREHOUSE_A",
|
||||
quantity=100,
|
||||
)
|
||||
db.add(inventory1)
|
||||
db.commit()
|
||||
|
||||
# Same product in different location should succeed
|
||||
inventory2 = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
location="WAREHOUSE_B",
|
||||
quantity=50,
|
||||
)
|
||||
db.add(inventory2)
|
||||
db.commit()
|
||||
db.refresh(inventory2)
|
||||
|
||||
assert inventory2.id is not None
|
||||
assert inventory2.location == "WAREHOUSE_B"
|
||||
|
||||
def test_inventory_default_values(self, db, test_vendor, test_product):
|
||||
"""Test Inventory model default values."""
|
||||
inventory = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
location="DEFAULT_LOC",
|
||||
quantity=100,
|
||||
)
|
||||
db.add(inventory)
|
||||
db.commit()
|
||||
db.refresh(inventory)
|
||||
|
||||
assert inventory.reserved_quantity == 0 # Default
|
||||
assert inventory.available_quantity == 100 # quantity - reserved
|
||||
|
||||
def test_inventory_available_quantity_property(self, db, test_vendor, test_product):
|
||||
"""Test available_quantity computed property."""
|
||||
inventory = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
location="PROP_TEST",
|
||||
quantity=200,
|
||||
reserved_quantity=50,
|
||||
)
|
||||
db.add(inventory)
|
||||
db.commit()
|
||||
db.refresh(inventory)
|
||||
|
||||
assert inventory.available_quantity == 150 # 200 - 50
|
||||
|
||||
def test_inventory_relationships(self, db, test_vendor, test_product):
|
||||
"""Test Inventory relationships."""
|
||||
inventory = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
location="REL_TEST",
|
||||
quantity=100,
|
||||
)
|
||||
db.add(inventory)
|
||||
db.commit()
|
||||
db.refresh(inventory)
|
||||
|
||||
assert inventory.product is not None
|
||||
assert inventory.vendor is not None
|
||||
assert inventory.product.id == test_product.id
|
||||
assert inventory.vendor.id == test_vendor.id
|
||||
|
||||
def test_inventory_without_gtin(self, db, test_vendor, test_product):
|
||||
"""Test Inventory can be created without GTIN."""
|
||||
inventory = Inventory(
|
||||
product_id=test_product.id,
|
||||
vendor_id=test_vendor.id,
|
||||
location="NO_GTIN",
|
||||
quantity=100,
|
||||
)
|
||||
db.add(inventory)
|
||||
db.commit()
|
||||
db.refresh(inventory)
|
||||
|
||||
assert inventory.gtin is None
|
||||
129
tests/unit/models/database/test_marketplace_import_job.py
Normal file
129
tests/unit/models/database/test_marketplace_import_job.py
Normal file
@@ -0,0 +1,129 @@
|
||||
# tests/unit/models/database/test_marketplace_import_job.py
|
||||
"""Unit tests for MarketplaceImportJob database model."""
|
||||
import pytest
|
||||
|
||||
from models.database.marketplace_import_job import MarketplaceImportJob
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestMarketplaceImportJobModel:
|
||||
"""Test MarketplaceImportJob model."""
|
||||
|
||||
def test_import_job_creation(self, db, test_user, test_vendor):
|
||||
"""Test MarketplaceImportJob model with relationships."""
|
||||
import_job = MarketplaceImportJob(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
marketplace="Letzshop",
|
||||
source_url="https://example.com/feed.csv",
|
||||
status="pending",
|
||||
imported_count=0,
|
||||
updated_count=0,
|
||||
error_count=0,
|
||||
total_processed=0,
|
||||
)
|
||||
|
||||
db.add(import_job)
|
||||
db.commit()
|
||||
db.refresh(import_job)
|
||||
|
||||
assert import_job.id is not None
|
||||
assert import_job.vendor_id == test_vendor.id
|
||||
assert import_job.user_id == test_user.id
|
||||
assert import_job.marketplace == "Letzshop"
|
||||
assert import_job.source_url == "https://example.com/feed.csv"
|
||||
assert import_job.status == "pending"
|
||||
assert import_job.vendor.vendor_code == test_vendor.vendor_code
|
||||
assert import_job.user.username == test_user.username
|
||||
|
||||
def test_import_job_default_values(self, db, test_user, test_vendor):
|
||||
"""Test MarketplaceImportJob default values."""
|
||||
import_job = MarketplaceImportJob(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
source_url="https://example.com/feed.csv",
|
||||
)
|
||||
|
||||
db.add(import_job)
|
||||
db.commit()
|
||||
db.refresh(import_job)
|
||||
|
||||
assert import_job.marketplace == "Letzshop" # Default
|
||||
assert import_job.status == "pending" # Default
|
||||
assert import_job.imported_count == 0 # Default
|
||||
assert import_job.updated_count == 0 # Default
|
||||
assert import_job.error_count == 0 # Default
|
||||
assert import_job.total_processed == 0 # Default
|
||||
|
||||
def test_import_job_status_values(self, db, test_user, test_vendor):
|
||||
"""Test MarketplaceImportJob with different status values."""
|
||||
statuses = ["pending", "processing", "completed", "failed", "completed_with_errors"]
|
||||
|
||||
for i, status in enumerate(statuses):
|
||||
import_job = MarketplaceImportJob(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
source_url=f"https://example.com/feed_{i}.csv",
|
||||
status=status,
|
||||
)
|
||||
db.add(import_job)
|
||||
db.commit()
|
||||
db.refresh(import_job)
|
||||
|
||||
assert import_job.status == status
|
||||
|
||||
def test_import_job_counts(self, db, test_user, test_vendor):
|
||||
"""Test MarketplaceImportJob count fields."""
|
||||
import_job = MarketplaceImportJob(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
source_url="https://example.com/feed.csv",
|
||||
status="completed",
|
||||
imported_count=100,
|
||||
updated_count=50,
|
||||
error_count=5,
|
||||
total_processed=155,
|
||||
)
|
||||
|
||||
db.add(import_job)
|
||||
db.commit()
|
||||
db.refresh(import_job)
|
||||
|
||||
assert import_job.imported_count == 100
|
||||
assert import_job.updated_count == 50
|
||||
assert import_job.error_count == 5
|
||||
assert import_job.total_processed == 155
|
||||
|
||||
def test_import_job_error_message(self, db, test_user, test_vendor):
|
||||
"""Test MarketplaceImportJob with error message."""
|
||||
import_job = MarketplaceImportJob(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
source_url="https://example.com/feed.csv",
|
||||
status="failed",
|
||||
error_message="Connection timeout while fetching CSV",
|
||||
)
|
||||
|
||||
db.add(import_job)
|
||||
db.commit()
|
||||
db.refresh(import_job)
|
||||
|
||||
assert import_job.error_message == "Connection timeout while fetching CSV"
|
||||
|
||||
def test_import_job_relationships(self, db, test_user, test_vendor):
|
||||
"""Test MarketplaceImportJob relationships."""
|
||||
import_job = MarketplaceImportJob(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
source_url="https://example.com/feed.csv",
|
||||
)
|
||||
|
||||
db.add(import_job)
|
||||
db.commit()
|
||||
db.refresh(import_job)
|
||||
|
||||
assert import_job.vendor is not None
|
||||
assert import_job.user is not None
|
||||
assert import_job.vendor.id == test_vendor.id
|
||||
assert import_job.user.id == test_user.id
|
||||
131
tests/unit/models/database/test_marketplace_product.py
Normal file
131
tests/unit/models/database/test_marketplace_product.py
Normal file
@@ -0,0 +1,131 @@
|
||||
# tests/unit/models/database/test_marketplace_product.py
|
||||
"""Unit tests for MarketplaceProduct database model."""
|
||||
import pytest
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestMarketplaceProductModel:
|
||||
"""Test MarketplaceProduct model."""
|
||||
|
||||
def test_marketplace_product_creation(self, db):
|
||||
"""Test MarketplaceProduct model creation."""
|
||||
marketplace_product = MarketplaceProduct(
|
||||
marketplace_product_id="DB_TEST_001",
|
||||
title="Database Test Product",
|
||||
description="Testing product model",
|
||||
price="25.99",
|
||||
currency="USD",
|
||||
brand="DBTest",
|
||||
gtin="1234567890123",
|
||||
availability="in stock",
|
||||
marketplace="Letzshop",
|
||||
vendor_name="Test Vendor",
|
||||
)
|
||||
|
||||
db.add(marketplace_product)
|
||||
db.commit()
|
||||
db.refresh(marketplace_product)
|
||||
|
||||
assert marketplace_product.id is not None
|
||||
assert marketplace_product.marketplace_product_id == "DB_TEST_001"
|
||||
assert marketplace_product.title == "Database Test Product"
|
||||
assert marketplace_product.marketplace == "Letzshop"
|
||||
assert marketplace_product.created_at is not None
|
||||
|
||||
def test_marketplace_product_id_uniqueness(self, db):
|
||||
"""Test unique marketplace_product_id constraint."""
|
||||
product1 = MarketplaceProduct(
|
||||
marketplace_product_id="UNIQUE_001",
|
||||
title="Product 1",
|
||||
marketplace="Letzshop",
|
||||
)
|
||||
db.add(product1)
|
||||
db.commit()
|
||||
|
||||
# Duplicate marketplace_product_id should raise error
|
||||
with pytest.raises(IntegrityError):
|
||||
product2 = MarketplaceProduct(
|
||||
marketplace_product_id="UNIQUE_001",
|
||||
title="Product 2",
|
||||
marketplace="Letzshop",
|
||||
)
|
||||
db.add(product2)
|
||||
db.commit()
|
||||
|
||||
def test_marketplace_product_all_fields(self, db):
|
||||
"""Test MarketplaceProduct with all optional fields."""
|
||||
marketplace_product = MarketplaceProduct(
|
||||
marketplace_product_id="FULL_001",
|
||||
title="Full Product",
|
||||
description="Complete product description",
|
||||
link="https://example.com/product",
|
||||
image_link="https://example.com/image.jpg",
|
||||
availability="in stock",
|
||||
price="99.99",
|
||||
brand="TestBrand",
|
||||
gtin="9876543210123",
|
||||
mpn="MPN123",
|
||||
condition="new",
|
||||
adult="no",
|
||||
age_group="adult",
|
||||
color="blue",
|
||||
gender="unisex",
|
||||
material="cotton",
|
||||
pattern="solid",
|
||||
size="M",
|
||||
google_product_category="Apparel & Accessories",
|
||||
product_type="Clothing",
|
||||
currency="EUR",
|
||||
marketplace="Letzshop",
|
||||
vendor_name="Full Vendor",
|
||||
)
|
||||
|
||||
db.add(marketplace_product)
|
||||
db.commit()
|
||||
db.refresh(marketplace_product)
|
||||
|
||||
assert marketplace_product.brand == "TestBrand"
|
||||
assert marketplace_product.gtin == "9876543210123"
|
||||
assert marketplace_product.color == "blue"
|
||||
assert marketplace_product.size == "M"
|
||||
|
||||
def test_marketplace_product_custom_labels(self, db):
|
||||
"""Test MarketplaceProduct with custom labels."""
|
||||
marketplace_product = MarketplaceProduct(
|
||||
marketplace_product_id="LABELS_001",
|
||||
title="Labeled Product",
|
||||
marketplace="Letzshop",
|
||||
custom_label_0="Label0",
|
||||
custom_label_1="Label1",
|
||||
custom_label_2="Label2",
|
||||
custom_label_3="Label3",
|
||||
custom_label_4="Label4",
|
||||
)
|
||||
|
||||
db.add(marketplace_product)
|
||||
db.commit()
|
||||
db.refresh(marketplace_product)
|
||||
|
||||
assert marketplace_product.custom_label_0 == "Label0"
|
||||
assert marketplace_product.custom_label_4 == "Label4"
|
||||
|
||||
def test_marketplace_product_minimal_fields(self, db):
|
||||
"""Test MarketplaceProduct with only required fields."""
|
||||
marketplace_product = MarketplaceProduct(
|
||||
marketplace_product_id="MINIMAL_001",
|
||||
title="Minimal Product",
|
||||
)
|
||||
|
||||
db.add(marketplace_product)
|
||||
db.commit()
|
||||
db.refresh(marketplace_product)
|
||||
|
||||
assert marketplace_product.id is not None
|
||||
assert marketplace_product.marketplace_product_id == "MINIMAL_001"
|
||||
assert marketplace_product.title == "Minimal Product"
|
||||
assert marketplace_product.description is None
|
||||
assert marketplace_product.price is None
|
||||
242
tests/unit/models/database/test_order.py
Normal file
242
tests/unit/models/database/test_order.py
Normal file
@@ -0,0 +1,242 @@
|
||||
# tests/unit/models/database/test_order.py
|
||||
"""Unit tests for Order and OrderItem database models."""
|
||||
import pytest
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from models.database.order import Order, OrderItem
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestOrderModel:
|
||||
"""Test Order model."""
|
||||
|
||||
def test_order_creation(
|
||||
self, db, test_vendor, test_customer, test_customer_address
|
||||
):
|
||||
"""Test Order model with customer relationship."""
|
||||
order = Order(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
order_number="ORD-001",
|
||||
status="pending",
|
||||
subtotal=99.99,
|
||||
total_amount=99.99,
|
||||
currency="EUR",
|
||||
shipping_address_id=test_customer_address.id,
|
||||
billing_address_id=test_customer_address.id,
|
||||
)
|
||||
|
||||
db.add(order)
|
||||
db.commit()
|
||||
db.refresh(order)
|
||||
|
||||
assert order.id is not None
|
||||
assert order.vendor_id == test_vendor.id
|
||||
assert order.customer_id == test_customer.id
|
||||
assert order.order_number == "ORD-001"
|
||||
assert order.status == "pending"
|
||||
assert float(order.total_amount) == 99.99
|
||||
|
||||
def test_order_number_uniqueness(
|
||||
self, db, test_vendor, test_customer, test_customer_address
|
||||
):
|
||||
"""Test order_number unique constraint."""
|
||||
order1 = Order(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
order_number="UNIQUE-ORD-001",
|
||||
status="pending",
|
||||
subtotal=50.00,
|
||||
total_amount=50.00,
|
||||
shipping_address_id=test_customer_address.id,
|
||||
billing_address_id=test_customer_address.id,
|
||||
)
|
||||
db.add(order1)
|
||||
db.commit()
|
||||
|
||||
# Duplicate order number should fail
|
||||
with pytest.raises(IntegrityError):
|
||||
order2 = Order(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
order_number="UNIQUE-ORD-001",
|
||||
status="pending",
|
||||
subtotal=75.00,
|
||||
total_amount=75.00,
|
||||
shipping_address_id=test_customer_address.id,
|
||||
billing_address_id=test_customer_address.id,
|
||||
)
|
||||
db.add(order2)
|
||||
db.commit()
|
||||
|
||||
def test_order_status_values(
|
||||
self, db, test_vendor, test_customer, test_customer_address
|
||||
):
|
||||
"""Test Order with different status values."""
|
||||
statuses = ["pending", "confirmed", "processing", "shipped", "delivered", "cancelled"]
|
||||
|
||||
for i, status in enumerate(statuses):
|
||||
order = Order(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
order_number=f"STATUS-ORD-{i:03d}",
|
||||
status=status,
|
||||
subtotal=50.00,
|
||||
total_amount=50.00,
|
||||
shipping_address_id=test_customer_address.id,
|
||||
billing_address_id=test_customer_address.id,
|
||||
)
|
||||
db.add(order)
|
||||
db.commit()
|
||||
db.refresh(order)
|
||||
|
||||
assert order.status == status
|
||||
|
||||
def test_order_amounts(
|
||||
self, db, test_vendor, test_customer, test_customer_address
|
||||
):
|
||||
"""Test Order amount fields."""
|
||||
order = Order(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
order_number="AMOUNTS-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_address_id=test_customer_address.id,
|
||||
billing_address_id=test_customer_address.id,
|
||||
)
|
||||
db.add(order)
|
||||
db.commit()
|
||||
db.refresh(order)
|
||||
|
||||
assert float(order.subtotal) == 100.00
|
||||
assert float(order.tax_amount) == 20.00
|
||||
assert float(order.shipping_amount) == 10.00
|
||||
assert float(order.discount_amount) == 5.00
|
||||
assert float(order.total_amount) == 125.00
|
||||
|
||||
def test_order_relationships(
|
||||
self, db, test_vendor, test_customer, test_customer_address
|
||||
):
|
||||
"""Test Order relationships."""
|
||||
order = Order(
|
||||
vendor_id=test_vendor.id,
|
||||
customer_id=test_customer.id,
|
||||
order_number="REL-ORD-001",
|
||||
status="pending",
|
||||
subtotal=50.00,
|
||||
total_amount=50.00,
|
||||
shipping_address_id=test_customer_address.id,
|
||||
billing_address_id=test_customer_address.id,
|
||||
)
|
||||
db.add(order)
|
||||
db.commit()
|
||||
db.refresh(order)
|
||||
|
||||
assert order.vendor is not None
|
||||
assert order.customer is not None
|
||||
assert order.vendor.id == test_vendor.id
|
||||
assert order.customer.id == test_customer.id
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestOrderItemModel:
|
||||
"""Test OrderItem model."""
|
||||
|
||||
def test_order_item_creation(self, db, test_order, test_product):
|
||||
"""Test OrderItem model."""
|
||||
order_item = OrderItem(
|
||||
order_id=test_order.id,
|
||||
product_id=test_product.id,
|
||||
product_name=test_product.marketplace_product.title,
|
||||
product_sku=test_product.product_id or "SKU001",
|
||||
quantity=2,
|
||||
unit_price=49.99,
|
||||
total_price=99.98,
|
||||
)
|
||||
|
||||
db.add(order_item)
|
||||
db.commit()
|
||||
db.refresh(order_item)
|
||||
|
||||
assert order_item.id is not None
|
||||
assert order_item.order_id == test_order.id
|
||||
assert order_item.product_id == test_product.id
|
||||
assert order_item.quantity == 2
|
||||
assert float(order_item.unit_price) == 49.99
|
||||
assert float(order_item.total_price) == 99.98
|
||||
|
||||
def test_order_item_stores_product_snapshot(self, db, test_order, test_product):
|
||||
"""Test OrderItem stores product name and SKU as snapshot."""
|
||||
order_item = OrderItem(
|
||||
order_id=test_order.id,
|
||||
product_id=test_product.id,
|
||||
product_name="Snapshot Product Name",
|
||||
product_sku="SNAPSHOT-SKU-001",
|
||||
quantity=1,
|
||||
unit_price=25.00,
|
||||
total_price=25.00,
|
||||
)
|
||||
|
||||
db.add(order_item)
|
||||
db.commit()
|
||||
db.refresh(order_item)
|
||||
|
||||
assert order_item.id is not None
|
||||
assert order_item.product_name == "Snapshot Product Name"
|
||||
assert order_item.product_sku == "SNAPSHOT-SKU-001"
|
||||
|
||||
def test_order_item_relationships(self, db, test_order, test_product):
|
||||
"""Test OrderItem relationships."""
|
||||
order_item = OrderItem(
|
||||
order_id=test_order.id,
|
||||
product_id=test_product.id,
|
||||
product_name="Test Product",
|
||||
product_sku="SKU001",
|
||||
quantity=1,
|
||||
unit_price=50.00,
|
||||
total_price=50.00,
|
||||
)
|
||||
|
||||
db.add(order_item)
|
||||
db.commit()
|
||||
db.refresh(order_item)
|
||||
|
||||
assert order_item.order is not None
|
||||
assert order_item.order.id == test_order.id
|
||||
|
||||
def test_multiple_items_per_order(self, db, test_order, test_product):
|
||||
"""Test multiple OrderItems can belong to same Order."""
|
||||
# Create two order items for the same product (different quantities)
|
||||
item1 = OrderItem(
|
||||
order_id=test_order.id,
|
||||
product_id=test_product.id,
|
||||
product_name="Product - Size M",
|
||||
product_sku="SKU001-M",
|
||||
quantity=1,
|
||||
unit_price=25.00,
|
||||
total_price=25.00,
|
||||
)
|
||||
item2 = OrderItem(
|
||||
order_id=test_order.id,
|
||||
product_id=test_product.id,
|
||||
product_name="Product - Size L",
|
||||
product_sku="SKU001-L",
|
||||
quantity=2,
|
||||
unit_price=30.00,
|
||||
total_price=60.00,
|
||||
)
|
||||
|
||||
db.add_all([item1, item2])
|
||||
db.commit()
|
||||
|
||||
assert item1.order_id == item2.order_id
|
||||
assert item1.id != item2.id
|
||||
assert item1.product_id == item2.product_id # Same product, different items
|
||||
123
tests/unit/models/database/test_product.py
Normal file
123
tests/unit/models/database/test_product.py
Normal file
@@ -0,0 +1,123 @@
|
||||
# tests/unit/models/database/test_product.py
|
||||
"""Unit tests for Product (vendor catalog) database model."""
|
||||
import pytest
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from models.database.product import Product
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestProductModel:
|
||||
"""Test Product (vendor catalog) model."""
|
||||
|
||||
def test_product_creation(self, db, test_vendor, test_marketplace_product):
|
||||
"""Test Product model linking vendor catalog to marketplace product."""
|
||||
product = Product(
|
||||
vendor_id=test_vendor.id,
|
||||
marketplace_product_id=test_marketplace_product.id,
|
||||
product_id="VENDOR_PROD_001",
|
||||
price=89.99,
|
||||
currency="EUR",
|
||||
availability="in stock",
|
||||
is_featured=True,
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
db.add(product)
|
||||
db.commit()
|
||||
db.refresh(product)
|
||||
|
||||
assert product.id is not None
|
||||
assert product.vendor_id == test_vendor.id
|
||||
assert product.marketplace_product_id == test_marketplace_product.id
|
||||
assert product.price == 89.99
|
||||
assert product.is_featured is True
|
||||
assert product.vendor.vendor_code == test_vendor.vendor_code
|
||||
assert product.marketplace_product.title == test_marketplace_product.title
|
||||
|
||||
def test_product_unique_per_vendor(self, db, test_vendor, test_marketplace_product):
|
||||
"""Test that same marketplace product can't be added twice to vendor catalog."""
|
||||
product1 = Product(
|
||||
vendor_id=test_vendor.id,
|
||||
marketplace_product_id=test_marketplace_product.id,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(product1)
|
||||
db.commit()
|
||||
|
||||
# Same marketplace product to same vendor should fail
|
||||
with pytest.raises(IntegrityError):
|
||||
product2 = Product(
|
||||
vendor_id=test_vendor.id,
|
||||
marketplace_product_id=test_marketplace_product.id,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(product2)
|
||||
db.commit()
|
||||
|
||||
def test_product_default_values(self, db, test_vendor, test_marketplace_product):
|
||||
"""Test Product model default values."""
|
||||
product = Product(
|
||||
vendor_id=test_vendor.id,
|
||||
marketplace_product_id=test_marketplace_product.id,
|
||||
)
|
||||
db.add(product)
|
||||
db.commit()
|
||||
db.refresh(product)
|
||||
|
||||
assert product.is_active is True # Default
|
||||
assert product.is_featured is False # Default
|
||||
assert product.min_quantity == 1 # Default
|
||||
assert product.display_order == 0 # Default
|
||||
|
||||
def test_product_vendor_override_fields(self, db, test_vendor, test_marketplace_product):
|
||||
"""Test Product model vendor-specific override fields."""
|
||||
product = Product(
|
||||
vendor_id=test_vendor.id,
|
||||
marketplace_product_id=test_marketplace_product.id,
|
||||
product_id="CUSTOM_SKU_001",
|
||||
price=49.99,
|
||||
sale_price=39.99,
|
||||
currency="USD",
|
||||
availability="limited",
|
||||
condition="new",
|
||||
)
|
||||
db.add(product)
|
||||
db.commit()
|
||||
db.refresh(product)
|
||||
|
||||
assert product.product_id == "CUSTOM_SKU_001"
|
||||
assert product.price == 49.99
|
||||
assert product.sale_price == 39.99
|
||||
assert product.currency == "USD"
|
||||
assert product.availability == "limited"
|
||||
|
||||
def test_product_inventory_settings(self, db, test_vendor, test_marketplace_product):
|
||||
"""Test Product model inventory settings."""
|
||||
product = Product(
|
||||
vendor_id=test_vendor.id,
|
||||
marketplace_product_id=test_marketplace_product.id,
|
||||
min_quantity=2,
|
||||
max_quantity=10,
|
||||
)
|
||||
db.add(product)
|
||||
db.commit()
|
||||
db.refresh(product)
|
||||
|
||||
assert product.min_quantity == 2
|
||||
assert product.max_quantity == 10
|
||||
|
||||
def test_product_relationships(self, db, test_vendor, test_marketplace_product):
|
||||
"""Test Product relationships."""
|
||||
product = Product(
|
||||
vendor_id=test_vendor.id,
|
||||
marketplace_product_id=test_marketplace_product.id,
|
||||
)
|
||||
db.add(product)
|
||||
db.commit()
|
||||
db.refresh(product)
|
||||
|
||||
assert product.vendor is not None
|
||||
assert product.marketplace_product is not None
|
||||
assert product.inventory_entries == [] # No inventory yet
|
||||
179
tests/unit/models/database/test_team.py
Normal file
179
tests/unit/models/database/test_team.py
Normal file
@@ -0,0 +1,179 @@
|
||||
# tests/unit/models/database/test_team.py
|
||||
"""Unit tests for VendorUser and Role database models."""
|
||||
import pytest
|
||||
|
||||
from models.database.vendor import Role, Vendor, VendorUser
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestRoleModel:
|
||||
"""Test Role model."""
|
||||
|
||||
def test_role_creation(self, db, test_vendor):
|
||||
"""Test Role model creation."""
|
||||
role = Role(
|
||||
vendor_id=test_vendor.id,
|
||||
name="Manager",
|
||||
permissions=["products.create", "orders.view"],
|
||||
)
|
||||
db.add(role)
|
||||
db.commit()
|
||||
db.refresh(role)
|
||||
|
||||
assert role.id is not None
|
||||
assert role.vendor_id == test_vendor.id
|
||||
assert role.name == "Manager"
|
||||
assert "products.create" in role.permissions
|
||||
assert "orders.view" in role.permissions
|
||||
|
||||
def test_role_default_permissions(self, db, test_vendor):
|
||||
"""Test Role model with default empty permissions."""
|
||||
role = Role(
|
||||
vendor_id=test_vendor.id,
|
||||
name="Viewer",
|
||||
)
|
||||
db.add(role)
|
||||
db.commit()
|
||||
db.refresh(role)
|
||||
|
||||
assert role.permissions == [] or role.permissions is None
|
||||
|
||||
def test_role_vendor_relationship(self, db, test_vendor):
|
||||
"""Test Role-Vendor relationship."""
|
||||
role = Role(
|
||||
vendor_id=test_vendor.id,
|
||||
name="Admin",
|
||||
permissions=["*"],
|
||||
)
|
||||
db.add(role)
|
||||
db.commit()
|
||||
db.refresh(role)
|
||||
|
||||
assert role.vendor is not None
|
||||
assert role.vendor.id == test_vendor.id
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestVendorUserModel:
|
||||
"""Test VendorUser model."""
|
||||
|
||||
def test_vendor_user_creation(self, db, test_vendor, test_user):
|
||||
"""Test VendorUser model for team management."""
|
||||
# Create a role
|
||||
role = Role(
|
||||
vendor_id=test_vendor.id,
|
||||
name="Manager",
|
||||
permissions=["products.create", "orders.view"],
|
||||
)
|
||||
db.add(role)
|
||||
db.commit()
|
||||
|
||||
# Create vendor user
|
||||
vendor_user = VendorUser(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
role_id=role.id,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(vendor_user)
|
||||
db.commit()
|
||||
db.refresh(vendor_user)
|
||||
|
||||
assert vendor_user.id is not None
|
||||
assert vendor_user.vendor_id == test_vendor.id
|
||||
assert vendor_user.user_id == test_user.id
|
||||
assert vendor_user.role.name == "Manager"
|
||||
assert "products.create" in vendor_user.role.permissions
|
||||
|
||||
def test_vendor_user_multiple_vendors(self, db, test_vendor, test_user, other_company):
|
||||
"""Test same user can be added to multiple vendors."""
|
||||
# Create another vendor
|
||||
other_vendor = Vendor(
|
||||
company_id=other_company.id,
|
||||
vendor_code="OTHER_VENDOR",
|
||||
subdomain="othervendor",
|
||||
name="Other Vendor",
|
||||
)
|
||||
db.add(other_vendor)
|
||||
db.commit()
|
||||
|
||||
role1 = Role(
|
||||
vendor_id=test_vendor.id,
|
||||
name="Editor1",
|
||||
permissions=["products.view"],
|
||||
)
|
||||
role2 = Role(
|
||||
vendor_id=other_vendor.id,
|
||||
name="Editor2",
|
||||
permissions=["products.view"],
|
||||
)
|
||||
db.add_all([role1, role2])
|
||||
db.commit()
|
||||
|
||||
# Same user can be added to different vendors
|
||||
vendor_user1 = VendorUser(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
role_id=role1.id,
|
||||
)
|
||||
vendor_user2 = VendorUser(
|
||||
vendor_id=other_vendor.id,
|
||||
user_id=test_user.id,
|
||||
role_id=role2.id,
|
||||
)
|
||||
db.add_all([vendor_user1, vendor_user2])
|
||||
db.commit()
|
||||
|
||||
assert vendor_user1.vendor_id != vendor_user2.vendor_id
|
||||
assert vendor_user1.user_id == vendor_user2.user_id
|
||||
|
||||
def test_vendor_user_relationships(self, db, test_vendor, test_user):
|
||||
"""Test VendorUser relationships."""
|
||||
role = Role(
|
||||
vendor_id=test_vendor.id,
|
||||
name="Staff",
|
||||
permissions=["orders.view"],
|
||||
)
|
||||
db.add(role)
|
||||
db.commit()
|
||||
|
||||
vendor_user = VendorUser(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
role_id=role.id,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(vendor_user)
|
||||
db.commit()
|
||||
db.refresh(vendor_user)
|
||||
|
||||
assert vendor_user.vendor is not None
|
||||
assert vendor_user.user is not None
|
||||
assert vendor_user.role is not None
|
||||
assert vendor_user.vendor.vendor_code == test_vendor.vendor_code
|
||||
assert vendor_user.user.email == test_user.email
|
||||
|
||||
def test_vendor_user_with_active_flag(self, db, test_vendor, test_user):
|
||||
"""Test VendorUser is_active field."""
|
||||
role = Role(
|
||||
vendor_id=test_vendor.id,
|
||||
name="Default",
|
||||
permissions=[],
|
||||
)
|
||||
db.add(role)
|
||||
db.commit()
|
||||
|
||||
# Create with explicit is_active=True
|
||||
vendor_user = VendorUser(
|
||||
vendor_id=test_vendor.id,
|
||||
user_id=test_user.id,
|
||||
role_id=role.id,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(vendor_user)
|
||||
db.commit()
|
||||
db.refresh(vendor_user)
|
||||
|
||||
assert vendor_user.is_active is True
|
||||
104
tests/unit/models/database/test_user.py
Normal file
104
tests/unit/models/database/test_user.py
Normal file
@@ -0,0 +1,104 @@
|
||||
# tests/unit/models/database/test_user.py
|
||||
"""Unit tests for User database model."""
|
||||
import pytest
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from models.database.user import User
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestUserModel:
|
||||
"""Test User model."""
|
||||
|
||||
def test_user_creation(self, db):
|
||||
"""Test User model creation and relationships."""
|
||||
user = User(
|
||||
email="db_test@example.com",
|
||||
username="dbtest",
|
||||
hashed_password="hashed_password_123",
|
||||
role="user",
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
db.add(user)
|
||||
db.commit()
|
||||
db.refresh(user)
|
||||
|
||||
assert user.id is not None
|
||||
assert user.email == "db_test@example.com"
|
||||
assert user.username == "dbtest"
|
||||
assert user.role == "user"
|
||||
assert user.is_active is True
|
||||
assert user.created_at is not None
|
||||
assert user.updated_at is not None
|
||||
|
||||
def test_user_email_uniqueness(self, db):
|
||||
"""Test email unique constraint."""
|
||||
user1 = User(
|
||||
email="unique@example.com",
|
||||
username="user1",
|
||||
hashed_password="hash1",
|
||||
)
|
||||
db.add(user1)
|
||||
db.commit()
|
||||
|
||||
# Duplicate email should raise error
|
||||
with pytest.raises(IntegrityError):
|
||||
user2 = User(
|
||||
email="unique@example.com",
|
||||
username="user2",
|
||||
hashed_password="hash2",
|
||||
)
|
||||
db.add(user2)
|
||||
db.commit()
|
||||
|
||||
def test_user_username_uniqueness(self, db):
|
||||
"""Test username unique constraint."""
|
||||
user1 = User(
|
||||
email="user1@example.com",
|
||||
username="sameusername",
|
||||
hashed_password="hash1",
|
||||
)
|
||||
db.add(user1)
|
||||
db.commit()
|
||||
|
||||
# Duplicate username should raise error
|
||||
with pytest.raises(IntegrityError):
|
||||
user2 = User(
|
||||
email="user2@example.com",
|
||||
username="sameusername",
|
||||
hashed_password="hash2",
|
||||
)
|
||||
db.add(user2)
|
||||
db.commit()
|
||||
|
||||
def test_user_default_values(self, db):
|
||||
"""Test User model default values."""
|
||||
user = User(
|
||||
email="defaults@example.com",
|
||||
username="defaultuser",
|
||||
hashed_password="hash",
|
||||
)
|
||||
db.add(user)
|
||||
db.commit()
|
||||
db.refresh(user)
|
||||
|
||||
assert user.is_active is True # Default
|
||||
assert user.role == "vendor" # Default (UserRole.VENDOR)
|
||||
|
||||
def test_user_optional_fields(self, db):
|
||||
"""Test User model with optional fields."""
|
||||
user = User(
|
||||
email="optional@example.com",
|
||||
username="optionaluser",
|
||||
hashed_password="hash",
|
||||
first_name="John",
|
||||
last_name="Doe",
|
||||
)
|
||||
db.add(user)
|
||||
db.commit()
|
||||
db.refresh(user)
|
||||
|
||||
assert user.first_name == "John"
|
||||
assert user.last_name == "Doe"
|
||||
137
tests/unit/models/database/test_vendor.py
Normal file
137
tests/unit/models/database/test_vendor.py
Normal file
@@ -0,0 +1,137 @@
|
||||
# tests/unit/models/database/test_vendor.py
|
||||
"""Unit tests for Vendor database model."""
|
||||
import pytest
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from models.database.vendor import Vendor
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.database
|
||||
class TestVendorModel:
|
||||
"""Test Vendor model."""
|
||||
|
||||
def test_vendor_creation(self, db, test_company):
|
||||
"""Test Vendor model creation with company relationship."""
|
||||
vendor = Vendor(
|
||||
company_id=test_company.id,
|
||||
vendor_code="DBTEST",
|
||||
subdomain="dbtest",
|
||||
name="Database Test Vendor",
|
||||
description="Testing vendor model",
|
||||
contact_email="contact@dbtest.com",
|
||||
contact_phone="+1234567890",
|
||||
business_address="123 Test Street",
|
||||
is_active=True,
|
||||
is_verified=False,
|
||||
)
|
||||
|
||||
db.add(vendor)
|
||||
db.commit()
|
||||
db.refresh(vendor)
|
||||
|
||||
assert vendor.id is not None
|
||||
assert vendor.vendor_code == "DBTEST"
|
||||
assert vendor.subdomain == "dbtest"
|
||||
assert vendor.name == "Database Test Vendor"
|
||||
assert vendor.company_id == test_company.id
|
||||
assert vendor.contact_email == "contact@dbtest.com"
|
||||
assert vendor.is_active is True
|
||||
assert vendor.is_verified is False
|
||||
assert vendor.created_at is not None
|
||||
|
||||
def test_vendor_with_letzshop_urls(self, db, test_company):
|
||||
"""Test Vendor model with multi-language Letzshop URLs."""
|
||||
vendor = Vendor(
|
||||
company_id=test_company.id,
|
||||
vendor_code="MULTILANG",
|
||||
subdomain="multilang",
|
||||
name="Multi-Language Vendor",
|
||||
letzshop_csv_url_fr="https://example.com/feed_fr.csv",
|
||||
letzshop_csv_url_en="https://example.com/feed_en.csv",
|
||||
letzshop_csv_url_de="https://example.com/feed_de.csv",
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
db.add(vendor)
|
||||
db.commit()
|
||||
db.refresh(vendor)
|
||||
|
||||
assert vendor.letzshop_csv_url_fr == "https://example.com/feed_fr.csv"
|
||||
assert vendor.letzshop_csv_url_en == "https://example.com/feed_en.csv"
|
||||
assert vendor.letzshop_csv_url_de == "https://example.com/feed_de.csv"
|
||||
|
||||
def test_vendor_code_uniqueness(self, db, test_company):
|
||||
"""Test vendor_code unique constraint."""
|
||||
vendor1 = Vendor(
|
||||
company_id=test_company.id,
|
||||
vendor_code="UNIQUE",
|
||||
subdomain="unique1",
|
||||
name="Unique Vendor 1",
|
||||
)
|
||||
db.add(vendor1)
|
||||
db.commit()
|
||||
|
||||
# Duplicate vendor_code should raise error
|
||||
with pytest.raises(IntegrityError):
|
||||
vendor2 = Vendor(
|
||||
company_id=test_company.id,
|
||||
vendor_code="UNIQUE",
|
||||
subdomain="unique2",
|
||||
name="Unique Vendor 2",
|
||||
)
|
||||
db.add(vendor2)
|
||||
db.commit()
|
||||
|
||||
def test_subdomain_uniqueness(self, db, test_company):
|
||||
"""Test subdomain unique constraint."""
|
||||
vendor1 = Vendor(
|
||||
company_id=test_company.id,
|
||||
vendor_code="VENDOR1",
|
||||
subdomain="testsubdomain",
|
||||
name="Vendor 1",
|
||||
)
|
||||
db.add(vendor1)
|
||||
db.commit()
|
||||
|
||||
# Duplicate subdomain should raise error
|
||||
with pytest.raises(IntegrityError):
|
||||
vendor2 = Vendor(
|
||||
company_id=test_company.id,
|
||||
vendor_code="VENDOR2",
|
||||
subdomain="testsubdomain",
|
||||
name="Vendor 2",
|
||||
)
|
||||
db.add(vendor2)
|
||||
db.commit()
|
||||
|
||||
def test_vendor_default_values(self, db, test_company):
|
||||
"""Test Vendor model default values."""
|
||||
vendor = Vendor(
|
||||
company_id=test_company.id,
|
||||
vendor_code="DEFAULTS",
|
||||
subdomain="defaults",
|
||||
name="Default Vendor",
|
||||
)
|
||||
db.add(vendor)
|
||||
db.commit()
|
||||
db.refresh(vendor)
|
||||
|
||||
assert vendor.is_active is True # Default
|
||||
assert vendor.is_verified is False # Default
|
||||
|
||||
def test_vendor_company_relationship(self, db, test_company):
|
||||
"""Test Vendor-Company relationship."""
|
||||
vendor = Vendor(
|
||||
company_id=test_company.id,
|
||||
vendor_code="RELTEST",
|
||||
subdomain="reltest",
|
||||
name="Relationship Test Vendor",
|
||||
)
|
||||
db.add(vendor)
|
||||
db.commit()
|
||||
db.refresh(vendor)
|
||||
|
||||
assert vendor.company is not None
|
||||
assert vendor.company.id == test_company.id
|
||||
assert vendor.company.name == test_company.name
|
||||
Reference in New Issue
Block a user