115 lines
3.7 KiB
Python
115 lines
3.7 KiB
Python
"""
|
|
Tests for API endpoints
|
|
|
|
Tests FastAPI application endpoints including health checks and future endpoints
|
|
"""
|
|
|
|
import pytest
|
|
from httpx import AsyncClient
|
|
from fastapi import status
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_health_endpoint(client: AsyncClient):
|
|
"""Test health check endpoint"""
|
|
response = await client.get("/health")
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
|
|
data = response.json()
|
|
assert data["status"] == "healthy"
|
|
assert data["app"] == "The APAC OpsBot"
|
|
assert "environment" in data
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_root_endpoint_redirect(client: AsyncClient):
|
|
"""Test root endpoint redirects to docs"""
|
|
response = await client.get("/", follow_redirects=False)
|
|
|
|
# Should redirect to /docs or return some response
|
|
assert response.status_code in [
|
|
status.HTTP_200_OK,
|
|
status.HTTP_307_TEMPORARY_REDIRECT,
|
|
status.HTTP_308_PERMANENT_REDIRECT
|
|
]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_docs_endpoint_accessible(client: AsyncClient):
|
|
"""Test OpenAPI docs are accessible"""
|
|
response = await client.get("/docs")
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
assert "text/html" in response.headers["content-type"]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_openapi_json_accessible(client: AsyncClient):
|
|
"""Test OpenAPI JSON schema is accessible"""
|
|
response = await client.get("/openapi.json")
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
assert response.headers["content-type"] == "application/json"
|
|
|
|
schema = response.json()
|
|
assert "openapi" in schema
|
|
assert "info" in schema
|
|
assert schema["info"]["title"] == "The APAC OpsBot"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_nonexistent_endpoint_returns_404(client: AsyncClient):
|
|
"""Test that non-existent endpoints return 404"""
|
|
response = await client.get("/this-does-not-exist")
|
|
|
|
assert response.status_code == status.HTTP_404_NOT_FOUND
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_health_endpoint_includes_timestamp(client: AsyncClient):
|
|
"""Test health endpoint includes timestamp"""
|
|
response = await client.get("/health")
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
|
|
# Health endpoint should include timestamp or similar metadata
|
|
assert "status" in data
|
|
|
|
|
|
# Future API endpoint tests (to be implemented in Phase 2)
|
|
|
|
@pytest.mark.skip(reason="Auth endpoints not yet implemented")
|
|
@pytest.mark.asyncio
|
|
async def test_auth_me_requires_authentication(client: AsyncClient):
|
|
"""Test /api/v1/auth/me requires authentication"""
|
|
response = await client.get("/api/v1/auth/me")
|
|
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|
|
|
|
|
|
@pytest.mark.skip(reason="Conversation endpoints not yet implemented")
|
|
@pytest.mark.asyncio
|
|
async def test_list_conversations_requires_auth(client: AsyncClient):
|
|
"""Test /api/v1/conversations requires authentication"""
|
|
response = await client.get("/api/v1/conversations")
|
|
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|
|
|
|
|
|
@pytest.mark.skip(reason="Message endpoints not yet implemented")
|
|
@pytest.mark.asyncio
|
|
async def test_send_message_requires_auth(client: AsyncClient):
|
|
"""Test sending messages requires authentication"""
|
|
response = await client.post(
|
|
"/api/v1/conversations/test-id/messages",
|
|
json={"content": "Test message"}
|
|
)
|
|
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|
|
|
|
|
|
@pytest.mark.skip(reason="Token endpoints not yet implemented")
|
|
@pytest.mark.asyncio
|
|
async def test_token_usage_requires_auth(client: AsyncClient):
|
|
"""Test /api/v1/tokens/usage requires authentication"""
|
|
response = await client.get("/api/v1/tokens/usage")
|
|
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|