184 lines
6.6 KiB
Python
184 lines
6.6 KiB
Python
|
|
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 ''
|