# tests/test_shop_service.py (simplified with fixtures) import pytest from fastapi import HTTPException from app.services.shop_service import ShopService from models.api_models import ShopCreate, ShopProductCreate class TestShopService: """Test suite for ShopService following the application's testing patterns""" def setup_method(self): """Setup method following the same pattern as admin service tests""" self.service = ShopService() def test_create_shop_success(self, db, test_user, shop_factory): """Test successful shop creation""" shop_data = ShopCreate( shop_code="NEWSHOP", shop_name="New Test Shop", description="A new test shop" ) shop = self.service.create_shop(db, shop_data, test_user) assert shop is not None assert shop.shop_code == "NEWSHOP" assert shop.owner_id == test_user.id assert shop.is_verified is False # Regular user creates unverified shop def test_create_shop_admin_auto_verify(self, db, test_admin, shop_factory): """Test admin creates verified shop automatically""" shop_data = ShopCreate( shop_code="ADMINSHOP", shop_name="Admin Test Shop" ) shop = self.service.create_shop(db, shop_data, test_admin) assert shop.is_verified is True # Admin creates verified shop def test_create_shop_duplicate_code(self, db, test_user, test_shop): """Test shop creation fails with duplicate shop code""" shop_data = ShopCreate( shop_code=test_shop.shop_code, shop_name=test_shop.shop_name ) with pytest.raises(HTTPException) as exc_info: self.service.create_shop(db, shop_data, test_user) assert exc_info.value.status_code == 400 assert "Shop code already exists" in str(exc_info.value.detail) def test_get_shops_regular_user(self, db, test_user, test_shop, inactive_shop): """Test regular user can only see active verified shops and own shops""" shops, total = self.service.get_shops(db, test_user, skip=0, limit=10) shop_codes = [shop.shop_code for shop in shops] assert test_shop.shop_code in shop_codes assert inactive_shop.shop_code not in shop_codes def test_get_shops_admin_user(self, db, test_admin, test_shop, inactive_shop, verified_shop): """Test admin user can see all shops with filters""" shops, total = self.service.get_shops(db, test_admin, active_only=False, verified_only=False) shop_codes = [shop.shop_code for shop in shops] assert test_shop.shop_code in shop_codes assert inactive_shop.shop_code in shop_codes assert verified_shop.shop_code in shop_codes def test_get_shop_by_code_owner_access(self, db, test_user, test_shop): """Test shop owner can access their own shop""" shop = self.service.get_shop_by_code(db, test_shop.shop_code.lower(), test_user) assert shop is not None assert shop.id == test_shop.id def test_get_shop_by_code_admin_access(self, db, test_admin, test_shop): """Test admin can access any shop""" shop = self.service.get_shop_by_code(db, test_shop.shop_code.lower(), test_admin) assert shop is not None assert shop.id == test_shop.id def test_get_shop_by_code_not_found(self, db, test_user): """Test shop not found returns appropriate error""" with pytest.raises(HTTPException) as exc_info: self.service.get_shop_by_code(db, "NONEXISTENT", test_user) assert exc_info.value.status_code == 404 def test_get_shop_by_code_access_denied(self, db, test_user, inactive_shop): """Test regular user cannot access unverified shop they don't own""" with pytest.raises(HTTPException) as exc_info: self.service.get_shop_by_code(db, inactive_shop.shop_code, test_user) assert exc_info.value.status_code == 404 def test_add_product_to_shop_success(self, db, test_shop, unique_product): """Test successfully adding product to shop""" shop_product_data = ShopProductCreate( product_id=unique_product.product_id, price="15.99", is_featured=True, stock_quantity=5 ) shop_product = self.service.add_product_to_shop(db, test_shop, shop_product_data) assert shop_product is not None assert shop_product.shop_id == test_shop.id assert shop_product.product_id == unique_product.id def test_add_product_to_shop_product_not_found(self, db, test_shop): """Test adding non-existent product to shop fails""" shop_product_data = ShopProductCreate( product_id="NONEXISTENT", price="15.99" ) with pytest.raises(HTTPException) as exc_info: self.service.add_product_to_shop(db, test_shop, shop_product_data) assert exc_info.value.status_code == 404 def test_add_product_to_shop_already_exists(self, db, test_shop, shop_product): """Test adding product that's already in shop fails""" shop_product_data = ShopProductCreate( product_id=shop_product.product.product_id, price="15.99" ) with pytest.raises(HTTPException) as exc_info: self.service.add_product_to_shop(db, test_shop, shop_product_data) assert exc_info.value.status_code == 400 def test_get_shop_products_owner_access(self, db, test_user, test_shop, shop_product): """Test shop owner can get shop products""" products, total = self.service.get_shop_products(db, test_shop, test_user) assert total >= 1 assert len(products) >= 1 product_ids = [p.product_id for p in products] assert shop_product.product_id in product_ids def test_get_shop_products_access_denied(self, db, test_user, inactive_shop): """Test non-owner cannot access unverified shop products""" with pytest.raises(HTTPException) as exc_info: self.service.get_shop_products(db, inactive_shop, test_user) assert exc_info.value.status_code == 404 def test_get_shop_by_id(self, db, test_shop): """Test getting shop by ID""" shop = self.service.get_shop_by_id(db, test_shop.id) assert shop is not None assert shop.id == test_shop.id def test_get_shop_by_id_not_found(self, db): """Test getting shop by ID when shop doesn't exist""" shop = self.service.get_shop_by_id(db, 99999) assert shop is None def test_shop_code_exists_true(self, db, test_shop): """Test shop_code_exists returns True when shop code exists""" exists = self.service.shop_code_exists(db, test_shop.shop_code) assert exists is True def test_shop_code_exists_false(self, db): """Test shop_code_exists returns False when shop code doesn't exist""" exists = self.service.shop_code_exists(db, "NONEXISTENT") assert exists is False def test_get_product_by_id(self, db, unique_product): """Test getting product by product_id""" product = self.service.get_product_by_id(db, unique_product.product_id) assert product is not None assert product.id == unique_product.id def test_get_product_by_id_not_found(self, db): """Test getting product by product_id when product doesn't exist""" product = self.service.get_product_by_id(db, "NONEXISTENT") assert product is None def test_product_in_shop_true(self, db, test_shop, shop_product): """Test product_in_shop returns True when product is in shop""" exists = self.service.product_in_shop(db, test_shop.id, shop_product.product_id) assert exists is True def test_product_in_shop_false(self, db, test_shop, unique_product): """Test product_in_shop returns False when product is not in shop""" exists = self.service.product_in_shop(db, test_shop.id, unique_product.id) assert exists is False def test_is_shop_owner_true(self, test_shop, test_user): """Test is_shop_owner returns True for shop owner""" is_owner = self.service.is_shop_owner(test_shop, test_user) assert is_owner is True def test_is_shop_owner_false(self, inactive_shop, test_user): """Test is_shop_owner returns False for non-owner""" is_owner = self.service.is_shop_owner(inactive_shop, test_user) assert is_owner is False def test_can_view_shop_owner(self, test_shop, test_user): """Test can_view_shop returns True for shop owner""" can_view = self.service.can_view_shop(test_shop, test_user) assert can_view is True def test_can_view_shop_admin(self, test_shop, test_admin): """Test can_view_shop returns True for admin""" can_view = self.service.can_view_shop(test_shop, test_admin) assert can_view is True def test_can_view_shop_active_verified(self, test_user, verified_shop): """Test can_view_shop returns True for active verified shop""" can_view = self.service.can_view_shop(verified_shop, test_user) assert can_view is True def test_can_view_shop_inactive_unverified(self, test_user, inactive_shop): """Test can_view_shop returns False for inactive unverified shop""" can_view = self.service.can_view_shop(inactive_shop, test_user) assert can_view is False