import pytest import asyncio from playwright.async_api import expect, Page @pytest.mark.asyncio class TestBillingAPIFlow: async def test_01_api_get_current_usage(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'testuser', 'testpassword123') response = await page.request.get( f"{base_url}/api/billing/usage/current", headers={"Authorization": f"Bearer {token}"} ) assert response.ok data = await response.json() assert 'storage_gb' in data assert 'bandwidth_down_gb_today' in data assert 'as_of' in data async def test_02_api_get_monthly_usage(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'testuser', 'testpassword123') response = await page.request.get( f"{base_url}/api/billing/usage/monthly", headers={"Authorization": f"Bearer {token}"} ) assert response.ok data = await response.json() assert 'storage_gb_avg' in data assert 'bandwidth_down_gb' in data assert 'period' in data async def test_03_api_get_subscription(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'testuser', 'testpassword123') response = await page.request.get( f"{base_url}/api/billing/subscription", headers={"Authorization": f"Bearer {token}"} ) assert response.ok data = await response.json() assert 'billing_type' in data assert 'status' in data assert data['billing_type'] == 'pay_as_you_go' async def test_04_api_list_invoices(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'testuser', 'testpassword123') response = await page.request.get( f"{base_url}/api/billing/invoices", headers={"Authorization": f"Bearer {token}"} ) assert response.ok data = await response.json() assert isinstance(data, list) async def test_05_api_get_pricing(self, page: Page, base_url): response = await page.request.get(f"{base_url}/api/billing/pricing") assert response.ok data = await response.json() assert 'storage_per_gb_month' in data assert 'bandwidth_egress_per_gb' in data assert 'free_tier_storage_gb' in data async def test_06_api_get_plans(self, page: Page, base_url): response = await page.request.get(f"{base_url}/api/billing/plans") assert response.ok data = await response.json() assert isinstance(data, list) async def test_07_api_admin_get_pricing_config(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'adminuser', 'adminpassword123') response = await page.request.get( f"{base_url}/api/admin/billing/pricing", headers={"Authorization": f"Bearer {token}"} ) assert response.ok data = await response.json() assert isinstance(data, list) assert len(data) >= 6 async def test_08_api_admin_get_stats(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'adminuser', 'adminpassword123') response = await page.request.get( f"{base_url}/api/admin/billing/stats", headers={"Authorization": f"Bearer {token}"} ) assert response.ok data = await response.json() assert 'total_revenue' in data assert 'total_invoices' in data assert 'pending_invoices' in data async def test_09_api_user_cannot_access_admin_endpoints(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'testuser', 'testpassword123') response = await page.request.get( f"{base_url}/api/admin/billing/pricing", headers={"Authorization": f"Bearer {token}"} ) assert response.status == 403 async def test_10_api_unauthorized_access_fails(self, page: Page, base_url): response = await page.request.get(f"{base_url}/api/billing/usage/current") assert response.status == 401 async def test_11_api_create_payment_setup_intent(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'testuser', 'testpassword123') response = await page.request.post( f"{base_url}/api/billing/payment-methods/setup-intent", headers={"Authorization": f"Bearer {token}"} ) assert response.ok or response.status == 500 async def test_12_api_get_payment_methods(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'testuser', 'testpassword123') response = await page.request.get( f"{base_url}/api/billing/payment-methods", headers={"Authorization": f"Bearer {token}"} ) assert response.ok data = await response.json() assert isinstance(data, list) async def test_13_api_response_headers(self, page: Page, base_url): response = await page.request.get(f"{base_url}/api/billing/pricing") assert response.ok headers = response.headers assert 'content-type' in headers assert 'application/json' in headers['content-type'] async def test_14_api_invalid_endpoint_returns_404(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'testuser', 'testpassword123') response = await page.request.get( f"{base_url}/api/billing/nonexistent", headers={"Authorization": f"Bearer {token}"} ) assert response.status == 404 async def test_15_api_request_with_params(self, page: Page, base_url): token = await self._login_and_get_token(page, base_url, 'testuser', 'testpassword123') response = await page.request.get( f"{base_url}/api/billing/usage/monthly?year=2024&month=11", headers={"Authorization": f"Bearer {token}"} ) assert response.ok data = await response.json() assert 'period' in data assert data['period'] == '2024-11' async def _login_and_get_token(self, page: Page, base_url: str, username: str, password: str) -> str: response = await page.request.post( f"{base_url}/api/auth/login", data={"username": username, "password": password} ) if response.ok: data = await response.json() return data.get('access_token', '') return ''