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:
315
tests/unit/models/schema/test_vendor.py
Normal file
315
tests/unit/models/schema/test_vendor.py
Normal file
@@ -0,0 +1,315 @@
|
||||
# tests/unit/models/schema/test_vendor.py
|
||||
"""Unit tests for vendor Pydantic schemas."""
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from models.schema.vendor import (
|
||||
VendorCreate,
|
||||
VendorUpdate,
|
||||
VendorResponse,
|
||||
VendorDetailResponse,
|
||||
VendorListResponse,
|
||||
VendorSummary,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.schema
|
||||
class TestVendorCreateSchema:
|
||||
"""Test VendorCreate schema validation."""
|
||||
|
||||
def test_valid_vendor_create(self):
|
||||
"""Test valid vendor creation data."""
|
||||
vendor = VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="TECHSTORE",
|
||||
subdomain="techstore",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert vendor.company_id == 1
|
||||
assert vendor.vendor_code == "TECHSTORE"
|
||||
assert vendor.subdomain == "techstore"
|
||||
assert vendor.name == "Tech Store"
|
||||
|
||||
def test_company_id_required(self):
|
||||
"""Test company_id is required."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
VendorCreate(
|
||||
vendor_code="TECHSTORE",
|
||||
subdomain="techstore",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert "company_id" in str(exc_info.value).lower()
|
||||
|
||||
def test_company_id_must_be_positive(self):
|
||||
"""Test company_id must be > 0."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
VendorCreate(
|
||||
company_id=0,
|
||||
vendor_code="TECHSTORE",
|
||||
subdomain="techstore",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert "company_id" in str(exc_info.value).lower()
|
||||
|
||||
def test_vendor_code_required(self):
|
||||
"""Test vendor_code is required."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
VendorCreate(
|
||||
company_id=1,
|
||||
subdomain="techstore",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert "vendor_code" in str(exc_info.value).lower()
|
||||
|
||||
def test_vendor_code_uppercase_normalized(self):
|
||||
"""Test vendor_code is normalized to uppercase."""
|
||||
vendor = VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="techstore",
|
||||
subdomain="techstore",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert vendor.vendor_code == "TECHSTORE"
|
||||
|
||||
def test_vendor_code_min_length(self):
|
||||
"""Test vendor_code minimum length (2)."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="T",
|
||||
subdomain="techstore",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert "vendor_code" in str(exc_info.value).lower()
|
||||
|
||||
def test_subdomain_required(self):
|
||||
"""Test subdomain is required."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="TECHSTORE",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert "subdomain" in str(exc_info.value).lower()
|
||||
|
||||
def test_subdomain_uppercase_invalid(self):
|
||||
"""Test subdomain with uppercase is invalid (validated before normalization)."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="TECHSTORE",
|
||||
subdomain="TechStore",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert "subdomain" in str(exc_info.value).lower()
|
||||
|
||||
def test_subdomain_valid_format(self):
|
||||
"""Test subdomain with valid format."""
|
||||
vendor = VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="TECHSTORE",
|
||||
subdomain="tech-store-123",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert vendor.subdomain == "tech-store-123"
|
||||
|
||||
def test_subdomain_invalid_format(self):
|
||||
"""Test subdomain with invalid characters raises ValidationError."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="TECHSTORE",
|
||||
subdomain="tech_store!",
|
||||
name="Tech Store",
|
||||
)
|
||||
assert "subdomain" in str(exc_info.value).lower()
|
||||
|
||||
def test_name_required(self):
|
||||
"""Test name is required."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="TECHSTORE",
|
||||
subdomain="techstore",
|
||||
)
|
||||
assert "name" in str(exc_info.value).lower()
|
||||
|
||||
def test_name_min_length(self):
|
||||
"""Test name minimum length (2)."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="TECHSTORE",
|
||||
subdomain="techstore",
|
||||
name="T",
|
||||
)
|
||||
assert "name" in str(exc_info.value).lower()
|
||||
|
||||
def test_optional_fields(self):
|
||||
"""Test optional fields."""
|
||||
vendor = VendorCreate(
|
||||
company_id=1,
|
||||
vendor_code="TECHSTORE",
|
||||
subdomain="techstore",
|
||||
name="Tech Store",
|
||||
description="Best tech store",
|
||||
letzshop_csv_url_fr="https://example.com/fr.csv",
|
||||
contact_email="contact@techstore.com",
|
||||
website="https://techstore.com",
|
||||
)
|
||||
assert vendor.description == "Best tech store"
|
||||
assert vendor.letzshop_csv_url_fr == "https://example.com/fr.csv"
|
||||
assert vendor.contact_email == "contact@techstore.com"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.schema
|
||||
class TestVendorUpdateSchema:
|
||||
"""Test VendorUpdate schema validation."""
|
||||
|
||||
def test_partial_update(self):
|
||||
"""Test partial update with only some fields."""
|
||||
update = VendorUpdate(name="New Tech Store")
|
||||
assert update.name == "New Tech Store"
|
||||
assert update.subdomain is None
|
||||
assert update.is_active is None
|
||||
|
||||
def test_empty_update_is_valid(self):
|
||||
"""Test empty update is valid."""
|
||||
update = VendorUpdate()
|
||||
assert update.model_dump(exclude_unset=True) == {}
|
||||
|
||||
def test_subdomain_normalized_to_lowercase(self):
|
||||
"""Test subdomain is normalized to lowercase."""
|
||||
update = VendorUpdate(subdomain="NewSubdomain")
|
||||
assert update.subdomain == "newsubdomain"
|
||||
|
||||
def test_subdomain_stripped(self):
|
||||
"""Test subdomain is stripped of whitespace."""
|
||||
update = VendorUpdate(subdomain=" newsubdomain ")
|
||||
assert update.subdomain == "newsubdomain"
|
||||
|
||||
def test_name_min_length(self):
|
||||
"""Test name minimum length (2)."""
|
||||
with pytest.raises(ValidationError):
|
||||
VendorUpdate(name="X")
|
||||
|
||||
def test_is_active_update(self):
|
||||
"""Test is_active can be updated."""
|
||||
update = VendorUpdate(is_active=False)
|
||||
assert update.is_active is False
|
||||
|
||||
def test_is_verified_update(self):
|
||||
"""Test is_verified can be updated."""
|
||||
update = VendorUpdate(is_verified=True)
|
||||
assert update.is_verified is True
|
||||
|
||||
def test_reset_contact_to_company_flag(self):
|
||||
"""Test reset_contact_to_company flag."""
|
||||
update = VendorUpdate(reset_contact_to_company=True)
|
||||
assert update.reset_contact_to_company is True
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.schema
|
||||
class TestVendorResponseSchema:
|
||||
"""Test VendorResponse schema."""
|
||||
|
||||
def test_from_dict(self):
|
||||
"""Test creating response from dict."""
|
||||
from datetime import datetime
|
||||
|
||||
data = {
|
||||
"id": 1,
|
||||
"vendor_code": "TECHSTORE",
|
||||
"subdomain": "techstore",
|
||||
"name": "Tech Store",
|
||||
"description": "Best tech store",
|
||||
"company_id": 1,
|
||||
"letzshop_csv_url_fr": None,
|
||||
"letzshop_csv_url_en": None,
|
||||
"letzshop_csv_url_de": None,
|
||||
"is_active": True,
|
||||
"is_verified": False,
|
||||
"created_at": datetime.now(),
|
||||
"updated_at": datetime.now(),
|
||||
}
|
||||
response = VendorResponse(**data)
|
||||
assert response.id == 1
|
||||
assert response.vendor_code == "TECHSTORE"
|
||||
assert response.is_active is True
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.schema
|
||||
class TestVendorDetailResponseSchema:
|
||||
"""Test VendorDetailResponse schema."""
|
||||
|
||||
def test_from_dict(self):
|
||||
"""Test creating detail response from dict."""
|
||||
from datetime import datetime
|
||||
|
||||
data = {
|
||||
"id": 1,
|
||||
"vendor_code": "TECHSTORE",
|
||||
"subdomain": "techstore",
|
||||
"name": "Tech Store",
|
||||
"description": None,
|
||||
"company_id": 1,
|
||||
"letzshop_csv_url_fr": None,
|
||||
"letzshop_csv_url_en": None,
|
||||
"letzshop_csv_url_de": None,
|
||||
"is_active": True,
|
||||
"is_verified": True,
|
||||
"created_at": datetime.now(),
|
||||
"updated_at": datetime.now(),
|
||||
# Additional detail fields
|
||||
"company_name": "Tech Corp",
|
||||
"owner_email": "owner@techcorp.com",
|
||||
"owner_username": "owner",
|
||||
"contact_email": "contact@techstore.com",
|
||||
"contact_email_inherited": False,
|
||||
}
|
||||
response = VendorDetailResponse(**data)
|
||||
assert response.company_name == "Tech Corp"
|
||||
assert response.owner_email == "owner@techcorp.com"
|
||||
assert response.contact_email_inherited is False
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.schema
|
||||
class TestVendorListResponseSchema:
|
||||
"""Test VendorListResponse schema."""
|
||||
|
||||
def test_valid_list_response(self):
|
||||
"""Test valid list response structure."""
|
||||
response = VendorListResponse(
|
||||
vendors=[],
|
||||
total=0,
|
||||
skip=0,
|
||||
limit=10,
|
||||
)
|
||||
assert response.vendors == []
|
||||
assert response.total == 0
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.schema
|
||||
class TestVendorSummarySchema:
|
||||
"""Test VendorSummary schema."""
|
||||
|
||||
def test_from_dict(self):
|
||||
"""Test creating summary from dict."""
|
||||
data = {
|
||||
"id": 1,
|
||||
"vendor_code": "TECHSTORE",
|
||||
"subdomain": "techstore",
|
||||
"name": "Tech Store",
|
||||
"company_id": 1,
|
||||
"is_active": True,
|
||||
}
|
||||
summary = VendorSummary(**data)
|
||||
assert summary.id == 1
|
||||
assert summary.vendor_code == "TECHSTORE"
|
||||
assert summary.is_active is True
|
||||
Reference in New Issue
Block a user