test: add admin customer service tests and update conftest
- Add unit tests for admin customer service - Update test configuration in conftest.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -128,5 +128,6 @@ pytest_plugins = [
|
||||
"tests.fixtures.vendor_fixtures",
|
||||
"tests.fixtures.customer_fixtures",
|
||||
"tests.fixtures.marketplace_import_job_fixtures",
|
||||
"tests.fixtures.message_fixtures",
|
||||
"tests.fixtures.testing_fixtures",
|
||||
]
|
||||
|
||||
280
tests/unit/services/test_admin_customer_service.py
Normal file
280
tests/unit/services/test_admin_customer_service.py
Normal file
@@ -0,0 +1,280 @@
|
||||
# tests/unit/services/test_admin_customer_service.py
|
||||
"""
|
||||
Unit tests for AdminCustomerService.
|
||||
"""
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
import pytest
|
||||
|
||||
from app.exceptions.customer import CustomerNotFoundException
|
||||
from app.services.admin_customer_service import AdminCustomerService
|
||||
from models.database.customer import Customer
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def admin_customer_service():
|
||||
"""Create AdminCustomerService instance."""
|
||||
return AdminCustomerService()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def customer_with_orders(db, test_vendor, test_customer):
|
||||
"""Create a customer with order data."""
|
||||
test_customer.total_orders = 5
|
||||
test_customer.total_spent = Decimal("250.00")
|
||||
db.commit()
|
||||
db.refresh(test_customer)
|
||||
return test_customer
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def multiple_customers(db, test_vendor):
|
||||
"""Create multiple customers for testing."""
|
||||
customers = []
|
||||
for i in range(5):
|
||||
customer = Customer(
|
||||
vendor_id=test_vendor.id,
|
||||
email=f"customer{i}@example.com",
|
||||
hashed_password="hashed_password_placeholder",
|
||||
first_name=f"First{i}",
|
||||
last_name=f"Last{i}",
|
||||
customer_number=f"CUST-00{i}",
|
||||
is_active=(i % 2 == 0), # Alternate active/inactive
|
||||
total_orders=i,
|
||||
total_spent=Decimal(str(i * 100)),
|
||||
)
|
||||
db.add(customer)
|
||||
customers.append(customer)
|
||||
|
||||
db.commit()
|
||||
for c in customers:
|
||||
db.refresh(c)
|
||||
|
||||
return customers
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestAdminCustomerServiceList:
|
||||
"""Tests for list_customers method."""
|
||||
|
||||
def test_list_customers_empty(self, db, admin_customer_service, test_vendor):
|
||||
"""Test listing customers when none exist."""
|
||||
customers, total = admin_customer_service.list_customers(db)
|
||||
|
||||
assert customers == []
|
||||
assert total == 0
|
||||
|
||||
def test_list_customers_basic(self, db, admin_customer_service, test_customer):
|
||||
"""Test basic customer listing."""
|
||||
customers, total = admin_customer_service.list_customers(db)
|
||||
|
||||
assert total == 1
|
||||
assert len(customers) == 1
|
||||
assert customers[0]["id"] == test_customer.id
|
||||
assert customers[0]["email"] == test_customer.email
|
||||
|
||||
def test_list_customers_with_vendor_info(
|
||||
self, db, admin_customer_service, test_customer, test_vendor
|
||||
):
|
||||
"""Test that vendor info is included."""
|
||||
customers, total = admin_customer_service.list_customers(db)
|
||||
|
||||
assert customers[0]["vendor_name"] == test_vendor.name
|
||||
assert customers[0]["vendor_code"] == test_vendor.vendor_code
|
||||
|
||||
def test_list_customers_filter_by_vendor(
|
||||
self, db, admin_customer_service, multiple_customers, test_vendor
|
||||
):
|
||||
"""Test filtering by vendor ID."""
|
||||
customers, total = admin_customer_service.list_customers(
|
||||
db, vendor_id=test_vendor.id
|
||||
)
|
||||
|
||||
assert total == 5
|
||||
for customer in customers:
|
||||
assert customer["vendor_id"] == test_vendor.id
|
||||
|
||||
def test_list_customers_filter_by_active_status(
|
||||
self, db, admin_customer_service, multiple_customers
|
||||
):
|
||||
"""Test filtering by active status."""
|
||||
# Get active customers (0, 2, 4 = 3 customers)
|
||||
customers, total = admin_customer_service.list_customers(db, is_active=True)
|
||||
assert total == 3
|
||||
|
||||
# Get inactive customers (1, 3 = 2 customers)
|
||||
customers, total = admin_customer_service.list_customers(db, is_active=False)
|
||||
assert total == 2
|
||||
|
||||
def test_list_customers_search_by_email(
|
||||
self, db, admin_customer_service, multiple_customers
|
||||
):
|
||||
"""Test searching by email."""
|
||||
customers, total = admin_customer_service.list_customers(
|
||||
db, search="customer2@"
|
||||
)
|
||||
|
||||
assert total == 1
|
||||
assert customers[0]["email"] == "customer2@example.com"
|
||||
|
||||
def test_list_customers_search_by_name(
|
||||
self, db, admin_customer_service, multiple_customers
|
||||
):
|
||||
"""Test searching by name."""
|
||||
customers, total = admin_customer_service.list_customers(db, search="First3")
|
||||
|
||||
assert total == 1
|
||||
assert customers[0]["first_name"] == "First3"
|
||||
|
||||
def test_list_customers_search_by_customer_number(
|
||||
self, db, admin_customer_service, multiple_customers
|
||||
):
|
||||
"""Test searching by customer number."""
|
||||
customers, total = admin_customer_service.list_customers(db, search="CUST-001")
|
||||
|
||||
assert total == 1
|
||||
assert customers[0]["customer_number"] == "CUST-001"
|
||||
|
||||
def test_list_customers_pagination(
|
||||
self, db, admin_customer_service, multiple_customers
|
||||
):
|
||||
"""Test pagination."""
|
||||
# Get first page
|
||||
customers, total = admin_customer_service.list_customers(db, skip=0, limit=2)
|
||||
assert len(customers) == 2
|
||||
assert total == 5
|
||||
|
||||
# Get second page
|
||||
customers, total = admin_customer_service.list_customers(db, skip=2, limit=2)
|
||||
assert len(customers) == 2
|
||||
|
||||
# Get last page
|
||||
customers, total = admin_customer_service.list_customers(db, skip=4, limit=2)
|
||||
assert len(customers) == 1
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestAdminCustomerServiceStats:
|
||||
"""Tests for get_customer_stats method."""
|
||||
|
||||
def test_get_customer_stats_empty(self, db, admin_customer_service, test_vendor):
|
||||
"""Test stats when no customers exist."""
|
||||
stats = admin_customer_service.get_customer_stats(db)
|
||||
|
||||
assert stats["total"] == 0
|
||||
assert stats["active"] == 0
|
||||
assert stats["inactive"] == 0
|
||||
assert stats["with_orders"] == 0
|
||||
assert stats["total_spent"] == 0
|
||||
assert stats["total_orders"] == 0
|
||||
assert stats["avg_order_value"] == 0
|
||||
|
||||
def test_get_customer_stats_with_data(
|
||||
self, db, admin_customer_service, multiple_customers
|
||||
):
|
||||
"""Test stats with customer data."""
|
||||
stats = admin_customer_service.get_customer_stats(db)
|
||||
|
||||
assert stats["total"] == 5
|
||||
assert stats["active"] == 3 # 0, 2, 4
|
||||
assert stats["inactive"] == 2 # 1, 3
|
||||
# with_orders = customers with total_orders > 0 (1, 2, 3, 4 = 4 customers)
|
||||
assert stats["with_orders"] == 4
|
||||
# total_spent = 0 + 100 + 200 + 300 + 400 = 1000
|
||||
assert stats["total_spent"] == 1000.0
|
||||
# total_orders = 0 + 1 + 2 + 3 + 4 = 10
|
||||
assert stats["total_orders"] == 10
|
||||
|
||||
def test_get_customer_stats_by_vendor(
|
||||
self, db, admin_customer_service, test_customer, test_vendor
|
||||
):
|
||||
"""Test stats filtered by vendor."""
|
||||
stats = admin_customer_service.get_customer_stats(db, vendor_id=test_vendor.id)
|
||||
|
||||
assert stats["total"] == 1
|
||||
|
||||
def test_get_customer_stats_avg_order_value(
|
||||
self, db, admin_customer_service, customer_with_orders
|
||||
):
|
||||
"""Test average order value calculation."""
|
||||
stats = admin_customer_service.get_customer_stats(db)
|
||||
|
||||
# total_spent = 250, total_orders = 5
|
||||
# avg = 250 / 5 = 50
|
||||
assert stats["avg_order_value"] == 50.0
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestAdminCustomerServiceGetCustomer:
|
||||
"""Tests for get_customer method."""
|
||||
|
||||
def test_get_customer_success(self, db, admin_customer_service, test_customer):
|
||||
"""Test getting customer by ID."""
|
||||
customer = admin_customer_service.get_customer(db, test_customer.id)
|
||||
|
||||
assert customer["id"] == test_customer.id
|
||||
assert customer["email"] == test_customer.email
|
||||
assert customer["first_name"] == test_customer.first_name
|
||||
assert customer["last_name"] == test_customer.last_name
|
||||
|
||||
def test_get_customer_with_vendor_info(
|
||||
self, db, admin_customer_service, test_customer, test_vendor
|
||||
):
|
||||
"""Test vendor info in customer detail."""
|
||||
customer = admin_customer_service.get_customer(db, test_customer.id)
|
||||
|
||||
assert customer["vendor_name"] == test_vendor.name
|
||||
assert customer["vendor_code"] == test_vendor.vendor_code
|
||||
|
||||
def test_get_customer_not_found(self, db, admin_customer_service):
|
||||
"""Test error when customer not found."""
|
||||
with pytest.raises(CustomerNotFoundException):
|
||||
admin_customer_service.get_customer(db, 99999)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestAdminCustomerServiceToggleStatus:
|
||||
"""Tests for toggle_customer_status method."""
|
||||
|
||||
def test_toggle_status_activate(
|
||||
self, db, admin_customer_service, test_customer, test_admin
|
||||
):
|
||||
"""Test activating an inactive customer."""
|
||||
# Make customer inactive first
|
||||
test_customer.is_active = False
|
||||
db.commit()
|
||||
|
||||
result = admin_customer_service.toggle_customer_status(
|
||||
db, test_customer.id, test_admin.email
|
||||
)
|
||||
db.commit()
|
||||
|
||||
assert result["id"] == test_customer.id
|
||||
assert result["is_active"] is True
|
||||
assert "activated" in result["message"]
|
||||
|
||||
def test_toggle_status_deactivate(
|
||||
self, db, admin_customer_service, test_customer, test_admin
|
||||
):
|
||||
"""Test deactivating an active customer."""
|
||||
test_customer.is_active = True
|
||||
db.commit()
|
||||
|
||||
result = admin_customer_service.toggle_customer_status(
|
||||
db, test_customer.id, test_admin.email
|
||||
)
|
||||
db.commit()
|
||||
|
||||
assert result["id"] == test_customer.id
|
||||
assert result["is_active"] is False
|
||||
assert "deactivated" in result["message"]
|
||||
|
||||
def test_toggle_status_not_found(
|
||||
self, db, admin_customer_service, test_admin
|
||||
):
|
||||
"""Test error when customer not found."""
|
||||
with pytest.raises(CustomerNotFoundException):
|
||||
admin_customer_service.toggle_customer_status(
|
||||
db, 99999, test_admin.email
|
||||
)
|
||||
Reference in New Issue
Block a user