244 lines
9.4 KiB
Python
244 lines
9.4 KiB
Python
# tests/test_shop_service.py (simplified with fixtures)
|
|
import pytest
|
|
from fastapi import HTTPException
|
|
|
|
from app.services.shop_service import ShopService
|
|
from models.api.shop import ShopCreate, ShopProductCreate
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.shops
|
|
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
|