"""Tests for plan and subscription Pydantic schemas."""
from datetime import datetime, date
from uuid import uuid4
import pytest
from pydantic import ValidationError
from preloop.models.schemas.plan import (
MonthlyUsage,
MonthlyUsageBase,
MonthlyUsageCreate,
Plan,
PlanBase,
PlanCreate,
PlanFeatures,
Subscription,
SubscriptionBase,
SubscriptionCreate,
)
class TestPlanFeatures:
"""Test PlanFeatures schema."""
def test_create_with_all_fields(self):
"""Test creating PlanFeatures with all fields."""
features = PlanFeatures(
api_calls_monthly=10000,
ai_calls_monthly=1000,
issues_ingested_monthly=5000,
custom_ai_models_enabled=True,
custom_compliance_metrics_enabled=True,
)
assert features.api_calls_monthly == 10000
assert features.ai_calls_monthly == 1000
assert features.issues_ingested_monthly == 5000
assert features.custom_ai_models_enabled is True
assert features.custom_compliance_metrics_enabled is True
def test_required_fields(self):
"""Test that all fields are required."""
with pytest.raises(ValidationError):
PlanFeatures()
with pytest.raises(ValidationError):
PlanFeatures(api_calls_monthly=1000)
class TestPlanBase:
"""Test PlanBase schema."""
def test_create_with_required_fields(self):
"""Test creating PlanBase with required fields."""
features = PlanFeatures(
api_calls_monthly=10000,
ai_calls_monthly=1000,
issues_ingested_monthly=5000,
custom_ai_models_enabled=True,
custom_compliance_metrics_enabled=False,
)
plan = PlanBase(name="Free Plan", features=features)
assert plan.name == "Free Plan"
assert plan.price_monthly is None
assert plan.price_annually is None
assert plan.is_active is True
assert plan.features == features
def test_create_with_all_fields(self):
"""Test creating PlanBase with all fields."""
features = PlanFeatures(
api_calls_monthly=50000,
ai_calls_monthly=5000,
issues_ingested_monthly=20000,
custom_ai_models_enabled=True,
custom_compliance_metrics_enabled=True,
)
plan = PlanBase(
name="Pro Plan",
price_monthly=99.99,
price_annually=999.00,
is_active=True,
features=features,
)
assert plan.name == "Pro Plan"
assert plan.price_monthly == 99.99
assert plan.price_annually == 999.00
assert plan.is_active is True
class TestPlanCreate:
"""Test PlanCreate schema."""
def test_inherits_from_base(self):
"""Test that PlanCreate inherits from PlanBase."""
features = PlanFeatures(
api_calls_monthly=10000,
ai_calls_monthly=1000,
issues_ingested_monthly=5000,
custom_ai_models_enabled=False,
custom_compliance_metrics_enabled=False,
)
plan = PlanCreate(name="Starter Plan", features=features)
assert isinstance(plan, PlanBase)
assert plan.name == "Starter Plan"
class TestPlan:
"""Test Plan schema."""
def test_create_complete_plan(self):
"""Test creating complete Plan with all fields."""
features = PlanFeatures(
api_calls_monthly=10000,
ai_calls_monthly=1000,
issues_ingested_monthly=5000,
custom_ai_models_enabled=True,
custom_compliance_metrics_enabled=False,
)
plan_id = "plan_" + str(uuid4())[:8]
created_at = datetime.now()
updated_at = datetime.now()
plan = Plan(
id=plan_id,
name="Enterprise Plan",
price_monthly=299.99,
price_annually=2999.00,
is_active=True,
features=features,
created_at=created_at,
updated_at=updated_at,
)
assert plan.id == plan_id
assert plan.name == "Enterprise Plan"
assert plan.price_monthly == 299.99
assert plan.created_at == created_at
assert plan.updated_at == updated_at
def test_from_attributes_config(self):
"""Test that from_attributes is enabled in Config."""
assert Plan.model_config.get("from_attributes") is True
class TestSubscriptionBase:
"""Test SubscriptionBase schema."""
def test_create_with_required_fields(self):
"""Test creating SubscriptionBase with required fields."""
account_id = uuid4()
plan_id = "plan_free"
start = datetime.now()
end = datetime(2025, 12, 31, 23, 59, 59)
sub = SubscriptionBase(
account_id=account_id,
plan_id=plan_id,
current_period_start=start,
current_period_end=end,
)
assert sub.account_id == account_id
assert sub.plan_id == plan_id
assert sub.status == "active" # default value
assert sub.current_period_start == start
assert sub.current_period_end == end
assert sub.stripe_subscription_id is None
def test_create_with_all_fields(self):
"""Test creating SubscriptionBase with all fields."""
account_id = uuid4()
plan_id = "plan_pro"
start = datetime.now()
end = datetime(2025, 12, 31, 23, 59, 59)
sub = SubscriptionBase(
account_id=account_id,
plan_id=plan_id,
status="trialing",
current_period_start=start,
current_period_end=end,
stripe_subscription_id="sub_1234567890",
)
assert sub.status == "trialing"
assert sub.stripe_subscription_id == "sub_1234567890"
class TestSubscriptionCreate:
"""Test SubscriptionCreate schema."""
def test_inherits_from_base(self):
"""Test that SubscriptionCreate inherits from SubscriptionBase."""
account_id = uuid4()
plan_id = "plan_starter"
start = datetime.now()
end = datetime(2025, 12, 31, 23, 59, 59)
sub = SubscriptionCreate(
account_id=account_id,
plan_id=plan_id,
current_period_start=start,
current_period_end=end,
)
assert isinstance(sub, SubscriptionBase)
assert sub.account_id == account_id
class TestSubscription:
"""Test Subscription schema."""
def test_create_complete_subscription(self):
"""Test creating complete Subscription with all fields."""
sub_id = uuid4()
account_id = uuid4()
plan_id = "plan_enterprise"
start = datetime.now()
end = datetime(2025, 12, 31, 23, 59, 59)
created_at = datetime.now()
updated_at = datetime.now()
sub = Subscription(
id=sub_id,
account_id=account_id,
plan_id=plan_id,
status="active",
current_period_start=start,
current_period_end=end,
stripe_subscription_id="sub_9876543210",
created_at=created_at,
updated_at=updated_at,
)
assert sub.id == sub_id
assert sub.account_id == account_id
assert sub.plan_id == plan_id
assert sub.status == "active"
assert sub.stripe_subscription_id == "sub_9876543210"
assert sub.created_at == created_at
assert sub.updated_at == updated_at
def test_from_attributes_config(self):
"""Test that from_attributes is enabled in Config."""
assert Subscription.model_config.get("from_attributes") is True
class TestMonthlyUsageBase:
"""Test MonthlyUsageBase schema."""
def test_create_with_required_fields(self):
"""Test creating MonthlyUsageBase with required fields."""
subscription_id = uuid4()
start_date = date(2025, 1, 1)
end_date = date(2025, 1, 31)
usage = MonthlyUsageBase(
subscription_id=subscription_id,
billing_cycle_start=start_date,
billing_cycle_end=end_date,
)
assert usage.subscription_id == subscription_id
assert usage.billing_cycle_start == start_date
assert usage.billing_cycle_end == end_date
assert usage.usage_counts == {} # default value
def test_create_with_usage_counts(self):
"""Test creating MonthlyUsageBase with usage counts."""
subscription_id = uuid4()
start_date = date(2025, 1, 1)
end_date = date(2025, 1, 31)
usage = MonthlyUsageBase(
subscription_id=subscription_id,
billing_cycle_start=start_date,
billing_cycle_end=end_date,
usage_counts={
"api_calls": 8500,
"ai_calls": 750,
"issues_ingested": 4200,
},
)
assert usage.usage_counts["api_calls"] == 8500
assert usage.usage_counts["ai_calls"] == 750
assert usage.usage_counts["issues_ingested"] == 4200
class TestMonthlyUsageCreate:
"""Test MonthlyUsageCreate schema."""
def test_inherits_from_base(self):
"""Test that MonthlyUsageCreate inherits from MonthlyUsageBase."""
subscription_id = uuid4()
start_date = date(2025, 1, 1)
end_date = date(2025, 1, 31)
usage = MonthlyUsageCreate(
subscription_id=subscription_id,
billing_cycle_start=start_date,
billing_cycle_end=end_date,
)
assert isinstance(usage, MonthlyUsageBase)
assert usage.subscription_id == subscription_id
class TestMonthlyUsage:
"""Test MonthlyUsage schema."""
def test_create_complete_monthly_usage(self):
"""Test creating complete MonthlyUsage with all fields."""
usage_id = uuid4()
subscription_id = uuid4()
start_date = date(2025, 1, 1)
end_date = date(2025, 1, 31)
created_at = datetime.now()
updated_at = datetime.now()
usage = MonthlyUsage(
id=usage_id,
subscription_id=subscription_id,
billing_cycle_start=start_date,
billing_cycle_end=end_date,
usage_counts={
"api_calls": 9500,
"ai_calls": 950,
"issues_ingested": 4800,
},
created_at=created_at,
updated_at=updated_at,
)
assert usage.id == usage_id
assert usage.subscription_id == subscription_id
assert usage.billing_cycle_start == start_date
assert usage.billing_cycle_end == end_date
assert usage.usage_counts["api_calls"] == 9500
assert usage.created_at == created_at
assert usage.updated_at == updated_at
def test_from_attributes_config(self):
"""Test that from_attributes is enabled in Config."""
assert MonthlyUsage.model_config.get("from_attributes") is True