tests and actions
This commit is contained in:
parent
c05feb37d3
commit
78f52ea7f4
17 changed files with 4140 additions and 3 deletions
125
hub/services/tests/test_utils.py
Normal file
125
hub/services/tests/test_utils.py
Normal file
|
@ -0,0 +1,125 @@
|
|||
"""
|
||||
Test utilities and fixtures for pricing tests
|
||||
"""
|
||||
|
||||
from decimal import Decimal
|
||||
from django.test import TestCase
|
||||
|
||||
from ..models.base import Currency, Term, Unit
|
||||
from ..models.providers import CloudProvider
|
||||
from ..models.services import Service, Category
|
||||
from ..models.pricing import (
|
||||
ProgressiveDiscountModel,
|
||||
DiscountTier,
|
||||
VSHNAppCatPrice,
|
||||
VSHNAppCatBaseFee,
|
||||
VSHNAppCatUnitRate,
|
||||
)
|
||||
|
||||
|
||||
class PricingTestMixin:
|
||||
"""Mixin providing common setup for pricing tests"""
|
||||
|
||||
def create_test_cloud_provider(self, name="Test Provider"):
|
||||
"""Create a test cloud provider"""
|
||||
return CloudProvider.objects.create(
|
||||
name=name,
|
||||
slug=name.lower().replace(" ", "-"),
|
||||
description=f"{name} description",
|
||||
website=f"https://{name.lower().replace(' ', '')}.com",
|
||||
)
|
||||
|
||||
def create_test_service(self, name="Test Service"):
|
||||
"""Create a test service"""
|
||||
return Service.objects.create(
|
||||
name=name,
|
||||
slug=name.lower().replace(" ", "-"),
|
||||
description=f"{name} description",
|
||||
features=f"{name} features",
|
||||
)
|
||||
|
||||
def create_test_discount_model(self, name="Test Discount", tiers=None):
|
||||
"""Create a test discount model with optional tiers"""
|
||||
discount_model = ProgressiveDiscountModel.objects.create(
|
||||
name=name, description=f"{name} description", active=True
|
||||
)
|
||||
|
||||
if tiers is None:
|
||||
# Default tiers: 0-9 (0%), 10-49 (10%), 50+ (20%)
|
||||
tiers = [
|
||||
(0, 10, Decimal("0.00")),
|
||||
(10, 50, Decimal("10.00")),
|
||||
(50, None, Decimal("20.00")),
|
||||
]
|
||||
|
||||
for min_units, max_units, discount_percent in tiers:
|
||||
DiscountTier.objects.create(
|
||||
discount_model=discount_model,
|
||||
min_units=min_units,
|
||||
max_units=max_units,
|
||||
discount_percent=discount_percent,
|
||||
)
|
||||
|
||||
return discount_model
|
||||
|
||||
def create_test_appcat_price(
|
||||
self,
|
||||
service,
|
||||
discount_model=None,
|
||||
base_fee=Decimal("50.00"),
|
||||
unit_rate=Decimal("5.0000"),
|
||||
):
|
||||
"""Create a test AppCat price configuration"""
|
||||
appcat_price = VSHNAppCatPrice.objects.create(
|
||||
service=service,
|
||||
variable_unit=VSHNAppCatPrice.VariableUnit.RAM,
|
||||
term=Term.MTH,
|
||||
discount_model=discount_model,
|
||||
)
|
||||
|
||||
# Create base fee
|
||||
VSHNAppCatBaseFee.objects.create(
|
||||
vshn_appcat_price_config=appcat_price,
|
||||
currency=Currency.CHF,
|
||||
amount=base_fee,
|
||||
)
|
||||
|
||||
# Create unit rate
|
||||
VSHNAppCatUnitRate.objects.create(
|
||||
vshn_appcat_price_config=appcat_price,
|
||||
currency=Currency.CHF,
|
||||
service_level=VSHNAppCatPrice.ServiceLevel.GUARANTEED,
|
||||
amount=unit_rate,
|
||||
)
|
||||
|
||||
return appcat_price
|
||||
|
||||
|
||||
def calculate_expected_discounted_price(base_rate, units, discount_tiers):
|
||||
"""Helper function to calculate expected discounted price manually"""
|
||||
final_price = Decimal("0")
|
||||
remaining_units = units
|
||||
|
||||
# Sort tiers by min_units
|
||||
sorted_tiers = sorted(discount_tiers, key=lambda x: x[0])
|
||||
|
||||
for min_units, max_units, discount_percent in sorted_tiers:
|
||||
if remaining_units <= 0:
|
||||
break
|
||||
|
||||
# Skip if we haven't reached this tier yet
|
||||
if units < min_units:
|
||||
continue
|
||||
|
||||
# Calculate units in this tier
|
||||
tier_max = max_units if max_units else float("inf")
|
||||
units_start = max(0, units - remaining_units)
|
||||
units_end = min(units, tier_max if max_units else units)
|
||||
tier_units = max(0, units_end - max(units_start, min_units - 1))
|
||||
|
||||
if tier_units > 0:
|
||||
discounted_rate = base_rate * (1 - discount_percent / 100)
|
||||
final_price += discounted_rate * tier_units
|
||||
remaining_units -= tier_units
|
||||
|
||||
return final_price
|
Loading…
Add table
Add a link
Reference in a new issue