refactor: remove backward compatibility code for pre-launch baseline
Clean up accumulated backward-compat shims, deprecated wrappers, unused aliases, and legacy code across the codebase. Since the platform is not live yet, this establishes a clean baseline. Changes: - Delete deprecated middleware/context.py (RequestContext, get_request_context) - Remove unused factory get_store_email_settings_service() - Remove deprecated pagination_full macro, /admin/platform-homepage route - Remove ConversationResponse, InvoiceSettings* unprefixed aliases - Simplify celery_config.py (remove empty LEGACY_TASK_MODULES) - Standardize billing exceptions: *Error aliases → *Exception names - Consolidate duplicate TierNotFoundError/FeatureNotFoundError classes - Remove deprecated is_admin_request() from Store/PlatformContextManager - Remove is_platform_default field, MediaUploadResponse legacy flat fields - Remove MediaItemResponse.url alias, update JS to use file_url - Update all affected tests and documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,24 +19,18 @@ from app.exceptions.base import (
|
||||
__all__ = [
|
||||
# Base billing exception
|
||||
"BillingException",
|
||||
"BillingServiceError", # Alias for backwards compatibility
|
||||
# Subscription exceptions
|
||||
"SubscriptionNotFoundException",
|
||||
"NoActiveSubscriptionException",
|
||||
"NoActiveSubscriptionError", # Alias for backwards compatibility
|
||||
"SubscriptionNotCancelledException",
|
||||
"SubscriptionNotCancelledError", # Alias for backwards compatibility
|
||||
"SubscriptionAlreadyCancelledException",
|
||||
# Tier exceptions
|
||||
"TierNotFoundException",
|
||||
"TierNotFoundError",
|
||||
"TierLimitExceededException",
|
||||
# Payment exceptions
|
||||
"PaymentSystemNotConfiguredException",
|
||||
"PaymentSystemNotConfiguredError", # Alias for backwards compatibility
|
||||
"StripeNotConfiguredException",
|
||||
"StripePriceNotConfiguredException",
|
||||
"StripePriceNotConfiguredError", # Alias for backwards compatibility
|
||||
"PaymentFailedException",
|
||||
# Webhook exceptions
|
||||
"InvalidWebhookSignatureException",
|
||||
@@ -44,7 +38,6 @@ __all__ = [
|
||||
"WebhookVerificationException",
|
||||
# Feature exceptions
|
||||
"FeatureNotFoundException",
|
||||
"FeatureNotFoundError",
|
||||
"FeatureNotAvailableException",
|
||||
"InvalidFeatureCodesError",
|
||||
]
|
||||
@@ -62,10 +55,6 @@ class BillingException(BusinessLogicException):
|
||||
super().__init__(message=message, error_code=error_code, details=details)
|
||||
|
||||
|
||||
# Alias for backwards compatibility with billing_service.py
|
||||
BillingServiceError = BillingException
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Subscription Exceptions
|
||||
# =============================================================================
|
||||
@@ -92,10 +81,6 @@ class NoActiveSubscriptionException(BusinessLogicException):
|
||||
)
|
||||
|
||||
|
||||
# Alias for backwards compatibility with billing_service.py
|
||||
NoActiveSubscriptionError = NoActiveSubscriptionException
|
||||
|
||||
|
||||
class SubscriptionNotCancelledException(BusinessLogicException):
|
||||
"""Raised when trying to reactivate a subscription that is not cancelled."""
|
||||
|
||||
@@ -106,10 +91,6 @@ class SubscriptionNotCancelledException(BusinessLogicException):
|
||||
)
|
||||
|
||||
|
||||
# Alias for backwards compatibility with billing_service.py
|
||||
SubscriptionNotCancelledError = SubscriptionNotCancelledException
|
||||
|
||||
|
||||
class SubscriptionAlreadyCancelledException(BusinessLogicException):
|
||||
"""Raised when trying to cancel an already cancelled subscription."""
|
||||
|
||||
@@ -138,18 +119,6 @@ class TierNotFoundException(ResourceNotFoundException):
|
||||
self.tier_code = tier_code
|
||||
|
||||
|
||||
class TierNotFoundError(ResourceNotFoundException):
|
||||
"""Subscription tier not found (alternate naming)."""
|
||||
|
||||
def __init__(self, tier_code: str):
|
||||
super().__init__(
|
||||
resource_type="SubscriptionTier",
|
||||
identifier=tier_code,
|
||||
message=f"Tier '{tier_code}' not found",
|
||||
)
|
||||
self.tier_code = tier_code
|
||||
|
||||
|
||||
class TierLimitExceededException(BillingException):
|
||||
"""Raised when a tier limit is exceeded."""
|
||||
|
||||
@@ -180,10 +149,6 @@ class PaymentSystemNotConfiguredException(ServiceUnavailableException):
|
||||
super().__init__(message="Payment system not configured")
|
||||
|
||||
|
||||
# Alias for backwards compatibility with billing_service.py
|
||||
PaymentSystemNotConfiguredError = PaymentSystemNotConfiguredException
|
||||
|
||||
|
||||
class StripeNotConfiguredException(BillingException):
|
||||
"""Raised when Stripe is not configured."""
|
||||
|
||||
@@ -206,10 +171,6 @@ class StripePriceNotConfiguredException(BusinessLogicException):
|
||||
self.tier_code = tier_code
|
||||
|
||||
|
||||
# Alias for backwards compatibility with billing_service.py
|
||||
StripePriceNotConfiguredError = StripePriceNotConfiguredException
|
||||
|
||||
|
||||
class PaymentFailedException(BillingException):
|
||||
"""Raised when a payment fails."""
|
||||
|
||||
@@ -277,18 +238,6 @@ class FeatureNotFoundException(ResourceNotFoundException):
|
||||
self.feature_code = feature_code
|
||||
|
||||
|
||||
class FeatureNotFoundError(ResourceNotFoundException):
|
||||
"""Feature not found (alternate naming)."""
|
||||
|
||||
def __init__(self, feature_code: str):
|
||||
super().__init__(
|
||||
resource_type="Feature",
|
||||
identifier=feature_code,
|
||||
message=f"Feature '{feature_code}' not found",
|
||||
)
|
||||
self.feature_code = feature_code
|
||||
|
||||
|
||||
class FeatureNotAvailableException(BillingException):
|
||||
"""Raised when a feature is not available in current tier."""
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.api.deps import get_current_store_api, require_module_access
|
||||
from app.core.database import get_db
|
||||
from app.modules.billing.exceptions import FeatureNotFoundError
|
||||
from app.modules.billing.exceptions import FeatureNotFoundException
|
||||
from app.modules.billing.schemas.billing import (
|
||||
CategoryListResponse,
|
||||
FeatureCodeListResponse,
|
||||
@@ -275,7 +275,7 @@ def get_feature_detail(
|
||||
# Get feature declaration
|
||||
decl = feature_aggregator.get_declaration(feature_code)
|
||||
if not decl:
|
||||
raise FeatureNotFoundError(feature_code)
|
||||
raise FeatureNotFoundException(feature_code)
|
||||
|
||||
# Check availability
|
||||
is_available = feature_service.has_feature(db, merchant_id, platform_id, feature_code)
|
||||
|
||||
@@ -5,14 +5,6 @@ Billing module services.
|
||||
Provides subscription management, Stripe integration, and admin operations.
|
||||
"""
|
||||
|
||||
from app.modules.billing.exceptions import (
|
||||
BillingServiceError,
|
||||
NoActiveSubscriptionError,
|
||||
PaymentSystemNotConfiguredError,
|
||||
StripePriceNotConfiguredError,
|
||||
SubscriptionNotCancelledError,
|
||||
TierNotFoundError,
|
||||
)
|
||||
from app.modules.billing.services.admin_subscription_service import (
|
||||
AdminSubscriptionService,
|
||||
admin_subscription_service,
|
||||
@@ -56,12 +48,6 @@ __all__ = [
|
||||
"admin_subscription_service",
|
||||
"BillingService",
|
||||
"billing_service",
|
||||
"BillingServiceError",
|
||||
"PaymentSystemNotConfiguredError",
|
||||
"TierNotFoundError",
|
||||
"StripePriceNotConfiguredError",
|
||||
"NoActiveSubscriptionError",
|
||||
"SubscriptionNotCancelledError",
|
||||
"FeatureService",
|
||||
"feature_service",
|
||||
"PlatformPricingService",
|
||||
|
||||
@@ -16,12 +16,12 @@ from datetime import datetime
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.modules.billing.exceptions import (
|
||||
BillingServiceError,
|
||||
NoActiveSubscriptionError,
|
||||
PaymentSystemNotConfiguredError,
|
||||
StripePriceNotConfiguredError,
|
||||
SubscriptionNotCancelledError,
|
||||
TierNotFoundError,
|
||||
BillingException,
|
||||
NoActiveSubscriptionException,
|
||||
PaymentSystemNotConfiguredException,
|
||||
StripePriceNotConfiguredException,
|
||||
SubscriptionNotCancelledException,
|
||||
TierNotFoundException,
|
||||
)
|
||||
from app.modules.billing.models import (
|
||||
AddOnProduct,
|
||||
@@ -93,7 +93,7 @@ class BillingService:
|
||||
Get a tier by its code.
|
||||
|
||||
Raises:
|
||||
TierNotFoundError: If tier doesn't exist
|
||||
TierNotFoundException: If tier doesn't exist
|
||||
"""
|
||||
tier = (
|
||||
db.query(SubscriptionTier)
|
||||
@@ -105,7 +105,7 @@ class BillingService:
|
||||
)
|
||||
|
||||
if not tier:
|
||||
raise TierNotFoundError(tier_code)
|
||||
raise TierNotFoundException(tier_code)
|
||||
|
||||
return tier
|
||||
|
||||
@@ -126,12 +126,12 @@ class BillingService:
|
||||
Dict with checkout_url and session_id
|
||||
|
||||
Raises:
|
||||
PaymentSystemNotConfiguredError: If Stripe not configured
|
||||
TierNotFoundError: If tier doesn't exist
|
||||
StripePriceNotConfiguredError: If price not configured
|
||||
PaymentSystemNotConfiguredException: If Stripe not configured
|
||||
TierNotFoundException: If tier doesn't exist
|
||||
StripePriceNotConfiguredException: If price not configured
|
||||
"""
|
||||
if not stripe_service.is_configured:
|
||||
raise PaymentSystemNotConfiguredError()
|
||||
raise PaymentSystemNotConfiguredException()
|
||||
|
||||
tier = self.get_tier_by_code(db, tier_code)
|
||||
|
||||
@@ -142,7 +142,7 @@ class BillingService:
|
||||
)
|
||||
|
||||
if not price_id:
|
||||
raise StripePriceNotConfiguredError(tier_code)
|
||||
raise StripePriceNotConfiguredException(tier_code)
|
||||
|
||||
# Check if this is a new subscription (for trial)
|
||||
existing_sub = subscription_service.get_merchant_subscription(
|
||||
@@ -188,18 +188,18 @@ class BillingService:
|
||||
Dict with portal_url
|
||||
|
||||
Raises:
|
||||
PaymentSystemNotConfiguredError: If Stripe not configured
|
||||
NoActiveSubscriptionError: If no subscription with customer ID
|
||||
PaymentSystemNotConfiguredException: If Stripe not configured
|
||||
NoActiveSubscriptionException: If no subscription with customer ID
|
||||
"""
|
||||
if not stripe_service.is_configured:
|
||||
raise PaymentSystemNotConfiguredError()
|
||||
raise PaymentSystemNotConfiguredException()
|
||||
|
||||
subscription = subscription_service.get_merchant_subscription(
|
||||
db, merchant_id, platform_id
|
||||
)
|
||||
|
||||
if not subscription or not subscription.stripe_customer_id:
|
||||
raise NoActiveSubscriptionError()
|
||||
raise NoActiveSubscriptionException()
|
||||
|
||||
session = stripe_service.create_portal_session(
|
||||
customer_id=subscription.stripe_customer_id,
|
||||
@@ -266,14 +266,14 @@ class BillingService:
|
||||
Dict with message and effective_date
|
||||
|
||||
Raises:
|
||||
NoActiveSubscriptionError: If no subscription to cancel
|
||||
NoActiveSubscriptionException: If no subscription to cancel
|
||||
"""
|
||||
subscription = subscription_service.get_merchant_subscription(
|
||||
db, merchant_id, platform_id
|
||||
)
|
||||
|
||||
if not subscription or not subscription.stripe_subscription_id:
|
||||
raise NoActiveSubscriptionError()
|
||||
raise NoActiveSubscriptionException()
|
||||
|
||||
if stripe_service.is_configured:
|
||||
stripe_service.cancel_subscription(
|
||||
@@ -308,18 +308,18 @@ class BillingService:
|
||||
Dict with success message
|
||||
|
||||
Raises:
|
||||
NoActiveSubscriptionError: If no subscription
|
||||
SubscriptionNotCancelledError: If not cancelled
|
||||
NoActiveSubscriptionException: If no subscription
|
||||
SubscriptionNotCancelledException: If not cancelled
|
||||
"""
|
||||
subscription = subscription_service.get_merchant_subscription(
|
||||
db, merchant_id, platform_id
|
||||
)
|
||||
|
||||
if not subscription or not subscription.stripe_subscription_id:
|
||||
raise NoActiveSubscriptionError()
|
||||
raise NoActiveSubscriptionException()
|
||||
|
||||
if not subscription.cancelled_at:
|
||||
raise SubscriptionNotCancelledError()
|
||||
raise SubscriptionNotCancelledException()
|
||||
|
||||
if stripe_service.is_configured:
|
||||
stripe_service.reactivate_subscription(subscription.stripe_subscription_id)
|
||||
@@ -339,14 +339,14 @@ class BillingService:
|
||||
Dict with amount_due_cents, currency, next_payment_date, line_items
|
||||
|
||||
Raises:
|
||||
NoActiveSubscriptionError: If no subscription with customer ID
|
||||
NoActiveSubscriptionException: If no subscription with customer ID
|
||||
"""
|
||||
subscription = subscription_service.get_merchant_subscription(
|
||||
db, merchant_id, platform_id
|
||||
)
|
||||
|
||||
if not subscription or not subscription.stripe_customer_id:
|
||||
raise NoActiveSubscriptionError()
|
||||
raise NoActiveSubscriptionException()
|
||||
|
||||
if not stripe_service.is_configured:
|
||||
return {
|
||||
@@ -399,16 +399,16 @@ class BillingService:
|
||||
Dict with message, new_tier, effective_immediately
|
||||
|
||||
Raises:
|
||||
TierNotFoundError: If tier doesn't exist
|
||||
NoActiveSubscriptionError: If no subscription
|
||||
StripePriceNotConfiguredError: If price not configured
|
||||
TierNotFoundException: If tier doesn't exist
|
||||
NoActiveSubscriptionException: If no subscription
|
||||
StripePriceNotConfiguredException: If price not configured
|
||||
"""
|
||||
subscription = subscription_service.get_merchant_subscription(
|
||||
db, merchant_id, platform_id
|
||||
)
|
||||
|
||||
if not subscription or not subscription.stripe_subscription_id:
|
||||
raise NoActiveSubscriptionError()
|
||||
raise NoActiveSubscriptionException()
|
||||
|
||||
tier = self.get_tier_by_code(db, new_tier_code)
|
||||
|
||||
@@ -419,7 +419,7 @@ class BillingService:
|
||||
)
|
||||
|
||||
if not price_id:
|
||||
raise StripePriceNotConfiguredError(new_tier_code)
|
||||
raise StripePriceNotConfiguredException(new_tier_code)
|
||||
|
||||
# Update in Stripe
|
||||
if stripe_service.is_configured:
|
||||
@@ -472,11 +472,11 @@ class BillingService:
|
||||
Dict with checkout_url and session_id
|
||||
|
||||
Raises:
|
||||
PaymentSystemNotConfiguredError: If Stripe not configured
|
||||
BillingServiceError: If addon doesn't exist
|
||||
PaymentSystemNotConfiguredException: If Stripe not configured
|
||||
BillingException: If addon doesn't exist
|
||||
"""
|
||||
if not stripe_service.is_configured:
|
||||
raise PaymentSystemNotConfiguredError()
|
||||
raise PaymentSystemNotConfiguredException()
|
||||
|
||||
addon = (
|
||||
db.query(AddOnProduct)
|
||||
@@ -488,10 +488,10 @@ class BillingService:
|
||||
)
|
||||
|
||||
if not addon:
|
||||
raise BillingServiceError(f"Add-on '{addon_code}' not found")
|
||||
raise BillingException(f"Add-on '{addon_code}' not found")
|
||||
|
||||
if not addon.stripe_price_id:
|
||||
raise BillingServiceError(f"Stripe price not configured for add-on '{addon_code}'")
|
||||
raise BillingException(f"Stripe price not configured for add-on '{addon_code}'")
|
||||
|
||||
from app.modules.tenancy.models import Store
|
||||
store = db.query(Store).filter(Store.id == store_id).first()
|
||||
@@ -522,7 +522,7 @@ class BillingService:
|
||||
Dict with message and addon_code
|
||||
|
||||
Raises:
|
||||
BillingServiceError: If addon not found or not owned by store
|
||||
BillingException: If addon not found or not owned by store
|
||||
"""
|
||||
store_addon = (
|
||||
db.query(StoreAddOn)
|
||||
@@ -534,7 +534,7 @@ class BillingService:
|
||||
)
|
||||
|
||||
if not store_addon:
|
||||
raise BillingServiceError("Add-on not found")
|
||||
raise BillingException("Add-on not found")
|
||||
|
||||
addon_code = store_addon.addon_product.code
|
||||
|
||||
|
||||
@@ -6,6 +6,13 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from app.modules.billing.exceptions import (
|
||||
NoActiveSubscriptionException,
|
||||
PaymentSystemNotConfiguredException,
|
||||
StripePriceNotConfiguredException,
|
||||
SubscriptionNotCancelledException,
|
||||
TierNotFoundException,
|
||||
)
|
||||
from app.modules.billing.models import (
|
||||
AddOnProduct,
|
||||
BillingHistory,
|
||||
@@ -13,14 +20,7 @@ from app.modules.billing.models import (
|
||||
SubscriptionStatus,
|
||||
SubscriptionTier,
|
||||
)
|
||||
from app.modules.billing.services.billing_service import (
|
||||
BillingService,
|
||||
NoActiveSubscriptionError,
|
||||
PaymentSystemNotConfiguredError,
|
||||
StripePriceNotConfiguredError,
|
||||
SubscriptionNotCancelledError,
|
||||
TierNotFoundError,
|
||||
)
|
||||
from app.modules.billing.services.billing_service import BillingService
|
||||
|
||||
# ============================================================================
|
||||
# Tier Lookup
|
||||
@@ -41,17 +41,17 @@ class TestBillingServiceTiers:
|
||||
assert tier.code == "essential"
|
||||
|
||||
def test_get_tier_by_code_not_found(self, db):
|
||||
"""Nonexistent tier raises TierNotFoundError."""
|
||||
with pytest.raises(TierNotFoundError) as exc_info:
|
||||
"""Nonexistent tier raises TierNotFoundException."""
|
||||
with pytest.raises(TierNotFoundException) as exc_info:
|
||||
self.service.get_tier_by_code(db, "nonexistent")
|
||||
assert exc_info.value.tier_code == "nonexistent"
|
||||
|
||||
def test_get_tier_by_code_inactive_not_returned(self, db, bs_tier_essential):
|
||||
"""Inactive tier raises TierNotFoundError (only active tiers returned)."""
|
||||
"""Inactive tier raises TierNotFoundException (only active tiers returned)."""
|
||||
bs_tier_essential.is_active = False
|
||||
db.flush()
|
||||
|
||||
with pytest.raises(TierNotFoundError):
|
||||
with pytest.raises(TierNotFoundException):
|
||||
self.service.get_tier_by_code(db, "essential")
|
||||
|
||||
|
||||
@@ -249,8 +249,8 @@ class TestBillingServiceChangeTier:
|
||||
self.service = BillingService()
|
||||
|
||||
def test_change_tier_no_subscription_raises(self, db, bs_tiers):
|
||||
"""Raises NoActiveSubscriptionError when no subscription exists."""
|
||||
with pytest.raises(NoActiveSubscriptionError):
|
||||
"""Raises NoActiveSubscriptionException when no subscription exists."""
|
||||
with pytest.raises(NoActiveSubscriptionException):
|
||||
self.service.change_tier(db, 99999, 99999, "professional", False)
|
||||
|
||||
def test_change_tier_no_stripe_subscription_raises(
|
||||
@@ -258,7 +258,7 @@ class TestBillingServiceChangeTier:
|
||||
):
|
||||
"""Raises when subscription has no stripe_subscription_id."""
|
||||
# bs_subscription has no Stripe IDs
|
||||
with pytest.raises(NoActiveSubscriptionError):
|
||||
with pytest.raises(NoActiveSubscriptionException):
|
||||
self.service.change_tier(
|
||||
db,
|
||||
bs_subscription.merchant_id,
|
||||
@@ -270,8 +270,8 @@ class TestBillingServiceChangeTier:
|
||||
def test_change_tier_nonexistent_tier_raises(
|
||||
self, db, bs_stripe_subscription
|
||||
):
|
||||
"""Raises TierNotFoundError for nonexistent tier."""
|
||||
with pytest.raises(TierNotFoundError):
|
||||
"""Raises TierNotFoundException for nonexistent tier."""
|
||||
with pytest.raises(TierNotFoundException):
|
||||
self.service.change_tier(
|
||||
db,
|
||||
bs_stripe_subscription.merchant_id,
|
||||
@@ -283,9 +283,9 @@ class TestBillingServiceChangeTier:
|
||||
def test_change_tier_no_price_id_raises(
|
||||
self, db, bs_stripe_subscription, bs_tiers
|
||||
):
|
||||
"""Raises StripePriceNotConfiguredError when tier has no Stripe price."""
|
||||
"""Raises StripePriceNotConfiguredException when tier has no Stripe price."""
|
||||
# bs_tiers have no stripe_price_* set
|
||||
with pytest.raises(StripePriceNotConfiguredError):
|
||||
with pytest.raises(StripePriceNotConfiguredException):
|
||||
self.service.change_tier(
|
||||
db,
|
||||
bs_stripe_subscription.merchant_id,
|
||||
@@ -382,12 +382,12 @@ class TestBillingServiceCancel:
|
||||
|
||||
def test_cancel_no_subscription_raises(self, db):
|
||||
"""Raises when no subscription found."""
|
||||
with pytest.raises(NoActiveSubscriptionError):
|
||||
with pytest.raises(NoActiveSubscriptionException):
|
||||
self.service.cancel_subscription(db, 99999, 99999, None, False)
|
||||
|
||||
def test_cancel_no_stripe_id_raises(self, db, bs_subscription):
|
||||
"""Raises when subscription has no stripe_subscription_id."""
|
||||
with pytest.raises(NoActiveSubscriptionError):
|
||||
with pytest.raises(NoActiveSubscriptionException):
|
||||
self.service.cancel_subscription(
|
||||
db,
|
||||
bs_subscription.merchant_id,
|
||||
@@ -431,12 +431,12 @@ class TestBillingServiceReactivate:
|
||||
|
||||
def test_reactivate_no_subscription_raises(self, db):
|
||||
"""Raises when no subscription found."""
|
||||
with pytest.raises(NoActiveSubscriptionError):
|
||||
with pytest.raises(NoActiveSubscriptionException):
|
||||
self.service.reactivate_subscription(db, 99999, 99999)
|
||||
|
||||
def test_reactivate_not_cancelled_raises(self, db, bs_stripe_subscription):
|
||||
"""Raises SubscriptionNotCancelledError when not cancelled."""
|
||||
with pytest.raises(SubscriptionNotCancelledError):
|
||||
"""Raises SubscriptionNotCancelledException when not cancelled."""
|
||||
with pytest.raises(SubscriptionNotCancelledException):
|
||||
self.service.reactivate_subscription(
|
||||
db,
|
||||
bs_stripe_subscription.merchant_id,
|
||||
@@ -480,25 +480,25 @@ class TestBillingServiceCheckout:
|
||||
self.service = BillingService()
|
||||
|
||||
def test_checkout_stripe_not_configured_raises(self, db, bs_tiers_with_stripe):
|
||||
"""Raises PaymentSystemNotConfiguredError when Stripe is off."""
|
||||
"""Raises PaymentSystemNotConfiguredException when Stripe is off."""
|
||||
with patch(
|
||||
"app.modules.billing.services.billing_service.stripe_service"
|
||||
) as mock_stripe:
|
||||
mock_stripe.is_configured = False
|
||||
|
||||
with pytest.raises(PaymentSystemNotConfiguredError):
|
||||
with pytest.raises(PaymentSystemNotConfiguredException):
|
||||
self.service.create_checkout_session(
|
||||
db, 1, 1, "essential", False, "http://ok", "http://cancel"
|
||||
)
|
||||
|
||||
def test_checkout_nonexistent_tier_raises(self, db):
|
||||
"""Raises TierNotFoundError for nonexistent tier."""
|
||||
"""Raises TierNotFoundException for nonexistent tier."""
|
||||
with patch(
|
||||
"app.modules.billing.services.billing_service.stripe_service"
|
||||
) as mock_stripe:
|
||||
mock_stripe.is_configured = True
|
||||
|
||||
with pytest.raises(TierNotFoundError):
|
||||
with pytest.raises(TierNotFoundException):
|
||||
self.service.create_checkout_session(
|
||||
db, 1, 1, "nonexistent", False, "http://ok", "http://cancel"
|
||||
)
|
||||
@@ -518,23 +518,23 @@ class TestBillingServicePortal:
|
||||
self.service = BillingService()
|
||||
|
||||
def test_portal_stripe_not_configured_raises(self, db):
|
||||
"""Raises PaymentSystemNotConfiguredError when Stripe is off."""
|
||||
"""Raises PaymentSystemNotConfiguredException when Stripe is off."""
|
||||
with patch(
|
||||
"app.modules.billing.services.billing_service.stripe_service"
|
||||
) as mock_stripe:
|
||||
mock_stripe.is_configured = False
|
||||
|
||||
with pytest.raises(PaymentSystemNotConfiguredError):
|
||||
with pytest.raises(PaymentSystemNotConfiguredException):
|
||||
self.service.create_portal_session(db, 1, 1, "http://return")
|
||||
|
||||
def test_portal_no_subscription_raises(self, db):
|
||||
"""Raises NoActiveSubscriptionError when no subscription found."""
|
||||
"""Raises NoActiveSubscriptionException when no subscription found."""
|
||||
with patch(
|
||||
"app.modules.billing.services.billing_service.stripe_service"
|
||||
) as mock_stripe:
|
||||
mock_stripe.is_configured = True
|
||||
|
||||
with pytest.raises(NoActiveSubscriptionError):
|
||||
with pytest.raises(NoActiveSubscriptionException):
|
||||
self.service.create_portal_session(db, 99999, 99999, "http://return")
|
||||
|
||||
def test_portal_no_customer_id_raises(self, db, bs_subscription):
|
||||
@@ -544,7 +544,7 @@ class TestBillingServicePortal:
|
||||
) as mock_stripe:
|
||||
mock_stripe.is_configured = True
|
||||
|
||||
with pytest.raises(NoActiveSubscriptionError):
|
||||
with pytest.raises(NoActiveSubscriptionException):
|
||||
self.service.create_portal_session(
|
||||
db,
|
||||
bs_subscription.merchant_id,
|
||||
@@ -568,12 +568,12 @@ class TestBillingServiceUpcomingInvoice:
|
||||
|
||||
def test_upcoming_invoice_no_subscription_raises(self, db):
|
||||
"""Raises when no subscription exists."""
|
||||
with pytest.raises(NoActiveSubscriptionError):
|
||||
with pytest.raises(NoActiveSubscriptionException):
|
||||
self.service.get_upcoming_invoice(db, 99999, 99999)
|
||||
|
||||
def test_upcoming_invoice_no_customer_id_raises(self, db, bs_subscription):
|
||||
"""Raises when subscription has no stripe_customer_id."""
|
||||
with pytest.raises(NoActiveSubscriptionError):
|
||||
with pytest.raises(NoActiveSubscriptionException):
|
||||
self.service.get_upcoming_invoice(
|
||||
db, bs_subscription.merchant_id, bs_subscription.platform_id
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user