Files
orion/app/modules/billing/tests/unit/test_billing_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

149 lines
4.4 KiB
Python

# app/modules/billing/tests/unit/test_billing_metrics.py
"""Unit tests for BillingMetricsProvider.get_merchant_metrics."""
import uuid
from datetime import UTC, datetime, timedelta
import pytest
from app.modules.billing.models import (
MerchantSubscription,
SubscriptionStatus,
SubscriptionTier,
)
from app.modules.billing.services.billing_metrics import BillingMetricsProvider
from app.modules.tenancy.models import Merchant, Platform, User
@pytest.fixture
def billing_platform(db):
"""Create a platform for billing metrics tests."""
platform = Platform(
code=f"bm_{uuid.uuid4().hex[:8]}",
name="Billing Metrics Platform",
is_active=True,
)
db.add(platform)
db.commit()
db.refresh(platform)
return platform
@pytest.fixture
def billing_merchant(db):
"""Create a merchant for billing metrics tests."""
from middleware.auth import AuthManager
auth = AuthManager()
user = User(
email=f"billowner_{uuid.uuid4().hex[:8]}@test.com",
username=f"billowner_{uuid.uuid4().hex[:8]}",
hashed_password=auth.hash_password("pass123"),
role="merchant_owner",
is_active=True,
)
db.add(user)
db.flush()
merchant = Merchant(
name="Billing 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 billing_tier(db, billing_platform):
"""Create a subscription tier."""
tier = SubscriptionTier(
code="professional",
name="Professional",
description="Pro tier",
price_monthly_cents=2900,
price_annual_cents=29000,
display_order=1,
is_active=True,
is_public=True,
platform_id=billing_platform.id,
)
db.add(tier)
db.commit()
db.refresh(tier)
return tier
@pytest.fixture
def billing_extra_platforms(db):
"""Create additional platforms for multiple subscriptions (unique constraint: merchant+platform)."""
platforms = []
for i in range(2):
platforms.append(Platform(
code=f"bm_extra_{uuid.uuid4().hex[:8]}",
name=f"Extra Platform {i}",
is_active=True,
))
db.add_all(platforms)
db.commit()
for p in platforms:
db.refresh(p)
return platforms
@pytest.fixture
def billing_subscriptions(db, billing_merchant, billing_platform, billing_tier, billing_extra_platforms):
"""Create subscriptions: 1 active, 1 trial, 1 cancelled (each on a different platform)."""
platforms = [billing_platform, billing_extra_platforms[0], billing_extra_platforms[1]]
subs = []
for status, platform in zip(
[SubscriptionStatus.ACTIVE, SubscriptionStatus.TRIAL, SubscriptionStatus.CANCELLED],
platforms, strict=False,
):
sub = MerchantSubscription(
merchant_id=billing_merchant.id,
platform_id=platform.id,
tier_id=billing_tier.id,
status=status.value,
is_annual=False,
period_start=datetime.now(UTC),
period_end=datetime.now(UTC) + timedelta(days=30),
)
db.add(sub)
subs.append(sub)
db.commit()
for s in subs:
db.refresh(s)
return subs
@pytest.mark.unit
@pytest.mark.billing
class TestBillingMetricsProviderMerchant:
"""Tests for BillingMetricsProvider.get_merchant_metrics."""
def setup_method(self):
self.provider = BillingMetricsProvider()
def test_active_subscriptions_count(self, db, billing_merchant, billing_subscriptions):
"""Counts active + trial subscriptions, excludes cancelled."""
metrics = self.provider.get_merchant_metrics(db, billing_merchant.id)
by_key = {m.key: m.value for m in metrics}
assert by_key["billing.active_subscriptions"] == 2
def test_no_subscriptions(self, db, billing_merchant):
"""Returns zero when merchant has no subscriptions."""
metrics = self.provider.get_merchant_metrics(db, billing_merchant.id)
by_key = {m.key: m.value for m in metrics}
assert by_key["billing.active_subscriptions"] == 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["billing.active_subscriptions"] == 0