# tests/test_stats_service.py import pytest from app.services.stats_service import StatsService from models.database_models import Product, Stock class TestStatsService: """Test suite for StatsService following the application's testing patterns""" def setup_method(self): """Setup method following the same pattern as other service tests""" self.service = StatsService() def test_get_comprehensive_stats_basic(self, db, test_product, test_stock): """Test getting comprehensive stats with basic data""" stats = self.service.get_comprehensive_stats(db) assert "total_products" in stats assert "unique_brands" in stats assert "unique_categories" in stats assert "unique_marketplaces" in stats assert "unique_shops" in stats assert "total_stock_entries" in stats assert "total_inventory_quantity" in stats assert stats["total_products"] >= 1 assert stats["total_stock_entries"] >= 1 assert stats["total_inventory_quantity"] >= 10 # test_stock has quantity 10 def test_get_comprehensive_stats_multiple_products(self, db, test_product): """Test comprehensive stats with multiple products across different dimensions""" # Create products with different brands, categories, marketplaces additional_products = [ Product( product_id="PROD002", title="Product 2", brand="DifferentBrand", google_product_category="Different Category", marketplace="Amazon", shop_name="AmazonShop", price="15.99", currency="EUR" ), Product( product_id="PROD003", title="Product 3", brand="ThirdBrand", google_product_category="Third Category", marketplace="eBay", shop_name="eBayShop", price="25.99", currency="USD" ), Product( product_id="PROD004", title="Product 4", brand="TestBrand", # Same as test_product google_product_category="Different Category", marketplace="Letzshop", # Same as test_product shop_name="DifferentShop", 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_product + 3 additional assert stats["unique_brands"] >= 3 # TestBrand, DifferentBrand, ThirdBrand assert stats["unique_categories"] >= 2 # At least 2 different categories assert stats["unique_marketplaces"] >= 3 # Letzshop, Amazon, eBay assert stats["unique_shops"] >= 3 # At least 3 different shops def test_get_comprehensive_stats_handles_nulls(self, db): """Test comprehensive stats handles null/empty values correctly""" # Create products with null/empty values products_with_nulls = [ Product( product_id="NULL001", title="Product with Nulls", brand=None, # Null brand google_product_category=None, # Null category marketplace=None, # Null marketplace shop_name=None, # Null shop price="10.00", currency="EUR" ), Product( product_id="EMPTY001", title="Product with Empty Values", brand="", # Empty brand google_product_category="", # Empty category marketplace="", # Empty marketplace shop_name="", # Empty shop price="15.00", currency="EUR" ) ] db.add_all(products_with_nulls) db.commit() 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, shops should not count null/empty values assert isinstance(stats["unique_brands"], int) assert isinstance(stats["unique_categories"], int) assert isinstance(stats["unique_marketplaces"], int) assert isinstance(stats["unique_shops"], int) def test_get_marketplace_breakdown_stats_basic(self, db, test_product): """Test getting marketplace breakdown stats with basic data""" stats = self.service.get_marketplace_breakdown_stats(db) assert isinstance(stats, list) assert len(stats) >= 1 # Find our test marketplace in the results test_marketplace_stat = next( (stat for stat in stats if stat["marketplace"] == test_product.marketplace), None ) assert test_marketplace_stat is not None assert test_marketplace_stat["total_products"] >= 1 assert test_marketplace_stat["unique_shops"] >= 1 assert test_marketplace_stat["unique_brands"] >= 1 def test_get_marketplace_breakdown_stats_multiple_marketplaces(self, db, test_product): """Test marketplace breakdown with multiple marketplaces""" # Create products for different marketplaces marketplace_products = [ Product( product_id="AMAZON001", title="Amazon Product 1", brand="AmazonBrand1", marketplace="Amazon", shop_name="AmazonShop1", price="20.00", currency="EUR" ), Product( product_id="AMAZON002", title="Amazon Product 2", brand="AmazonBrand2", marketplace="Amazon", shop_name="AmazonShop2", price="25.00", currency="EUR" ), Product( product_id="EBAY001", title="eBay Product", brand="eBayBrand", marketplace="eBay", shop_name="eBayShop", price="30.00", currency="USD" ) ] db.add_all(marketplace_products) db.commit() stats = self.service.get_marketplace_breakdown_stats(db) # Should have at least 3 marketplaces: test_product.marketplace, Amazon, eBay marketplace_names = [stat["marketplace"] for stat in stats] assert "Amazon" in marketplace_names assert "eBay" in marketplace_names assert test_product.marketplace in marketplace_names # Check Amazon stats specifically amazon_stat = next(stat for stat in stats if stat["marketplace"] == "Amazon") assert amazon_stat["total_products"] == 2 assert amazon_stat["unique_shops"] == 2 assert amazon_stat["unique_brands"] == 2 # Check eBay stats specifically ebay_stat = next(stat for stat in stats if stat["marketplace"] == "eBay") assert ebay_stat["total_products"] == 1 assert ebay_stat["unique_shops"] == 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 null_marketplace_product = Product( product_id="NULLMARKET001", title="Product without marketplace", marketplace=None, shop_name="SomeShop", brand="SomeBrand", price="10.00", currency="EUR" ) db.add(null_marketplace_product) db.commit() stats = self.service.get_marketplace_breakdown_stats(db) # Should not include any stats for null marketplace marketplace_names = [stat["marketplace"] for stat in stats if stat["marketplace"] is not None] assert None not in marketplace_names def test_get_product_count(self, db, test_product): """Test getting total product count""" count = self.service.get_product_count(db) assert count >= 1 assert isinstance(count, int) def test_get_unique_brands_count(self, db, test_product): """Test getting unique brands count""" # Add products with different brands brand_products = [ Product( product_id="BRAND001", title="Brand Product 1", brand="BrandA", marketplace="Test", shop_name="TestShop", price="10.00", currency="EUR" ), Product( product_id="BRAND002", title="Brand Product 2", brand="BrandB", marketplace="Test", shop_name="TestShop", price="15.00", currency="EUR" ) ] db.add_all(brand_products) db.commit() count = self.service.get_unique_brands_count(db) assert count >= 2 # At least BrandA and BrandB, plus possibly test_product brand assert isinstance(count, int) def test_get_unique_categories_count(self, db, test_product): """Test getting unique categories count""" # Add products with different categories category_products = [ Product( product_id="CAT001", title="Category Product 1", google_product_category="Electronics", marketplace="Test", shop_name="TestShop", price="10.00", currency="EUR" ), Product( product_id="CAT002", title="Category Product 2", google_product_category="Books", marketplace="Test", shop_name="TestShop", price="15.00", currency="EUR" ) ] db.add_all(category_products) db.commit() count = self.service.get_unique_categories_count(db) assert count >= 2 # At least Electronics and Books assert isinstance(count, int) def test_get_unique_marketplaces_count(self, db, test_product): """Test getting unique marketplaces count""" # Add products with different marketplaces marketplace_products = [ Product( product_id="MARKET001", title="Marketplace Product 1", marketplace="Amazon", shop_name="AmazonShop", price="10.00", currency="EUR" ), Product( product_id="MARKET002", title="Marketplace Product 2", marketplace="eBay", shop_name="eBayShop", 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_product marketplace assert isinstance(count, int) def test_get_unique_shops_count(self, db, test_product): """Test getting unique shops count""" # Add products with different shop names shop_products = [ Product( product_id="SHOP001", title="Shop Product 1", marketplace="Test", shop_name="ShopA", price="10.00", currency="EUR" ), Product( product_id="SHOP002", title="Shop Product 2", marketplace="Test", shop_name="ShopB", price="15.00", currency="EUR" ) ] db.add_all(shop_products) db.commit() count = self.service.get_unique_shops_count(db) assert count >= 2 # At least ShopA and ShopB, plus test_product shop assert isinstance(count, int) def test_get_stock_statistics(self, db, test_stock): """Test getting stock statistics""" # Add additional stock entries additional_stocks = [ Stock( gtin="1234567890124", location="LOCATION2", quantity=25, reserved_quantity=5, shop_id=test_stock.shop_id ), Stock( gtin="1234567890125", location="LOCATION3", quantity=0, # Out of stock reserved_quantity=0, shop_id=test_stock.shop_id ) ] db.add_all(additional_stocks) db.commit() stats = self.service.get_stock_statistics(db) assert "total_stock_entries" in stats assert "total_inventory_quantity" in stats assert stats["total_stock_entries"] >= 3 # test_stock + 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 = [ Product( product_id="SPECIFIC001", title="Specific Product 1", brand="SpecificBrand1", marketplace="SpecificMarket", shop_name="SpecificShop1", price="10.00", currency="EUR" ), Product( product_id="SPECIFIC002", title="Specific Product 2", brand="SpecificBrand2", marketplace="SpecificMarket", shop_name="SpecificShop2", price="15.00", currency="EUR" ), Product( product_id="OTHER001", title="Other Product", brand="OtherBrand", marketplace="OtherMarket", shop_name="OtherShop", 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_shops_by_marketplace(self, db): """Test getting shops for a specific marketplace""" # Create products for specific marketplace marketplace_products = [ Product( product_id="SHOPTEST001", title="Shop Test Product 1", brand="TestBrand", marketplace="TestMarketplace", shop_name="TestShop1", price="10.00", currency="EUR" ), Product( product_id="SHOPTEST002", title="Shop Test Product 2", brand="TestBrand", marketplace="TestMarketplace", shop_name="TestShop2", price="15.00", currency="EUR" ) ] db.add_all(marketplace_products) db.commit() shops = self.service.get_shops_by_marketplace(db, "TestMarketplace") assert len(shops) == 2 assert "TestShop1" in shops assert "TestShop2" in shops def test_get_products_by_marketplace(self, db): """Test getting product count for a specific marketplace""" # Create products for specific marketplace marketplace_products = [ Product( product_id="COUNT001", title="Count Product 1", marketplace="CountMarketplace", shop_name="CountShop", price="10.00", currency="EUR" ), Product( product_id="COUNT002", title="Count Product 2", marketplace="CountMarketplace", shop_name="CountShop", price="15.00", currency="EUR" ), Product( product_id="COUNT003", title="Count Product 3", marketplace="CountMarketplace", shop_name="CountShop", price="20.00", currency="EUR" ) ] db.add_all(marketplace_products) db.commit() count = self.service.get_products_by_marketplace(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(db, "NonExistentMarketplace") assert count == 0 def test_empty_database_stats(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["unique_shops"] == 0 assert stats["total_stock_entries"] == 0 assert stats["total_inventory_quantity"] == 0 def test_marketplace_breakdown_empty_database(self, db): """Test marketplace breakdown with empty database""" stats = self.service.get_marketplace_breakdown_stats(db) assert isinstance(stats, list) assert len(stats) == 0