Skip to content

Commit d71ba33

Browse files
Integrate prompts and actions into unit tests (#69)
1 parent efa5f82 commit d71ba33

7 files changed

Lines changed: 1065 additions & 1 deletion

File tree

tests/unit/api/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Unit tests for API endpoints."""

tests/unit/api/test_main.py

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
"""
2+
Tests for api/main.py FastAPI endpoints.
3+
4+
Tests the main API endpoints:
5+
- Root endpoint (/)
6+
- Health check (/health)
7+
- Hello endpoint (/hello/{name})
8+
"""
9+
10+
import pytest
11+
from fastapi.testclient import TestClient
12+
13+
from api.main import app
14+
15+
16+
@pytest.fixture
17+
def client() -> TestClient:
18+
"""Create a test client for the FastAPI app."""
19+
return TestClient(app)
20+
21+
22+
class TestRootEndpoint:
23+
"""Tests for the root endpoint (/)."""
24+
25+
def test_returns_welcome_message(self, client: TestClient) -> None:
26+
"""Root endpoint should return welcome message."""
27+
response = client.get("/")
28+
29+
assert response.status_code == 200
30+
data = response.json()
31+
assert data["message"] == "Welcome to pyplots API"
32+
33+
def test_returns_version(self, client: TestClient) -> None:
34+
"""Root endpoint should return version."""
35+
response = client.get("/")
36+
37+
data = response.json()
38+
assert "version" in data
39+
assert data["version"] == "0.1.0"
40+
41+
def test_returns_docs_url(self, client: TestClient) -> None:
42+
"""Root endpoint should return docs URL."""
43+
response = client.get("/")
44+
45+
data = response.json()
46+
assert data["docs"] == "/docs"
47+
48+
def test_returns_health_url(self, client: TestClient) -> None:
49+
"""Root endpoint should return health URL."""
50+
response = client.get("/")
51+
52+
data = response.json()
53+
assert data["health"] == "/health"
54+
55+
56+
class TestHealthEndpoint:
57+
"""Tests for the health check endpoint (/health)."""
58+
59+
def test_returns_200_status(self, client: TestClient) -> None:
60+
"""Health endpoint should return 200 OK."""
61+
response = client.get("/health")
62+
63+
assert response.status_code == 200
64+
65+
def test_returns_healthy_status(self, client: TestClient) -> None:
66+
"""Health endpoint should report healthy status."""
67+
response = client.get("/health")
68+
69+
data = response.json()
70+
assert data["status"] == "healthy"
71+
72+
def test_returns_service_name(self, client: TestClient) -> None:
73+
"""Health endpoint should return service name."""
74+
response = client.get("/health")
75+
76+
data = response.json()
77+
assert data["service"] == "pyplots-api"
78+
79+
def test_returns_version(self, client: TestClient) -> None:
80+
"""Health endpoint should return version."""
81+
response = client.get("/health")
82+
83+
data = response.json()
84+
assert data["version"] == "0.1.0"
85+
86+
87+
class TestHelloEndpoint:
88+
"""Tests for the hello endpoint (/hello/{name})."""
89+
90+
def test_greets_by_name(self, client: TestClient) -> None:
91+
"""Hello endpoint should greet by name."""
92+
response = client.get("/hello/World")
93+
94+
assert response.status_code == 200
95+
data = response.json()
96+
assert data["message"] == "Hello, World!"
97+
98+
def test_greets_different_names(self, client: TestClient) -> None:
99+
"""Hello endpoint should work with different names."""
100+
for name in ["Alice", "Bob", "Claude"]:
101+
response = client.get(f"/hello/{name}")
102+
103+
assert response.status_code == 200
104+
data = response.json()
105+
assert data["message"] == f"Hello, {name}!"
106+
107+
def test_returns_service_name(self, client: TestClient) -> None:
108+
"""Hello endpoint should return service name."""
109+
response = client.get("/hello/Test")
110+
111+
data = response.json()
112+
assert data["service"] == "pyplots"
113+
114+
def test_handles_special_characters(self, client: TestClient) -> None:
115+
"""Hello endpoint should handle URL-encoded names."""
116+
response = client.get("/hello/John%20Doe")
117+
118+
assert response.status_code == 200
119+
data = response.json()
120+
assert "John Doe" in data["message"]
121+
122+
def test_handles_unicode_names(self, client: TestClient) -> None:
123+
"""Hello endpoint should handle unicode names."""
124+
response = client.get("/hello/日本語")
125+
126+
assert response.status_code == 200
127+
data = response.json()
128+
assert "日本語" in data["message"]
129+
130+
131+
class TestOpenAPIDocumentation:
132+
"""Tests for OpenAPI documentation endpoints."""
133+
134+
def test_docs_endpoint_exists(self, client: TestClient) -> None:
135+
"""Swagger docs should be available at /docs."""
136+
response = client.get("/docs")
137+
138+
# Swagger UI returns 200
139+
assert response.status_code == 200
140+
141+
def test_redoc_endpoint_exists(self, client: TestClient) -> None:
142+
"""ReDoc should be available at /redoc."""
143+
response = client.get("/redoc")
144+
145+
assert response.status_code == 200
146+
147+
def test_openapi_json_exists(self, client: TestClient) -> None:
148+
"""OpenAPI schema should be available at /openapi.json."""
149+
response = client.get("/openapi.json")
150+
151+
assert response.status_code == 200
152+
data = response.json()
153+
assert "openapi" in data
154+
assert "info" in data
155+
assert data["info"]["title"] == "pyplots API"
156+
157+
158+
class TestCORSMiddleware:
159+
"""Tests for CORS configuration."""
160+
161+
def test_cors_allows_localhost(self, client: TestClient) -> None:
162+
"""CORS should allow localhost origins."""
163+
response = client.options(
164+
"/", headers={"Origin": "http://localhost:3000", "Access-Control-Request-Method": "GET"}
165+
)
166+
167+
# Should not be blocked
168+
assert response.status_code in [200, 204, 400]
169+
170+
def test_cors_headers_present(self, client: TestClient) -> None:
171+
"""CORS headers should be present in response."""
172+
response = client.get("/", headers={"Origin": "http://localhost:3000"})
173+
174+
# The response should include CORS headers
175+
assert response.status_code == 200
176+
177+
178+
class TestAppConfiguration:
179+
"""Tests for app configuration."""
180+
181+
def test_app_title(self) -> None:
182+
"""App should have correct title."""
183+
assert app.title == "pyplots API"
184+
185+
def test_app_version(self) -> None:
186+
"""App should have correct version."""
187+
assert app.version == "0.1.0"
188+
189+
def test_app_description(self) -> None:
190+
"""App should have description."""
191+
assert "AI-powered" in app.description
192+
assert "plotting" in app.description.lower()

0 commit comments

Comments
 (0)