Files
gh-greyhaven-ai-claude-code…/skills/testing-strategy/templates/pytest-integration.py
2025-11-29 18:29:30 +08:00

114 lines
3.8 KiB
Python

# tests/integration/test_FEATURE_api.py
import pytest
from httpx import AsyncClient
from uuid import uuid4
@pytest.mark.integration
class TestYourAPI:
"""Integration tests for Your API endpoints."""
async def test_create_endpoint(self, client: AsyncClient, tenant_id):
"""Test POST /api/YOUR_RESOURCE creates resource."""
response = await client.post(
"/api/YOUR_RESOURCE",
json={
"name": "Test Resource",
"description": "Test description",
},
headers={"X-Tenant-ID": str(tenant_id)},
)
assert response.status_code == 201
data = response.json()
assert data["name"] == "Test Resource"
assert data["tenant_id"] == str(tenant_id)
async def test_get_endpoint(self, client: AsyncClient, tenant_id, test_resource):
"""Test GET /api/YOUR_RESOURCE/{id} retrieves resource."""
response = await client.get(
f"/api/YOUR_RESOURCE/{test_resource.id}",
headers={"X-Tenant-ID": str(tenant_id)},
)
assert response.status_code == 200
data = response.json()
assert data["id"] == str(test_resource.id)
assert data["name"] == test_resource.name
async def test_get_enforces_tenant_isolation(
self, client: AsyncClient, tenant_id, test_resource
):
"""Test GET enforces tenant isolation."""
# Should succeed with correct tenant
response = await client.get(
f"/api/YOUR_RESOURCE/{test_resource.id}",
headers={"X-Tenant-ID": str(tenant_id)},
)
assert response.status_code == 200
# Should fail with different tenant
different_tenant = str(uuid4())
response = await client.get(
f"/api/YOUR_RESOURCE/{test_resource.id}",
headers={"X-Tenant-ID": different_tenant},
)
assert response.status_code == 404
async def test_list_endpoint(self, client: AsyncClient, tenant_id):
"""Test GET /api/YOUR_RESOURCE lists resources."""
response = await client.get(
"/api/YOUR_RESOURCE",
headers={"X-Tenant-ID": str(tenant_id)},
)
assert response.status_code == 200
data = response.json()
assert isinstance(data, list)
async def test_update_endpoint(
self, client: AsyncClient, tenant_id, test_resource
):
"""Test PATCH /api/YOUR_RESOURCE/{id} updates resource."""
response = await client.patch(
f"/api/YOUR_RESOURCE/{test_resource.id}",
json={"name": "Updated Name"},
headers={"X-Tenant-ID": str(tenant_id)},
)
assert response.status_code == 200
data = response.json()
assert data["name"] == "Updated Name"
async def test_delete_endpoint(
self, client: AsyncClient, tenant_id, test_resource
):
"""Test DELETE /api/YOUR_RESOURCE/{id} deletes resource."""
response = await client.delete(
f"/api/YOUR_RESOURCE/{test_resource.id}",
headers={"X-Tenant-ID": str(tenant_id)},
)
assert response.status_code == 204
# Verify deletion
response = await client.get(
f"/api/YOUR_RESOURCE/{test_resource.id}",
headers={"X-Tenant-ID": str(tenant_id)},
)
assert response.status_code == 404
async def test_validation_errors(self, client: AsyncClient, tenant_id):
"""Test endpoint validates input correctly."""
response = await client.post(
"/api/YOUR_RESOURCE",
json={
"name": "", # Invalid: empty name
},
headers={"X-Tenant-ID": str(tenant_id)},
)
assert response.status_code == 422
data = response.json()
assert "detail" in data