Files
adaptive-pricing/projects/coulomb-pricing/tests/test_mvp_sprints.py
tegwick 0a38def5a5 Complete Economic Observatory MVP (ADAPTIVE-WP-0002)
Add file-based Bubble, Stripe, and OpenRouter importers; usage attribution,
cost allocation, pricing simulator, credit wallets, and recommendations in the
dashboard API. Document whynot-design UI workflow and archive the finished
workplan with all ten tasks marked done.
2026-06-22 23:23:31 +02:00

96 lines
3.3 KiB
Python

from __future__ import annotations
from decimal import Decimal
from pathlib import Path
from observatory.allocation import build_cost_allocation
from observatory.api import build_dashboard_payload
from observatory.credits import build_credit_summary, load_credit_wallets
from observatory.economics import build_snapshot
from observatory.load import (
load_membership,
load_monthly_ledger,
load_payment_records,
load_pricing_models,
load_product,
)
from observatory.membership_analytics import build_membership_analytics
from observatory.recommendations import build_pricing_recommendations
from observatory.simulator import build_pricing_simulations
from observatory.usage import build_usage_summary, load_usage_records
DATA_DIR = Path(__file__).resolve().parent.parent / "data"
def _snapshot(period: str = "2026-06"):
product = load_product(DATA_DIR)
models = load_pricing_models(DATA_DIR)
members = load_membership(DATA_DIR)
payments = load_payment_records(DATA_DIR)
ledger = load_monthly_ledger(DATA_DIR)
return build_snapshot(period, product, models, members, payments, ledger)
def test_membership_analytics_counts_active_member() -> None:
members = load_membership(DATA_DIR)
analytics = build_membership_analytics(members, "2026-06", ["2026-05", "2026-06"])
assert analytics["active_members"] == 1
assert analytics["total_members"] == 1
def test_usage_summary_attributes_member_cost() -> None:
records = load_usage_records(DATA_DIR)
summary = build_usage_summary(records, "2026-06")
assert summary["record_count"] == 1
assert summary["by_member"]["member-tegwick"] == Decimal("0.06")
def test_cost_allocation_includes_ai_variable_cost() -> None:
snapshot = _snapshot()
allocation = build_cost_allocation(snapshot, load_usage_records(DATA_DIR))
assert allocation["variable_ai_eur"] == Decimal("0.06")
assert allocation["cost_floor_eur"] == snapshot.cost_per_member
def test_pricing_simulator_compares_candidate_models() -> None:
snapshot = _snapshot()
models = load_pricing_models(DATA_DIR)
simulations = build_pricing_simulations(snapshot, models, Decimal("0.06"))
assert len(simulations["scenarios"]) == 3
assert simulations["active_scenario_id"] == "flat-899-eur-monthly"
def test_credit_summary_tracks_remaining_allowance() -> None:
wallets = load_credit_wallets(DATA_DIR)
summary = build_credit_summary(wallets, {"member-tegwick": Decimal("0.06")}, "2026-06")
assert summary["wallets"][0]["remaining_eur"] == Decimal("1.94")
def test_recommendations_include_hold_or_action() -> None:
payload = build_dashboard_payload(DATA_DIR, "2026-06")
recs = build_pricing_recommendations(
payload["cost_floor"],
payload["value_range"],
payload["market_price"],
payload["pricing_simulations"],
payload["usage"],
)
assert recs
assert recs[0]["id"] in {"margin-pressure", "usage-pricing-signal", "value-headroom", "hold-course"}
def test_dashboard_payload_includes_mvp_sections() -> None:
payload = build_dashboard_payload(DATA_DIR, "2026-06")
assert "membership_analytics" in payload
assert "usage" in payload
assert "cost_allocation" in payload
assert "pricing_simulations" in payload
assert "credit_wallets" in payload
assert "recommendations" in payload