Files
orion/app/modules/customers/tests/unit/test_customer_metrics.py
Samir Boulahtit 540205402f
Some checks failed
CI / pytest (push) Waiting to run
CI / ruff (push) Successful in 12s
CI / validate (push) Successful in 26s
CI / dependency-scanning (push) Successful in 31s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
feat(middleware): harden routing with fail-closed policy, custom subdomain management, and perf fixes
- Fix IPv6 host parsing with _strip_port() utility
- Remove dangerous StorePlatform→Store.subdomain silent fallback
- Close storefront gate bypass when frontend_type is None
- Add custom subdomain management UI and API for stores
- Add domain health diagnostic tool
- Convert db.add() in loops to db.add_all() (24 PERF-006 fixes)
- Add tests for all new functionality (18 subdomain service tests)
- Add .github templates for validator compliance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 18:13:01 +01:00

127 lines
3.9 KiB
Python

# app/modules/customers/tests/unit/test_customer_metrics.py
"""Unit tests for CustomerMetricsProvider.get_merchant_metrics."""
import uuid
import pytest
from app.modules.customers.models.customer import Customer
from app.modules.customers.services.customer_metrics import CustomerMetricsProvider
from app.modules.tenancy.models import Merchant, Store, User
@pytest.fixture
def cust_merchant(db):
"""Create a merchant for customer metrics tests."""
from middleware.auth import AuthManager
auth = AuthManager()
user = User(
email=f"custowner_{uuid.uuid4().hex[:8]}@test.com",
username=f"custowner_{uuid.uuid4().hex[:8]}",
hashed_password=auth.hash_password("pass123"),
role="merchant_owner",
is_active=True,
)
db.add(user)
db.flush()
merchant = Merchant(
name="Customer Metrics Merchant",
owner_user_id=user.id,
contact_email=user.email,
is_active=True,
is_verified=True,
)
db.add(merchant)
db.commit()
db.refresh(merchant)
return merchant
@pytest.fixture
def cust_stores(db, cust_merchant):
"""Create 2 stores for the merchant."""
stores = []
for i in range(2):
uid = uuid.uuid4().hex[:8].upper()
stores.append(Store(
merchant_id=cust_merchant.id,
store_code=f"CSTORE_{uid}",
subdomain=f"cstore{uid.lower()}",
name=f"Cust Store {i}",
is_active=True,
is_verified=True,
))
db.add_all(stores)
db.commit()
for s in stores:
db.refresh(s)
return stores
@pytest.fixture
def cust_customers(db, cust_stores):
"""Create customers across the merchant's stores."""
customers = []
# 3 customers in store 0
for i in range(3):
uid = uuid.uuid4().hex[:8]
customers.append(Customer(
store_id=cust_stores[0].id,
email=f"cust_{uid}@test.com",
hashed_password="hashed", # noqa: SEC001
first_name=f"First{i}",
last_name=f"Last{i}",
customer_number=f"C{uid}",
is_active=True,
))
# 2 customers in store 1
for i in range(2):
uid = uuid.uuid4().hex[:8]
customers.append(Customer(
store_id=cust_stores[1].id,
email=f"cust_{uid}@test.com",
hashed_password="hashed", # noqa: SEC001
first_name=f"First{i}",
last_name=f"Last{i}",
customer_number=f"C{uid}",
is_active=True,
))
db.add_all(customers)
db.commit()
return customers
@pytest.mark.unit
@pytest.mark.customers
class TestCustomerMetricsProviderMerchant:
"""Tests for CustomerMetricsProvider.get_merchant_metrics."""
def setup_method(self):
self.provider = CustomerMetricsProvider()
def test_total_customers_across_stores(self, db, cust_merchant, cust_stores, cust_customers):
"""Aggregates customers across all merchant stores."""
metrics = self.provider.get_merchant_metrics(db, cust_merchant.id)
by_key = {m.key: m.value for m in metrics}
assert by_key["customers.total"] == 5
def test_no_customers(self, db, cust_merchant, cust_stores):
"""Returns zero when stores have no customers."""
metrics = self.provider.get_merchant_metrics(db, cust_merchant.id)
by_key = {m.key: m.value for m in metrics}
assert by_key["customers.total"] == 0
def test_no_stores(self, db, cust_merchant):
"""Returns zero when merchant has no stores."""
metrics = self.provider.get_merchant_metrics(db, cust_merchant.id)
by_key = {m.key: m.value for m in metrics}
assert by_key["customers.total"] == 0
def test_nonexistent_merchant(self, db):
"""Returns zero for a non-existent merchant ID."""
metrics = self.provider.get_merchant_metrics(db, 999999)
by_key = {m.key: m.value for m in metrics}
assert by_key["customers.total"] == 0