270 lines
9.2 KiB
Python
270 lines
9.2 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import replace
|
|
from decimal import Decimal
|
|
from pathlib import Path
|
|
|
|
from adaptive_pricing_core.boundary_engine import (
|
|
BoundaryPolicy,
|
|
CommitmentTerms,
|
|
PricingConfiguration,
|
|
validate_pricing_configuration,
|
|
)
|
|
from adaptive_pricing_core.pricing_models import AssuranceClaim
|
|
from observatory.load import load_pricing_models
|
|
|
|
DATA_DIR = Path(__file__).resolve().parent.parent / "data"
|
|
|
|
|
|
def _model(model_id: str):
|
|
return next(item for item in load_pricing_models(DATA_DIR) if item.id == model_id)
|
|
|
|
|
|
def _configuration_with_claim(claim: AssuranceClaim) -> PricingConfiguration:
|
|
return PricingConfiguration(
|
|
model=replace(_model("flat-899-eur-monthly"), assurance_claims=(claim,)),
|
|
segment="coulomb-social-members",
|
|
allocated_fixed_cost=Decimal("1.00"),
|
|
payment_fee_rate_pct=Decimal("5"),
|
|
)
|
|
|
|
|
|
def _claim(**changes) -> AssuranceClaim:
|
|
defaults = {
|
|
"id": "isolation-tier",
|
|
"kind": "isolation",
|
|
"customer_wording": "Other tenants cannot reach your data.",
|
|
"minimum_levels": {"E": 4, "P": 3},
|
|
"delivering_service": "tenant-engine",
|
|
"evidence_ref": "evidence/isolation-review.json",
|
|
}
|
|
defaults.update(changes)
|
|
return AssuranceClaim(**defaults)
|
|
|
|
|
|
def test_valid_assurance_claim_passes_with_explainable_result() -> None:
|
|
result = validate_pricing_configuration(
|
|
_configuration_with_claim(_claim()),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assurance = next(item for item in result.constraints if item.id == "assurance-claims")
|
|
assert assurance.status == "pass"
|
|
assert assurance.details["claim_ids"] == ["isolation-tier"]
|
|
|
|
|
|
def test_isolation_wording_requires_e4_and_coupled_p3() -> None:
|
|
result = validate_pricing_configuration(
|
|
_configuration_with_claim(_claim(minimum_levels={"E": 3, "P": 2})),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assurance = next(item for item in result.constraints if item.id == "assurance-claims")
|
|
assert assurance.status == "fail"
|
|
assert "E §11.4" in assurance.reason
|
|
|
|
|
|
def test_retention_claim_requires_bounded_shared_horizon() -> None:
|
|
result = validate_pricing_configuration(
|
|
_configuration_with_claim(
|
|
_claim(
|
|
id="retention-tier",
|
|
kind="retention",
|
|
customer_wording="Deleted data is gone.",
|
|
minimum_levels={"R": 3, "P": 1},
|
|
)
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assurance = next(item for item in result.constraints if item.id == "assurance-claims")
|
|
assert assurance.status == "fail"
|
|
assert "R §4.5.4/§11.1" in assurance.reason
|
|
assert "P §4.5.4" in assurance.reason
|
|
assert "R §11.4" in assurance.reason
|
|
|
|
|
|
def test_performance_claim_requires_p2_or_resource_governor() -> None:
|
|
result = validate_pricing_configuration(
|
|
_configuration_with_claim(
|
|
_claim(
|
|
id="performance-tier",
|
|
kind="performance",
|
|
customer_wording="Predictable performance under neighbour load.",
|
|
minimum_levels={"P": 1},
|
|
)
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assurance = next(item for item in result.constraints if item.id == "assurance-claims")
|
|
assert assurance.status == "fail"
|
|
assert "P §8.3.1/§11.6" in assurance.reason
|
|
|
|
|
|
def test_availability_wording_requires_matching_failure_scope() -> None:
|
|
result = validate_pricing_configuration(
|
|
_configuration_with_claim(
|
|
_claim(
|
|
id="availability-tier",
|
|
kind="availability",
|
|
customer_wording="High availability survives regional loss.",
|
|
minimum_levels={"V": 3},
|
|
)
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assurance = next(item for item in result.constraints if item.id == "assurance-claims")
|
|
assert assurance.status == "fail"
|
|
assert "V §11.4" in assurance.reason
|
|
|
|
|
|
def test_commitment_backed_discount_is_accepted_when_economics_stay_strong() -> None:
|
|
result = validate_pricing_configuration(
|
|
PricingConfiguration(
|
|
model=_model("membership-plus-overage"),
|
|
segment="coulomb-social-members",
|
|
expected_usage_units=Decimal("100200"),
|
|
expected_usage_variance_pct=Decimal("25"),
|
|
allocated_fixed_cost=Decimal("2.00"),
|
|
unit_cost=Decimal("0.00000125"),
|
|
payment_fee_rate_pct=Decimal("5"),
|
|
usage_unit_price=Decimal("0.0015"),
|
|
commitment_terms=CommitmentTerms(
|
|
contract_duration_months=6,
|
|
minimum_monthly_turnover=Decimal("9.30"),
|
|
),
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assert result.decision == "accepted"
|
|
assert result.valid is True
|
|
assert result.requires_approval is False
|
|
commitment_result = next(
|
|
item for item in result.constraints if item.id == "commitment-backed-concession"
|
|
)
|
|
assert commitment_result.status == "pass"
|
|
assert "minimum_monthly_turnover" in commitment_result.details["signals"]
|
|
|
|
|
|
def test_discount_without_commitment_is_rejected() -> None:
|
|
result = validate_pricing_configuration(
|
|
PricingConfiguration(
|
|
model=_model("membership-plus-overage"),
|
|
segment="coulomb-social-members",
|
|
expected_usage_units=Decimal("100200"),
|
|
expected_usage_variance_pct=Decimal("25"),
|
|
allocated_fixed_cost=Decimal("2.00"),
|
|
unit_cost=Decimal("0.00000125"),
|
|
payment_fee_rate_pct=Decimal("5"),
|
|
usage_unit_price=Decimal("0.0015"),
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assert result.decision == "rejected"
|
|
assert result.valid is False
|
|
failing_ids = {
|
|
item.id for item in result.constraints if item.status == "fail" and item.severity == "hard"
|
|
}
|
|
assert "commitment-backed-concession" in failing_ids
|
|
|
|
|
|
def test_weak_commitment_trade_is_rejected() -> None:
|
|
result = validate_pricing_configuration(
|
|
PricingConfiguration(
|
|
model=_model("membership-plus-overage"),
|
|
segment="coulomb-social-members",
|
|
expected_usage_units=Decimal("100200"),
|
|
expected_usage_variance_pct=Decimal("25"),
|
|
allocated_fixed_cost=Decimal("2.00"),
|
|
unit_cost=Decimal("0.00000125"),
|
|
payment_fee_rate_pct=Decimal("5"),
|
|
usage_unit_price=Decimal("0.0015"),
|
|
commitment_terms=CommitmentTerms(
|
|
contract_duration_months=2,
|
|
minimum_monthly_turnover=Decimal("9.00"),
|
|
),
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assert result.decision == "rejected"
|
|
commitment_result = next(
|
|
item for item in result.constraints if item.id == "commitment-backed-concession"
|
|
)
|
|
assert commitment_result.status == "fail"
|
|
|
|
|
|
def test_large_but_supported_concession_requires_approval() -> None:
|
|
result = validate_pricing_configuration(
|
|
PricingConfiguration(
|
|
model=_model("flat-899-eur-monthly"),
|
|
segment="coulomb-social-members",
|
|
allocated_fixed_cost=Decimal("1.00"),
|
|
payment_fee_rate_pct=Decimal("5"),
|
|
access_fee_amount=Decimal("7.50"),
|
|
commitment_terms=CommitmentTerms(
|
|
contract_duration_months=6,
|
|
minimum_monthly_turnover=Decimal("8.00"),
|
|
),
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assert result.decision == "requires_approval"
|
|
assert result.valid is True
|
|
assert result.requires_approval is True
|
|
review_ids = {item.id for item in result.constraints if item.status == "review"}
|
|
assert "discount-approval-threshold" in review_ids
|
|
|
|
|
|
def test_zero_usage_flat_configuration_can_pass() -> None:
|
|
result = validate_pricing_configuration(
|
|
PricingConfiguration(
|
|
model=_model("flat-899-eur-monthly"),
|
|
segment="coulomb-social-members",
|
|
expected_usage_units=Decimal("0"),
|
|
expected_usage_variance_pct=Decimal("0"),
|
|
allocated_fixed_cost=Decimal("3.00"),
|
|
payment_fee_rate_pct=Decimal("5"),
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assert result.decision == "accepted"
|
|
assert result.metrics.billable_usage_units == Decimal("0")
|
|
|
|
|
|
def test_high_fee_configuration_is_rejected() -> None:
|
|
result = validate_pricing_configuration(
|
|
PricingConfiguration(
|
|
model=_model("flat-899-eur-monthly"),
|
|
segment="coulomb-social-members",
|
|
allocated_fixed_cost=Decimal("1.00"),
|
|
payment_fee_rate_pct=Decimal("30"),
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assert result.decision == "rejected"
|
|
payment_fee_result = next(item for item in result.constraints if item.id == "payment-fee-limit")
|
|
assert payment_fee_result.status == "fail"
|
|
|
|
|
|
def test_unprofitable_configuration_is_rejected() -> None:
|
|
result = validate_pricing_configuration(
|
|
PricingConfiguration(
|
|
model=_model("flat-899-eur-monthly"),
|
|
segment="coulomb-social-members",
|
|
allocated_fixed_cost=Decimal("10.00"),
|
|
payment_fee_rate_pct=Decimal("5"),
|
|
),
|
|
BoundaryPolicy(),
|
|
)
|
|
|
|
assert result.decision == "rejected"
|
|
assert result.metrics.monthly_margin < Decimal("0")
|
|
assert any(item.id == "cost-floor-coverage" and item.status == "fail" for item in result.constraints)
|