import pytest from unittest.mock import patch, MagicMock from app.models.plan_billing import PlanBilling @pytest.mark.asyncio async def test_checkout_session_creates_stripe_session( client, test_db, test_user, auth_headers, monkeypatch ): """End-to-end: post body → Stripe SDK called → URL returned. Stripe SDK mocked; Customer + Session calls patched.""" from app.core.config import settings monkeypatch.setattr(settings, "STRIPE_SECRET_KEY", "sk_test_dummy") test_db.add(PlanBilling( plan="pro", display_name="Pro", stripe_product_id="prod_test", stripe_monthly_price_id="price_test_monthly", )) await test_db.commit() fake_customer = MagicMock() fake_customer.id = "cus_test_123" fake_session = MagicMock() fake_session.url = "https://checkout.stripe.com/test" with patch("stripe.Customer.create", return_value=fake_customer) as cust_mock, \ patch("stripe.checkout.Session.create", return_value=fake_session) as sess_mock: response = await client.post( "/api/v1/billing/checkout-session", json={"plan": "pro", "seats": 3, "billing_interval": "monthly"}, headers=auth_headers, ) assert response.status_code == 200, response.json() assert response.json()["url"] == "https://checkout.stripe.com/test" cust_mock.assert_called_once() sess_mock.assert_called_once() @pytest.mark.asyncio async def test_checkout_session_unknown_plan_returns_500( client, test_db, test_user, auth_headers, monkeypatch ): """No PlanBilling row → ValueError surfaces as 500 (the endpoint doesn't catch business errors).""" from app.core.config import settings monkeypatch.setattr(settings, "STRIPE_SECRET_KEY", "sk_test_dummy") response = await client.post( "/api/v1/billing/checkout-session", json={"plan": "pro", "seats": 1, "billing_interval": "monthly"}, headers=auth_headers, ) assert response.status_code == 500