test: update service tests for fixture and API changes
Updates to work with refactored fixtures (no expunge): - Re-query entities when modifying state in tests - Remove assertions on expunged object properties Auth service tests: - Update to use email_or_username field instead of username Admin service tests: - Fix statistics test to use stats_service module - Remove vendor_name filter test (field removed) - Update import job assertions Inventory/Marketplace/Stats/Vendor service tests: - Refactor to work with attached session objects - Update assertions for changed response formats - Improve test isolation and cleanup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,24 +1,33 @@
|
||||
# tests/test_stats_service.py
|
||||
import pytest
|
||||
# tests/unit/services/test_stats_service.py
|
||||
"""Unit tests for StatsService following the application's testing patterns."""
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from app.exceptions import AdminOperationException, VendorNotFoundException
|
||||
from app.services.stats_service import StatsService
|
||||
from models.database.inventory import Inventory
|
||||
from models.database.marketplace_import_job import MarketplaceImportJob
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
from models.database.product import Product
|
||||
from models.database.vendor import Vendor
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.stats
|
||||
class TestStatsService:
|
||||
"""Test suite for StatsService following the application's testing patterns"""
|
||||
"""Test suite for StatsService following the application's testing patterns."""
|
||||
|
||||
def setup_method(self):
|
||||
"""Setup method following the same pattern as other service tests"""
|
||||
"""Setup method following the same pattern as other service tests."""
|
||||
self.service = StatsService()
|
||||
|
||||
def test_get_comprehensive_stats_basic(
|
||||
self, db, test_marketplace_product, test_inventory
|
||||
):
|
||||
"""Test getting comprehensive stats with basic data"""
|
||||
# ==================== get_comprehensive_stats Tests ====================
|
||||
|
||||
def test_get_comprehensive_stats_basic(self, db, test_marketplace_product):
|
||||
"""Test getting comprehensive stats with basic data."""
|
||||
stats = self.service.get_comprehensive_stats(db)
|
||||
|
||||
assert "total_products" in stats
|
||||
@@ -29,18 +38,29 @@ class TestStatsService:
|
||||
assert "total_inventory_entries" in stats
|
||||
assert "total_inventory_quantity" in stats
|
||||
|
||||
assert stats["total_products"] >= 1
|
||||
assert stats["total_inventory_entries"] >= 1
|
||||
assert stats["total_inventory_quantity"] >= 10 # test_inventory has quantity 10
|
||||
# Verify types
|
||||
assert isinstance(stats["total_products"], int)
|
||||
assert isinstance(stats["unique_brands"], int)
|
||||
assert isinstance(stats["unique_categories"], int)
|
||||
assert isinstance(stats["unique_marketplaces"], int)
|
||||
assert isinstance(stats["unique_vendors"], int)
|
||||
assert isinstance(stats["total_inventory_entries"], int)
|
||||
assert isinstance(stats["total_inventory_quantity"], int)
|
||||
|
||||
def test_get_comprehensive_stats_multiple_products(
|
||||
def test_get_comprehensive_stats_with_products(self, db, test_product):
|
||||
"""Test comprehensive stats counts Product records correctly."""
|
||||
stats = self.service.get_comprehensive_stats(db)
|
||||
|
||||
assert stats["total_products"] >= 1
|
||||
|
||||
def test_get_comprehensive_stats_multiple_marketplaces(
|
||||
self, db, test_marketplace_product
|
||||
):
|
||||
"""Test comprehensive stats with multiple products across different dimensions"""
|
||||
# Create products with different brands, categories, marketplaces
|
||||
"""Test comprehensive stats with multiple marketplaces."""
|
||||
unique_id = str(uuid.uuid4())[:8]
|
||||
additional_products = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="PROD002",
|
||||
marketplace_product_id=f"PROD002_{unique_id}",
|
||||
title="MarketplaceProduct 2",
|
||||
brand="DifferentBrand",
|
||||
google_product_category="Different Category",
|
||||
@@ -50,7 +70,7 @@ class TestStatsService:
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="PROD003",
|
||||
marketplace_product_id=f"PROD003_{unique_id}",
|
||||
title="MarketplaceProduct 3",
|
||||
brand="ThirdBrand",
|
||||
google_product_category="Third Category",
|
||||
@@ -59,49 +79,36 @@ class TestStatsService:
|
||||
price="25.99",
|
||||
currency="USD",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="PROD004",
|
||||
title="MarketplaceProduct 4",
|
||||
brand="TestBrand", # Same as test_marketplace_product
|
||||
google_product_category="Different Category",
|
||||
marketplace="Letzshop", # Same as test_marketplace_product
|
||||
vendor_name="DifferentVendor",
|
||||
price="35.99",
|
||||
currency="EUR",
|
||||
),
|
||||
]
|
||||
db.add_all(additional_products)
|
||||
db.commit()
|
||||
|
||||
stats = self.service.get_comprehensive_stats(db)
|
||||
|
||||
assert stats["total_products"] >= 4 # test_marketplace_product + 3 additional
|
||||
assert stats["unique_brands"] >= 3 # TestBrand, DifferentBrand, ThirdBrand
|
||||
assert stats["unique_categories"] >= 2 # At least 2 different categories
|
||||
# Should count unique marketplaces from MarketplaceProduct table
|
||||
assert stats["unique_marketplaces"] >= 3 # Letzshop, Amazon, eBay
|
||||
assert stats["unique_vendors"] >= 3 # At least 3 different vendors
|
||||
|
||||
def test_get_comprehensive_stats_handles_nulls(self, db):
|
||||
"""Test comprehensive stats handles null/empty values correctly"""
|
||||
# Create products with null/empty values
|
||||
"""Test comprehensive stats handles null/empty values correctly."""
|
||||
unique_id = str(uuid.uuid4())[:8]
|
||||
products_with_nulls = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="NULL001",
|
||||
marketplace_product_id=f"NULL001_{unique_id}",
|
||||
title="MarketplaceProduct with Nulls",
|
||||
brand=None, # Null brand
|
||||
google_product_category=None, # Null category
|
||||
marketplace=None, # Null marketplace
|
||||
vendor_name=None, # Null vendor
|
||||
brand=None,
|
||||
google_product_category=None,
|
||||
marketplace=None,
|
||||
vendor_name=None,
|
||||
price="10.00",
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="EMPTY001",
|
||||
marketplace_product_id=f"EMPTY001_{unique_id}",
|
||||
title="MarketplaceProduct with Empty Values",
|
||||
brand="", # Empty brand
|
||||
google_product_category="", # Empty category
|
||||
marketplace="", # Empty marketplace
|
||||
vendor_name="", # Empty vendor
|
||||
brand="",
|
||||
google_product_category="",
|
||||
marketplace="",
|
||||
vendor_name="",
|
||||
price="15.00",
|
||||
currency="EUR",
|
||||
),
|
||||
@@ -111,16 +118,34 @@ class TestStatsService:
|
||||
|
||||
stats = self.service.get_comprehensive_stats(db)
|
||||
|
||||
# These products shouldn't contribute to unique counts due to null/empty values
|
||||
assert stats["total_products"] >= 2
|
||||
# Brands, categories, marketplaces, vendors should not count null/empty values
|
||||
# Should not throw error - null/empty values handled gracefully
|
||||
assert isinstance(stats["unique_brands"], int)
|
||||
assert isinstance(stats["unique_categories"], int)
|
||||
assert isinstance(stats["unique_marketplaces"], int)
|
||||
assert isinstance(stats["unique_vendors"], int)
|
||||
|
||||
def test_get_comprehensive_stats_empty_database(self, db):
|
||||
"""Test stats with empty database."""
|
||||
stats = self.service.get_comprehensive_stats(db)
|
||||
|
||||
assert stats["total_products"] == 0
|
||||
assert stats["unique_brands"] == 0
|
||||
assert stats["unique_categories"] == 0
|
||||
assert stats["unique_marketplaces"] == 0
|
||||
assert stats["total_inventory_entries"] == 0
|
||||
assert stats["total_inventory_quantity"] == 0
|
||||
|
||||
def test_get_comprehensive_stats_database_error(self, db):
|
||||
"""Test comprehensive stats handles database errors."""
|
||||
with patch.object(db, "query", side_effect=SQLAlchemyError("DB Error")):
|
||||
with pytest.raises(AdminOperationException) as exc_info:
|
||||
self.service.get_comprehensive_stats(db)
|
||||
|
||||
assert exc_info.value.details.get("operation") == "get_comprehensive_stats"
|
||||
|
||||
# ==================== get_marketplace_breakdown_stats Tests ====================
|
||||
|
||||
def test_get_marketplace_breakdown_stats_basic(self, db, test_marketplace_product):
|
||||
"""Test getting marketplace breakdown stats with basic data"""
|
||||
"""Test getting marketplace breakdown stats with basic data."""
|
||||
stats = self.service.get_marketplace_breakdown_stats(db)
|
||||
|
||||
assert isinstance(stats, list)
|
||||
@@ -137,17 +162,17 @@ class TestStatsService:
|
||||
)
|
||||
assert test_marketplace_stat is not None
|
||||
assert test_marketplace_stat["total_products"] >= 1
|
||||
assert test_marketplace_stat["unique_vendors"] >= 1
|
||||
assert test_marketplace_stat["unique_brands"] >= 1
|
||||
assert "unique_vendors" in test_marketplace_stat
|
||||
assert "unique_brands" in test_marketplace_stat
|
||||
|
||||
def test_get_marketplace_breakdown_stats_multiple_marketplaces(
|
||||
self, db, test_marketplace_product
|
||||
):
|
||||
"""Test marketplace breakdown with multiple marketplaces"""
|
||||
# Create products for different marketplaces
|
||||
"""Test marketplace breakdown with multiple marketplaces."""
|
||||
unique_id = str(uuid.uuid4())[:8]
|
||||
marketplace_products = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="AMAZON001",
|
||||
marketplace_product_id=f"AMAZON001_{unique_id}",
|
||||
title="Amazon MarketplaceProduct 1",
|
||||
brand="AmazonBrand1",
|
||||
marketplace="Amazon",
|
||||
@@ -156,7 +181,7 @@ class TestStatsService:
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="AMAZON002",
|
||||
marketplace_product_id=f"AMAZON002_{unique_id}",
|
||||
title="Amazon MarketplaceProduct 2",
|
||||
brand="AmazonBrand2",
|
||||
marketplace="Amazon",
|
||||
@@ -165,7 +190,7 @@ class TestStatsService:
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="EBAY001",
|
||||
marketplace_product_id=f"EBAY001_{unique_id}",
|
||||
title="eBay MarketplaceProduct",
|
||||
brand="eBayBrand",
|
||||
marketplace="eBay",
|
||||
@@ -179,29 +204,27 @@ class TestStatsService:
|
||||
|
||||
stats = self.service.get_marketplace_breakdown_stats(db)
|
||||
|
||||
# Should have at least 3 marketplaces: test_marketplace_product.marketplace, Amazon, eBay
|
||||
marketplace_names = [stat["marketplace"] for stat in stats]
|
||||
assert "Amazon" in marketplace_names
|
||||
assert "eBay" in marketplace_names
|
||||
assert test_marketplace_product.marketplace in marketplace_names
|
||||
|
||||
# Check Amazon stats specifically
|
||||
# Check Amazon stats
|
||||
amazon_stat = next(stat for stat in stats if stat["marketplace"] == "Amazon")
|
||||
assert amazon_stat["total_products"] == 2
|
||||
assert amazon_stat["unique_vendors"] == 2
|
||||
assert amazon_stat["unique_brands"] == 2
|
||||
|
||||
# Check eBay stats specifically
|
||||
# Check eBay stats
|
||||
ebay_stat = next(stat for stat in stats if stat["marketplace"] == "eBay")
|
||||
assert ebay_stat["total_products"] == 1
|
||||
assert ebay_stat["unique_vendors"] == 1
|
||||
assert ebay_stat["unique_brands"] == 1
|
||||
|
||||
def test_get_marketplace_breakdown_stats_excludes_nulls(self, db):
|
||||
"""Test marketplace breakdown excludes products with null marketplaces"""
|
||||
# Create product with null marketplace
|
||||
"""Test marketplace breakdown excludes products with null marketplaces."""
|
||||
unique_id = str(uuid.uuid4())[:8]
|
||||
null_marketplace_product = MarketplaceProduct(
|
||||
marketplace_product_id="NULLMARKET001",
|
||||
marketplace_product_id=f"NULLMARKET001_{unique_id}",
|
||||
title="MarketplaceProduct without marketplace",
|
||||
marketplace=None,
|
||||
vendor_name="SomeVendor",
|
||||
@@ -220,19 +243,219 @@ class TestStatsService:
|
||||
]
|
||||
assert None not in marketplace_names
|
||||
|
||||
def test_get_product_count(self, db, test_marketplace_product):
|
||||
"""Test getting total product count"""
|
||||
count = self.service._get_product_count(db)
|
||||
def test_get_marketplace_breakdown_empty_database(self, db):
|
||||
"""Test marketplace breakdown with empty database."""
|
||||
stats = self.service.get_marketplace_breakdown_stats(db)
|
||||
|
||||
assert count >= 1
|
||||
assert isinstance(count, int)
|
||||
assert isinstance(stats, list)
|
||||
assert len(stats) == 0
|
||||
|
||||
def test_get_marketplace_breakdown_stats_database_error(self, db):
|
||||
"""Test marketplace breakdown handles database errors."""
|
||||
with patch.object(db, "query", side_effect=SQLAlchemyError("DB Error")):
|
||||
with pytest.raises(AdminOperationException) as exc_info:
|
||||
self.service.get_marketplace_breakdown_stats(db)
|
||||
|
||||
assert exc_info.value.details.get("operation") == "get_marketplace_breakdown_stats"
|
||||
|
||||
# ==================== get_vendor_stats Tests ====================
|
||||
|
||||
def test_get_vendor_stats_success(self, db, test_vendor, test_product):
|
||||
"""Test getting vendor statistics successfully."""
|
||||
stats = self.service.get_vendor_stats(db, test_vendor.id)
|
||||
|
||||
assert "catalog" in stats
|
||||
assert "staging" in stats
|
||||
assert "inventory" in stats
|
||||
assert "imports" in stats
|
||||
assert "orders" in stats
|
||||
assert "customers" in stats
|
||||
|
||||
assert stats["catalog"]["total_products"] >= 0
|
||||
assert stats["inventory"]["total_quantity"] >= 0
|
||||
|
||||
def test_get_vendor_stats_vendor_not_found(self, db):
|
||||
"""Test vendor stats with non-existent vendor."""
|
||||
with pytest.raises(VendorNotFoundException):
|
||||
self.service.get_vendor_stats(db, 99999)
|
||||
|
||||
def test_get_vendor_stats_with_inventory(
|
||||
self, db, test_vendor, test_product, test_inventory
|
||||
):
|
||||
"""Test vendor stats includes inventory data."""
|
||||
stats = self.service.get_vendor_stats(db, test_vendor.id)
|
||||
|
||||
assert stats["inventory"]["total_quantity"] >= test_inventory.quantity
|
||||
assert stats["inventory"]["reserved_quantity"] >= 0
|
||||
|
||||
def test_get_vendor_stats_database_error(self, db, test_vendor):
|
||||
"""Test vendor stats handles database errors after vendor check."""
|
||||
# Mock query to fail after first successful call (vendor check)
|
||||
original_query = db.query
|
||||
call_count = [0]
|
||||
|
||||
def mock_query(*args, **kwargs):
|
||||
call_count[0] += 1
|
||||
if call_count[0] > 1:
|
||||
raise SQLAlchemyError("DB Error")
|
||||
return original_query(*args, **kwargs)
|
||||
|
||||
with patch.object(db, "query", side_effect=mock_query):
|
||||
with pytest.raises(AdminOperationException) as exc_info:
|
||||
self.service.get_vendor_stats(db, test_vendor.id)
|
||||
|
||||
assert exc_info.value.details.get("operation") == "get_vendor_stats"
|
||||
|
||||
# ==================== get_vendor_analytics Tests ====================
|
||||
|
||||
def test_get_vendor_analytics_success(self, db, test_vendor):
|
||||
"""Test getting vendor analytics successfully."""
|
||||
analytics = self.service.get_vendor_analytics(db, test_vendor.id)
|
||||
|
||||
assert "period" in analytics
|
||||
assert "start_date" in analytics
|
||||
assert "imports" in analytics
|
||||
assert "catalog" in analytics
|
||||
assert "inventory" in analytics
|
||||
|
||||
def test_get_vendor_analytics_different_periods(self, db, test_vendor):
|
||||
"""Test vendor analytics with different time periods."""
|
||||
for period in ["7d", "30d", "90d", "1y"]:
|
||||
analytics = self.service.get_vendor_analytics(
|
||||
db, test_vendor.id, period=period
|
||||
)
|
||||
assert analytics["period"] == period
|
||||
|
||||
def test_get_vendor_analytics_vendor_not_found(self, db):
|
||||
"""Test vendor analytics with non-existent vendor."""
|
||||
with pytest.raises(VendorNotFoundException):
|
||||
self.service.get_vendor_analytics(db, 99999)
|
||||
|
||||
# ==================== get_vendor_statistics Tests ====================
|
||||
|
||||
def test_get_vendor_statistics_success(self, db, test_vendor):
|
||||
"""Test getting vendor statistics for admin dashboard."""
|
||||
stats = self.service.get_vendor_statistics(db)
|
||||
|
||||
assert "total_vendors" in stats
|
||||
assert "active_vendors" in stats
|
||||
assert "inactive_vendors" in stats
|
||||
assert "verified_vendors" in stats
|
||||
assert "verification_rate" in stats
|
||||
|
||||
assert stats["total_vendors"] >= 1
|
||||
assert stats["active_vendors"] >= 1
|
||||
|
||||
def test_get_vendor_statistics_calculates_rates(self, db, test_vendor):
|
||||
"""Test vendor statistics calculates rates correctly."""
|
||||
stats = self.service.get_vendor_statistics(db)
|
||||
|
||||
if stats["total_vendors"] > 0:
|
||||
expected_rate = (
|
||||
stats["verified_vendors"] / stats["total_vendors"] * 100
|
||||
)
|
||||
assert abs(stats["verification_rate"] - expected_rate) < 0.01
|
||||
|
||||
def test_get_vendor_statistics_database_error(self, db):
|
||||
"""Test vendor statistics handles database errors."""
|
||||
with patch.object(db, "query", side_effect=SQLAlchemyError("DB Error")):
|
||||
with pytest.raises(AdminOperationException) as exc_info:
|
||||
self.service.get_vendor_statistics(db)
|
||||
|
||||
assert exc_info.value.details.get("operation") == "get_vendor_statistics"
|
||||
|
||||
# ==================== get_user_statistics Tests ====================
|
||||
|
||||
def test_get_user_statistics_success(self, db, test_user):
|
||||
"""Test getting user statistics."""
|
||||
stats = self.service.get_user_statistics(db)
|
||||
|
||||
assert "total_users" in stats
|
||||
assert "active_users" in stats
|
||||
assert "inactive_users" in stats
|
||||
assert "admin_users" in stats
|
||||
assert "activation_rate" in stats
|
||||
|
||||
assert stats["total_users"] >= 1
|
||||
|
||||
def test_get_user_statistics_calculates_correctly(self, db, test_user, test_admin):
|
||||
"""Test user statistics calculates values correctly."""
|
||||
stats = self.service.get_user_statistics(db)
|
||||
|
||||
assert stats["total_users"] == stats["active_users"] + stats["inactive_users"]
|
||||
assert stats["admin_users"] >= 1 # test_admin
|
||||
|
||||
def test_get_user_statistics_database_error(self, db):
|
||||
"""Test user statistics handles database errors."""
|
||||
with patch.object(db, "query", side_effect=SQLAlchemyError("DB Error")):
|
||||
with pytest.raises(AdminOperationException) as exc_info:
|
||||
self.service.get_user_statistics(db)
|
||||
|
||||
assert exc_info.value.details.get("operation") == "get_user_statistics"
|
||||
|
||||
# ==================== get_import_statistics Tests ====================
|
||||
|
||||
def test_get_import_statistics_success(self, db):
|
||||
"""Test getting import statistics."""
|
||||
stats = self.service.get_import_statistics(db)
|
||||
|
||||
assert "total_imports" in stats
|
||||
assert "completed_imports" in stats
|
||||
assert "failed_imports" in stats
|
||||
assert "success_rate" in stats
|
||||
|
||||
def test_get_import_statistics_with_jobs(
|
||||
self, db, test_vendor, test_marketplace_import_job
|
||||
):
|
||||
"""Test import statistics with existing jobs."""
|
||||
stats = self.service.get_import_statistics(db)
|
||||
|
||||
assert stats["total_imports"] >= 1
|
||||
assert stats["completed_imports"] >= 1 # test job has completed status
|
||||
|
||||
def test_get_import_statistics_calculates_rate(self, db):
|
||||
"""Test import statistics calculates success rate."""
|
||||
stats = self.service.get_import_statistics(db)
|
||||
|
||||
if stats["total_imports"] > 0:
|
||||
expected_rate = (
|
||||
stats["completed_imports"] / stats["total_imports"] * 100
|
||||
)
|
||||
assert abs(stats["success_rate"] - expected_rate) < 0.01
|
||||
else:
|
||||
assert stats["success_rate"] == 0
|
||||
|
||||
def test_get_import_statistics_handles_errors(self, db):
|
||||
"""Test import statistics returns zeros on error."""
|
||||
with patch.object(db, "query", side_effect=SQLAlchemyError("DB Error")):
|
||||
stats = self.service.get_import_statistics(db)
|
||||
|
||||
# Should return default values, not raise exception
|
||||
assert stats["total_imports"] == 0
|
||||
assert stats["completed_imports"] == 0
|
||||
assert stats["failed_imports"] == 0
|
||||
assert stats["success_rate"] == 0
|
||||
|
||||
# ==================== Private Helper Method Tests ====================
|
||||
|
||||
def test_parse_period_known_values(self):
|
||||
"""Test period parsing for known values."""
|
||||
assert self.service._parse_period("7d") == 7
|
||||
assert self.service._parse_period("30d") == 30
|
||||
assert self.service._parse_period("90d") == 90
|
||||
assert self.service._parse_period("1y") == 365
|
||||
|
||||
def test_parse_period_unknown_defaults(self):
|
||||
"""Test period parsing defaults to 30 for unknown values."""
|
||||
assert self.service._parse_period("unknown") == 30
|
||||
assert self.service._parse_period("") == 30
|
||||
|
||||
def test_get_unique_brands_count(self, db, test_marketplace_product):
|
||||
"""Test getting unique brands count"""
|
||||
# Add products with different brands
|
||||
"""Test getting unique brands count."""
|
||||
unique_id = str(uuid.uuid4())[:8]
|
||||
brand_products = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="BRAND001",
|
||||
marketplace_product_id=f"BRAND001_{unique_id}",
|
||||
title="Brand MarketplaceProduct 1",
|
||||
brand="BrandA",
|
||||
marketplace="Test",
|
||||
@@ -241,7 +464,7 @@ class TestStatsService:
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="BRAND002",
|
||||
marketplace_product_id=f"BRAND002_{unique_id}",
|
||||
title="Brand MarketplaceProduct 2",
|
||||
brand="BrandB",
|
||||
marketplace="Test",
|
||||
@@ -255,17 +478,15 @@ class TestStatsService:
|
||||
|
||||
count = self.service._get_unique_brands_count(db)
|
||||
|
||||
assert (
|
||||
count >= 2
|
||||
) # At least BrandA and BrandB, plus possibly test_marketplace_product brand
|
||||
assert count >= 2 # At least BrandA and BrandB
|
||||
assert isinstance(count, int)
|
||||
|
||||
def test_get_unique_categories_count(self, db, test_marketplace_product):
|
||||
"""Test getting unique categories count"""
|
||||
# Add products with different categories
|
||||
"""Test getting unique categories count."""
|
||||
unique_id = str(uuid.uuid4())[:8]
|
||||
category_products = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="CAT001",
|
||||
marketplace_product_id=f"CAT001_{unique_id}",
|
||||
title="Category MarketplaceProduct 1",
|
||||
google_product_category="Electronics",
|
||||
marketplace="Test",
|
||||
@@ -274,7 +495,7 @@ class TestStatsService:
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="CAT002",
|
||||
marketplace_product_id=f"CAT002_{unique_id}",
|
||||
title="Category MarketplaceProduct 2",
|
||||
google_product_category="Books",
|
||||
marketplace="Test",
|
||||
@@ -291,230 +512,35 @@ class TestStatsService:
|
||||
assert count >= 2 # At least Electronics and Books
|
||||
assert isinstance(count, int)
|
||||
|
||||
def test_get_unique_marketplaces_count(self, db, test_marketplace_product):
|
||||
"""Test getting unique marketplaces count"""
|
||||
# Add products with different marketplaces
|
||||
marketplace_products = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="MARKET001",
|
||||
title="Marketplace MarketplaceProduct 1",
|
||||
marketplace="Amazon",
|
||||
vendor_name="AmazonVendor",
|
||||
price="10.00",
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="MARKET002",
|
||||
title="Marketplace MarketplaceProduct 2",
|
||||
marketplace="eBay",
|
||||
vendor_name="eBayVendor",
|
||||
price="15.00",
|
||||
currency="EUR",
|
||||
),
|
||||
]
|
||||
db.add_all(marketplace_products)
|
||||
db.commit()
|
||||
|
||||
count = self.service._get_unique_marketplaces_count(db)
|
||||
|
||||
assert (
|
||||
count >= 2
|
||||
) # At least Amazon and eBay, plus test_marketplace_product marketplace
|
||||
assert isinstance(count, int)
|
||||
|
||||
def test_get_unique_vendors_count(self, db, test_marketplace_product):
|
||||
"""Test getting unique vendors count"""
|
||||
# Add products with different vendor names
|
||||
products = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="PRODUCT001",
|
||||
title="Vendor MarketplaceProduct 1",
|
||||
marketplace="Test",
|
||||
vendor_name="VendorA",
|
||||
price="10.00",
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="PRODUCT002",
|
||||
title="Vendor MarketplaceProduct 2",
|
||||
marketplace="Test",
|
||||
vendor_name="VendorB",
|
||||
price="15.00",
|
||||
currency="EUR",
|
||||
),
|
||||
]
|
||||
db.add_all(products)
|
||||
db.commit()
|
||||
|
||||
count = self.service._get_unique_vendors_count(db)
|
||||
|
||||
assert (
|
||||
count >= 2
|
||||
) # At least VendorA and VendorB, plus test_marketplace_product vendor
|
||||
assert isinstance(count, int)
|
||||
|
||||
def test_get_inventory_statistics(self, db, test_inventory):
|
||||
"""Test getting inventory statistics"""
|
||||
# Add additional inventory entries
|
||||
additional_inventory = [
|
||||
Inventory(
|
||||
gtin="1234567890124",
|
||||
location="LOCATION2",
|
||||
quantity=25,
|
||||
reserved_quantity=5,
|
||||
vendor_id=test_inventory.vendor_id,
|
||||
),
|
||||
Inventory(
|
||||
gtin="1234567890125",
|
||||
location="LOCATION3",
|
||||
quantity=0, # Out of inventory
|
||||
reserved_quantity=0,
|
||||
vendor_id=test_inventory.vendor_id,
|
||||
),
|
||||
]
|
||||
db.add_all(additional_inventory)
|
||||
db.commit()
|
||||
|
||||
stats = self.service.get_inventory_statistics(db)
|
||||
|
||||
assert "total_inventory_entries" in stats
|
||||
assert "total_inventory_quantity" in stats
|
||||
assert stats["total_inventory_entries"] >= 3 # test_inventory + 2 additional
|
||||
assert stats["total_inventory_quantity"] >= 35 # 10 + 25 + 0 = 35
|
||||
|
||||
def test_get_brands_by_marketplace(self, db):
|
||||
"""Test getting brands for a specific marketplace"""
|
||||
# Create products for specific marketplace
|
||||
marketplace_products = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="SPECIFIC001",
|
||||
title="Specific MarketplaceProduct 1",
|
||||
brand="SpecificBrand1",
|
||||
marketplace="SpecificMarket",
|
||||
vendor_name="SpecificVendor1",
|
||||
price="10.00",
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="SPECIFIC002",
|
||||
title="Specific MarketplaceProduct 2",
|
||||
brand="SpecificBrand2",
|
||||
marketplace="SpecificMarket",
|
||||
vendor_name="SpecificVendor2",
|
||||
price="15.00",
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="OTHER001",
|
||||
title="Other MarketplaceProduct",
|
||||
brand="OtherBrand",
|
||||
marketplace="OtherMarket",
|
||||
vendor_name="OtherVendor",
|
||||
price="20.00",
|
||||
currency="EUR",
|
||||
),
|
||||
]
|
||||
db.add_all(marketplace_products)
|
||||
db.commit()
|
||||
|
||||
brands = self.service._get_brands_by_marketplace(db, "SpecificMarket")
|
||||
|
||||
assert len(brands) == 2
|
||||
assert "SpecificBrand1" in brands
|
||||
assert "SpecificBrand2" in brands
|
||||
assert "OtherBrand" not in brands
|
||||
|
||||
def test_get_vendors_by_marketplace(self, db):
|
||||
"""Test getting vendors for a specific marketplace"""
|
||||
# Create products for specific marketplace
|
||||
marketplace_products = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="MARKETTEST001",
|
||||
title="Vendor Test MarketplaceProduct 1",
|
||||
brand="TestBrand",
|
||||
marketplace="TestMarketplace",
|
||||
vendor_name="TestVendor1",
|
||||
price="10.00",
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="MARKETTEST002",
|
||||
title="Vendor Test MarketplaceProduct 2",
|
||||
brand="TestBrand",
|
||||
marketplace="TestMarketplace",
|
||||
vendor_name="TestVendor2",
|
||||
price="15.00",
|
||||
currency="EUR",
|
||||
),
|
||||
]
|
||||
db.add_all(marketplace_products)
|
||||
db.commit()
|
||||
|
||||
vendors = self.service._get_vendors_by_marketplace(db, "TestMarketplace")
|
||||
|
||||
assert len(vendors) == 2
|
||||
assert "TestVendor1" in vendors
|
||||
assert "TestVendor2" in vendors
|
||||
|
||||
def test_get_products_by_marketplace(self, db):
|
||||
"""Test getting product count for a specific marketplace"""
|
||||
# Create products for specific marketplace
|
||||
marketplace_products = [
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="COUNT001",
|
||||
title="Count MarketplaceProduct 1",
|
||||
marketplace="CountMarketplace",
|
||||
vendor_name="CountVendor",
|
||||
price="10.00",
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="COUNT002",
|
||||
title="Count MarketplaceProduct 2",
|
||||
marketplace="CountMarketplace",
|
||||
vendor_name="CountVendor",
|
||||
price="15.00",
|
||||
currency="EUR",
|
||||
),
|
||||
MarketplaceProduct(
|
||||
marketplace_product_id="COUNT003",
|
||||
title="Count MarketplaceProduct 3",
|
||||
marketplace="CountMarketplace",
|
||||
vendor_name="CountVendor",
|
||||
price="20.00",
|
||||
currency="EUR",
|
||||
),
|
||||
]
|
||||
db.add_all(marketplace_products)
|
||||
db.commit()
|
||||
|
||||
count = self.service._get_products_by_marketplace_count(db, "CountMarketplace")
|
||||
|
||||
assert count == 3
|
||||
|
||||
def test_get_products_by_marketplace_not_found(self, db):
|
||||
"""Test getting product count for non-existent marketplace"""
|
||||
count = self.service._get_products_by_marketplace_count(
|
||||
db, "NonExistentMarketplace"
|
||||
"""Test getting inventory statistics."""
|
||||
unique_id = str(uuid.uuid4())[:8]
|
||||
additional_inventory = Inventory(
|
||||
gtin=f"123456789{unique_id[:4]}",
|
||||
location=f"LOCATION2_{unique_id}",
|
||||
quantity=25,
|
||||
reserved_quantity=5,
|
||||
vendor_id=test_inventory.vendor_id,
|
||||
product_id=test_inventory.product_id,
|
||||
)
|
||||
db.add(additional_inventory)
|
||||
db.commit()
|
||||
|
||||
assert count == 0
|
||||
stats = self.service._get_inventory_statistics(db)
|
||||
|
||||
def test_empty_database_stats(self, db):
|
||||
"""Test stats with empty database"""
|
||||
stats = self.service.get_comprehensive_stats(db)
|
||||
assert "total_entries" in stats
|
||||
assert "total_quantity" in stats
|
||||
assert "total_reserved" in stats
|
||||
assert "total_available" in stats
|
||||
|
||||
assert stats["total_products"] == 0
|
||||
assert stats["unique_brands"] == 0
|
||||
assert stats["unique_categories"] == 0
|
||||
assert stats["unique_marketplaces"] == 0
|
||||
assert stats["unique_vendors"] == 0
|
||||
assert stats["total_inventory_entries"] == 0
|
||||
assert stats["total_inventory_quantity"] == 0
|
||||
assert stats["total_entries"] >= 2
|
||||
assert stats["total_quantity"] >= test_inventory.quantity + 25
|
||||
|
||||
def test_marketplace_breakdown_empty_database(self, db):
|
||||
"""Test marketplace breakdown with empty database"""
|
||||
stats = self.service.get_marketplace_breakdown_stats(db)
|
||||
def test_get_inventory_statistics_empty(self, db):
|
||||
"""Test inventory statistics with empty database."""
|
||||
stats = self.service._get_inventory_statistics(db)
|
||||
|
||||
assert isinstance(stats, list)
|
||||
assert len(stats) == 0
|
||||
assert stats["total_entries"] == 0
|
||||
assert stats["total_quantity"] == 0
|
||||
assert stats["total_reserved"] == 0
|
||||
assert stats["total_available"] == 0
|
||||
|
||||
Reference in New Issue
Block a user