import pytest from infrasynth.billing.models import ( BillingPlan, Invoice, PaymentGateway, Subscription, ) from infrasynth.shared.enums import BillingInterval, InvoiceStatus, SubscriptionStatus pytestmark = pytest.mark.django_db @pytest.fixture def gateway(): return PaymentGateway.objects.create( slug="stripe", display_name="Stripe", gateway_class="infrasynth.billing.gateways.stripe.StripeGateway", supported_currencies=["USD"], ) class TestPaymentGateway: def test_create(self): gateway = PaymentGateway.objects.create( slug="fake", display_name="Fake", gateway_class="tests.helpers.FakeGateway", ) assert gateway.is_active is True assert str(gateway) == "Fake" assert gateway.supported_currencies == [] assert gateway.config == {} def test_pk_is_slug(self, gateway): assert gateway.pk == "stripe" class TestBillingPlan: def test_create(self, gateway): plan = BillingPlan.objects.create( slug="pro", name="Pro", price_amount="49.00", price_currency="USD", interval=BillingInterval.MONTHLY, gateway=gateway, ) assert plan.is_active is True assert plan.trial_days == 0 assert plan.features == [] assert str(plan) == "Pro" def test_unique_slug(self, gateway): BillingPlan.objects.create(slug="pro", name="A", price_amount=1, price_currency="USD", interval="monthly") with pytest.raises(Exception): BillingPlan.objects.create(slug="pro", name="B", price_amount=1, price_currency="USD", interval="monthly") class TestSubscription: def test_create(self, user, gateway): subscription = Subscription.objects.create( user=user, gateway=gateway, status=SubscriptionStatus.ACTIVE, ) assert subscription.cancel_at_period_end is False assert subscription.metadata == {} def test_status_choices(self, user, gateway): subscription = Subscription.objects.create( user=user, gateway=gateway, status=SubscriptionStatus.TRIALING, ) assert subscription.status == "trialing" class TestInvoice: def test_create(self, user, gateway): invoice = Invoice.objects.create( user=user, gateway=gateway, invoice_number="INV-2026-000001", amount="49.00", currency="USD", status=InvoiceStatus.DRAFT, ) assert invoice.tax_amount == 0 assert invoice.tax_name == "" assert invoice.line_items == [] assert invoice.metadata == {} assert invoice.pdf_file_id is None assert str(invoice) == "INV-2026-000001" def test_no_default_status(self, user, gateway): invoice = Invoice.objects.create( user=user, invoice_number="INV-2", amount=10, currency="USD", ) assert invoice.status == "" def test_unique_invoice_number(self, user, gateway): Invoice.objects.create(user=user, invoice_number="INV-1", amount=1, currency="USD", status="open") with pytest.raises(Exception): Invoice.objects.create(user=user, invoice_number="INV-1", amount=1, currency="USD", status="open")