# 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, vendor_sku="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 # Use get_title() method instead of .title attribute assert ( product.marketplace_product.get_title("en") == test_marketplace_product.get_title("en") ) 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, vendor_sku="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.vendor_sku == "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 def test_product_effective_properties(self, db, test_vendor, test_marketplace_product): """Test Product effective properties with override pattern.""" # First, set some values on the marketplace product test_marketplace_product.price_numeric = 100.00 test_marketplace_product.brand = "SourceBrand" db.commit() db.refresh(test_marketplace_product) # Create product without overrides product = Product( vendor_id=test_vendor.id, marketplace_product_id=test_marketplace_product.id, ) db.add(product) db.commit() db.refresh(product) # Should inherit from marketplace product assert product.effective_price == 100.00 assert product.effective_brand == "SourceBrand" # Now override the price product.price = 89.99 db.commit() db.refresh(product) # Should use the override assert product.effective_price == 89.99 # Brand still inherited assert product.effective_brand == "SourceBrand" def test_product_reset_to_source(self, db, test_vendor, test_marketplace_product): """Test reset_to_source methods.""" # Set up marketplace product values test_marketplace_product.price_numeric = 100.00 test_marketplace_product.brand = "SourceBrand" db.commit() # Create product with overrides product = Product( vendor_id=test_vendor.id, marketplace_product_id=test_marketplace_product.id, price=89.99, brand="OverrideBrand", ) db.add(product) db.commit() db.refresh(product) assert product.effective_price == 89.99 assert product.effective_brand == "OverrideBrand" # Reset price to source product.reset_field_to_source("price") db.commit() db.refresh(product) assert product.price is None assert product.effective_price == 100.00 # Now inherits # Reset all fields product.reset_all_to_source() db.commit() db.refresh(product) assert product.brand is None assert product.effective_brand == "SourceBrand" # Now inherits def test_product_get_override_info(self, db, test_vendor, test_marketplace_product): """Test get_override_info method.""" test_marketplace_product.price_numeric = 100.00 test_marketplace_product.brand = "SourceBrand" db.commit() product = Product( vendor_id=test_vendor.id, marketplace_product_id=test_marketplace_product.id, price=89.99, # Override # brand not set - will inherit ) db.add(product) db.commit() db.refresh(product) info = product.get_override_info() # Price is overridden assert info["price"] == 89.99 assert info["price_overridden"] is True assert info["price_source"] == 100.00 # Brand is inherited assert info["brand"] == "SourceBrand" assert info["brand_overridden"] is False assert info["brand_source"] == "SourceBrand"