234 lines
6.6 KiB
Python
234 lines
6.6 KiB
Python
"""Tests for admin endpoints."""
|
|
|
|
import pytest
|
|
from httpx import AsyncClient
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_client(client: AsyncClient, admin_headers: dict):
|
|
"""Test creating a new client."""
|
|
response = await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={
|
|
"name": "Acme Corp",
|
|
"contact_email": "admin@acme.com",
|
|
"billing_plan": "pro",
|
|
},
|
|
headers=admin_headers,
|
|
)
|
|
|
|
assert response.status_code == 201
|
|
data = response.json()
|
|
assert data["name"] == "Acme Corp"
|
|
assert data["contact_email"] == "admin@acme.com"
|
|
assert data["billing_plan"] == "pro"
|
|
assert data["status"] == "active"
|
|
assert "id" in data
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_client_unauthorized(client: AsyncClient):
|
|
"""Test creating client without auth fails."""
|
|
response = await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={"name": "Test Corp"},
|
|
)
|
|
|
|
assert response.status_code == 422 # Missing header
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_client_invalid_key(client: AsyncClient):
|
|
"""Test creating client with invalid key fails."""
|
|
response = await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={"name": "Test Corp"},
|
|
headers={"X-Admin-Api-Key": "invalid-key"},
|
|
)
|
|
|
|
assert response.status_code == 401
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_list_clients(client: AsyncClient, admin_headers: dict):
|
|
"""Test listing clients."""
|
|
# Create a client first
|
|
await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={"name": "Test Corp 1"},
|
|
headers=admin_headers,
|
|
)
|
|
await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={"name": "Test Corp 2"},
|
|
headers=admin_headers,
|
|
)
|
|
|
|
response = await client.get(
|
|
"/api/v1/admin/clients",
|
|
headers=admin_headers,
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert len(data) >= 2
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_instance(client: AsyncClient, admin_headers: dict):
|
|
"""Test creating an instance for a client."""
|
|
# Create client first
|
|
client_response = await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={"name": "Instance Test Corp"},
|
|
headers=admin_headers,
|
|
)
|
|
client_id = client_response.json()["id"]
|
|
|
|
# Create instance
|
|
response = await client.post(
|
|
f"/api/v1/admin/clients/{client_id}/instances",
|
|
json={
|
|
"instance_id": "test-orchestrator",
|
|
"region": "eu-west-1",
|
|
},
|
|
headers=admin_headers,
|
|
)
|
|
|
|
assert response.status_code == 201
|
|
data = response.json()
|
|
assert data["instance_id"] == "test-orchestrator"
|
|
assert data["region"] == "eu-west-1"
|
|
assert data["license_status"] == "active"
|
|
assert data["status"] == "pending"
|
|
# Keys should be returned on creation
|
|
assert "license_key" in data
|
|
assert data["license_key"].startswith("lb_inst_")
|
|
assert "hub_api_key" in data
|
|
assert data["hub_api_key"].startswith("hk_")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_duplicate_instance(client: AsyncClient, admin_headers: dict):
|
|
"""Test that duplicate instance_id fails."""
|
|
# Create client
|
|
client_response = await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={"name": "Duplicate Test Corp"},
|
|
headers=admin_headers,
|
|
)
|
|
client_id = client_response.json()["id"]
|
|
|
|
# Create first instance
|
|
await client.post(
|
|
f"/api/v1/admin/clients/{client_id}/instances",
|
|
json={"instance_id": "duplicate-test"},
|
|
headers=admin_headers,
|
|
)
|
|
|
|
# Try to create duplicate
|
|
response = await client.post(
|
|
f"/api/v1/admin/clients/{client_id}/instances",
|
|
json={"instance_id": "duplicate-test"},
|
|
headers=admin_headers,
|
|
)
|
|
|
|
assert response.status_code == 409
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_rotate_license_key(client: AsyncClient, admin_headers: dict):
|
|
"""Test rotating a license key."""
|
|
# Create client and instance
|
|
client_response = await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={"name": "Rotate Test Corp"},
|
|
headers=admin_headers,
|
|
)
|
|
client_id = client_response.json()["id"]
|
|
|
|
instance_response = await client.post(
|
|
f"/api/v1/admin/clients/{client_id}/instances",
|
|
json={"instance_id": "rotate-test"},
|
|
headers=admin_headers,
|
|
)
|
|
original_key = instance_response.json()["license_key"]
|
|
|
|
# Rotate license
|
|
response = await client.post(
|
|
"/api/v1/admin/instances/rotate-test/rotate-license",
|
|
headers=admin_headers,
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["license_key"].startswith("lb_inst_")
|
|
assert data["license_key"] != original_key
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_suspend_instance(client: AsyncClient, admin_headers: dict):
|
|
"""Test suspending an instance."""
|
|
# Create client and instance
|
|
client_response = await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={"name": "Suspend Test Corp"},
|
|
headers=admin_headers,
|
|
)
|
|
client_id = client_response.json()["id"]
|
|
|
|
await client.post(
|
|
f"/api/v1/admin/clients/{client_id}/instances",
|
|
json={"instance_id": "suspend-test"},
|
|
headers=admin_headers,
|
|
)
|
|
|
|
# Suspend
|
|
response = await client.post(
|
|
"/api/v1/admin/instances/suspend-test/suspend",
|
|
headers=admin_headers,
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
assert response.json()["status"] == "suspended"
|
|
|
|
# Verify status
|
|
get_response = await client.get(
|
|
"/api/v1/admin/instances/suspend-test",
|
|
headers=admin_headers,
|
|
)
|
|
assert get_response.json()["license_status"] == "suspended"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_reactivate_instance(client: AsyncClient, admin_headers: dict):
|
|
"""Test reactivating a suspended instance."""
|
|
# Create client and instance
|
|
client_response = await client.post(
|
|
"/api/v1/admin/clients",
|
|
json={"name": "Reactivate Test Corp"},
|
|
headers=admin_headers,
|
|
)
|
|
client_id = client_response.json()["id"]
|
|
|
|
await client.post(
|
|
f"/api/v1/admin/clients/{client_id}/instances",
|
|
json={"instance_id": "reactivate-test"},
|
|
headers=admin_headers,
|
|
)
|
|
|
|
# Suspend
|
|
await client.post(
|
|
"/api/v1/admin/instances/reactivate-test/suspend",
|
|
headers=admin_headers,
|
|
)
|
|
|
|
# Reactivate
|
|
response = await client.post(
|
|
"/api/v1/admin/instances/reactivate-test/reactivate",
|
|
headers=admin_headers,
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
assert response.json()["status"] == "pending" # Not activated yet
|