test: update tests for multi-language translation support
- Update marketplace_product_fixtures to create translations - Update test_marketplace_product.py for translation-based titles - Update test_product.py for effective property tests - Update test_order.py to use get_title() method - Add comprehensive CSV processor tests for translations - Update stats service tests for new flat response structure - Fix product schema tests with required marketplace_product_id field - Add helper function create_marketplace_product_with_translation() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,24 @@ import pytest
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
from models.database.marketplace_product_translation import MarketplaceProductTranslation
|
||||
|
||||
|
||||
def _create_with_translation(db, marketplace_product_id, title, **kwargs):
|
||||
"""Helper to create MarketplaceProduct with translation."""
|
||||
mp = MarketplaceProduct(marketplace_product_id=marketplace_product_id, **kwargs)
|
||||
db.add(mp)
|
||||
db.flush()
|
||||
|
||||
translation = MarketplaceProductTranslation(
|
||||
marketplace_product_id=mp.id,
|
||||
language="en",
|
||||
title=title,
|
||||
)
|
||||
db.add(translation)
|
||||
db.commit()
|
||||
db.refresh(mp)
|
||||
return mp
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@@ -13,10 +31,10 @@ class TestMarketplaceProductModel:
|
||||
|
||||
def test_marketplace_product_creation(self, db):
|
||||
"""Test MarketplaceProduct model creation."""
|
||||
marketplace_product = MarketplaceProduct(
|
||||
marketplace_product = _create_with_translation(
|
||||
db,
|
||||
marketplace_product_id="DB_TEST_001",
|
||||
title="Database Test Product",
|
||||
description="Testing product model",
|
||||
price="25.99",
|
||||
currency="USD",
|
||||
brand="DBTest",
|
||||
@@ -26,42 +44,36 @@ class TestMarketplaceProductModel:
|
||||
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.get_title("en") == "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(
|
||||
_create_with_translation(
|
||||
db,
|
||||
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(
|
||||
_create_with_translation(
|
||||
db,
|
||||
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 = _create_with_translation(
|
||||
db,
|
||||
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",
|
||||
@@ -78,16 +90,12 @@ class TestMarketplaceProductModel:
|
||||
pattern="solid",
|
||||
size="M",
|
||||
google_product_category="Apparel & Accessories",
|
||||
product_type="Clothing",
|
||||
product_type_raw="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"
|
||||
@@ -95,7 +103,8 @@ class TestMarketplaceProductModel:
|
||||
|
||||
def test_marketplace_product_custom_labels(self, db):
|
||||
"""Test MarketplaceProduct with custom labels."""
|
||||
marketplace_product = MarketplaceProduct(
|
||||
marketplace_product = _create_with_translation(
|
||||
db,
|
||||
marketplace_product_id="LABELS_001",
|
||||
title="Labeled Product",
|
||||
marketplace="Letzshop",
|
||||
@@ -106,26 +115,127 @@ class TestMarketplaceProductModel:
|
||||
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 = _create_with_translation(
|
||||
db,
|
||||
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.get_title("en") == "Minimal Product"
|
||||
assert marketplace_product.get_description("en") is None
|
||||
assert marketplace_product.price is None
|
||||
|
||||
def test_marketplace_product_digital_fields(self, db):
|
||||
"""Test MarketplaceProduct with digital product fields."""
|
||||
marketplace_product = _create_with_translation(
|
||||
db,
|
||||
marketplace_product_id="DIGITAL_001",
|
||||
title="Digital Product",
|
||||
product_type_enum="digital",
|
||||
is_digital=True,
|
||||
digital_delivery_method="license_key",
|
||||
platform="steam",
|
||||
region_restrictions=["EU", "US"],
|
||||
license_type="single_use",
|
||||
)
|
||||
|
||||
assert marketplace_product.product_type_enum == "digital"
|
||||
assert marketplace_product.is_digital is True
|
||||
assert marketplace_product.digital_delivery_method == "license_key"
|
||||
assert marketplace_product.platform == "steam"
|
||||
assert marketplace_product.region_restrictions == ["EU", "US"]
|
||||
assert marketplace_product.license_type == "single_use"
|
||||
|
||||
def test_marketplace_product_translation_methods(self, db):
|
||||
"""Test translation helper methods."""
|
||||
mp = MarketplaceProduct(marketplace_product_id="TRANS_001")
|
||||
db.add(mp)
|
||||
db.flush()
|
||||
|
||||
# Add English translation
|
||||
en_trans = MarketplaceProductTranslation(
|
||||
marketplace_product_id=mp.id,
|
||||
language="en",
|
||||
title="English Title",
|
||||
description="English Description",
|
||||
)
|
||||
db.add(en_trans)
|
||||
|
||||
# Add French translation
|
||||
fr_trans = MarketplaceProductTranslation(
|
||||
marketplace_product_id=mp.id,
|
||||
language="fr",
|
||||
title="Titre Français",
|
||||
description="Description Française",
|
||||
)
|
||||
db.add(fr_trans)
|
||||
db.commit()
|
||||
db.refresh(mp)
|
||||
|
||||
assert mp.get_title("en") == "English Title"
|
||||
assert mp.get_title("fr") == "Titre Français"
|
||||
assert mp.get_description("en") == "English Description"
|
||||
assert mp.get_description("fr") == "Description Française"
|
||||
|
||||
# Test fallback to English for unknown language
|
||||
assert mp.get_title("de") == "English Title" # Falls back to 'en'
|
||||
assert mp.get_description("de") == "English Description"
|
||||
|
||||
def test_marketplace_product_numeric_prices(self, db):
|
||||
"""Test numeric price fields."""
|
||||
marketplace_product = _create_with_translation(
|
||||
db,
|
||||
marketplace_product_id="PRICES_001",
|
||||
title="Priced Product",
|
||||
price="99.99 EUR",
|
||||
price_numeric=99.99,
|
||||
sale_price="79.99 EUR",
|
||||
sale_price_numeric=79.99,
|
||||
)
|
||||
|
||||
assert marketplace_product.price == "99.99 EUR"
|
||||
assert marketplace_product.price_numeric == 99.99
|
||||
assert marketplace_product.sale_price_numeric == 79.99
|
||||
assert marketplace_product.effective_price == 99.99
|
||||
assert marketplace_product.effective_sale_price == 79.99
|
||||
|
||||
def test_marketplace_product_attributes_json(self, db):
|
||||
"""Test flexible attributes JSON field."""
|
||||
marketplace_product = _create_with_translation(
|
||||
db,
|
||||
marketplace_product_id="ATTRS_001",
|
||||
title="Product with Attributes",
|
||||
attributes={
|
||||
"custom_field": "custom_value",
|
||||
"nested": {"key": "value"},
|
||||
},
|
||||
)
|
||||
|
||||
assert marketplace_product.attributes["custom_field"] == "custom_value"
|
||||
assert marketplace_product.attributes["nested"]["key"] == "value"
|
||||
|
||||
def test_marketplace_product_all_images_property(self, db):
|
||||
"""Test all_images property."""
|
||||
marketplace_product = _create_with_translation(
|
||||
db,
|
||||
marketplace_product_id="IMAGES_001",
|
||||
title="Product with Images",
|
||||
image_link="https://example.com/main.jpg",
|
||||
additional_images=[
|
||||
"https://example.com/img1.jpg",
|
||||
"https://example.com/img2.jpg",
|
||||
],
|
||||
)
|
||||
|
||||
images = marketplace_product.all_images
|
||||
assert len(images) == 3
|
||||
assert images[0] == "https://example.com/main.jpg"
|
||||
assert "https://example.com/img1.jpg" in images
|
||||
assert "https://example.com/img2.jpg" in images
|
||||
|
||||
@@ -152,11 +152,14 @@ class TestOrderItemModel:
|
||||
|
||||
def test_order_item_creation(self, db, test_order, test_product):
|
||||
"""Test OrderItem model."""
|
||||
# Get title from translation
|
||||
product_title = test_product.marketplace_product.get_title("en")
|
||||
|
||||
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",
|
||||
product_name=product_title,
|
||||
product_sku=test_product.vendor_sku or "SKU001",
|
||||
quantity=2,
|
||||
unit_price=49.99,
|
||||
total_price=99.98,
|
||||
|
||||
@@ -16,7 +16,7 @@ class TestProductModel:
|
||||
product = Product(
|
||||
vendor_id=test_vendor.id,
|
||||
marketplace_product_id=test_marketplace_product.id,
|
||||
product_id="VENDOR_PROD_001",
|
||||
vendor_sku="VENDOR_PROD_001",
|
||||
price=89.99,
|
||||
currency="EUR",
|
||||
availability="in stock",
|
||||
@@ -34,7 +34,11 @@ class TestProductModel:
|
||||
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
|
||||
# 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."""
|
||||
@@ -76,7 +80,7 @@ class TestProductModel:
|
||||
product = Product(
|
||||
vendor_id=test_vendor.id,
|
||||
marketplace_product_id=test_marketplace_product.id,
|
||||
product_id="CUSTOM_SKU_001",
|
||||
vendor_sku="CUSTOM_SKU_001",
|
||||
price=49.99,
|
||||
sale_price=39.99,
|
||||
currency="USD",
|
||||
@@ -87,7 +91,7 @@ class TestProductModel:
|
||||
db.commit()
|
||||
db.refresh(product)
|
||||
|
||||
assert product.product_id == "CUSTOM_SKU_001"
|
||||
assert product.vendor_sku == "CUSTOM_SKU_001"
|
||||
assert product.price == 49.99
|
||||
assert product.sale_price == 39.99
|
||||
assert product.currency == "USD"
|
||||
@@ -121,3 +125,99 @@ class TestProductModel:
|
||||
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"
|
||||
|
||||
@@ -157,12 +157,13 @@ class TestProductResponseSchema:
|
||||
"vendor_id": 1,
|
||||
"marketplace_product": {
|
||||
"id": 1,
|
||||
"marketplace_product_id": "TEST001", # Required field
|
||||
"gtin": "1234567890123",
|
||||
"title": "Test Product",
|
||||
"description": "A test product",
|
||||
"brand": "Test Brand",
|
||||
"category": "Electronics",
|
||||
"image_url": "https://example.com/image.jpg",
|
||||
"google_product_category": "Electronics",
|
||||
"image_link": "https://example.com/image.jpg",
|
||||
"created_at": datetime.now(),
|
||||
"updated_at": datetime.now(),
|
||||
},
|
||||
@@ -194,12 +195,13 @@ class TestProductResponseSchema:
|
||||
"vendor_id": 1,
|
||||
"marketplace_product": {
|
||||
"id": 1,
|
||||
"marketplace_product_id": "TEST002", # Required field
|
||||
"gtin": "1234567890123",
|
||||
"title": "Test Product",
|
||||
"description": None,
|
||||
"brand": None,
|
||||
"category": None,
|
||||
"image_url": None,
|
||||
"google_product_category": None,
|
||||
"image_link": None,
|
||||
"created_at": datetime.now(),
|
||||
"updated_at": datetime.now(),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user