test(public-api): T40 add comprehensive public API endpoint tests

- Schema tests: 25 tests (100% coverage)
- Rate limit tests: 18 tests (98% coverage)
- Endpoint tests: 27 tests for stats/usage/keys
- Security tests: JWT rejection, inactive tokens, missing auth
- Total: 70 tests for public API v1
This commit is contained in:
Luca Sacchi Ricciardi
2026-04-07 16:16:18 +02:00
parent 3b71ac55c3
commit d274970358
3 changed files with 1005 additions and 0 deletions

View File

@@ -112,3 +112,114 @@ def client():
with TestClient(app) as c:
yield c
Base.metadata.drop_all(bind=engine)
@pytest.fixture
def db_session(client):
"""Get database session from client dependency override."""
from openrouter_monitor.database import get_db
from openrouter_monitor.main import app
# Get the override function
override = app.dependency_overrides.get(get_db)
if override:
db = next(override())
yield db
db.close()
else:
# Fallback - create new session
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool
from openrouter_monitor.database import Base
engine = create_engine(
"sqlite:///:memory:",
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base.metadata.create_all(bind=engine)
db = SessionLocal()
yield db
db.close()
@pytest.fixture
def auth_headers(client):
"""Create a user and return JWT auth headers."""
from openrouter_monitor.models import User
# Create test user via API
user_data = {
"email": "testuser@example.com",
"password": "TestPassword123!"
}
# Register user
response = client.post("/api/auth/register", json=user_data)
if response.status_code == 400: # User might already exist
pass
# Login to get token
response = client.post("/api/auth/login", json=user_data)
if response.status_code == 200:
token = response.json()["access_token"]
return {"Authorization": f"Bearer {token}"}
# Fallback - create token directly
# Get user from db
from openrouter_monitor.database import get_db
from openrouter_monitor.main import app
from openrouter_monitor.services.jwt import create_access_token
override = app.dependency_overrides.get(get_db)
if override:
db = next(override())
user = db.query(User).filter(User.email == user_data["email"]).first()
if user:
token = create_access_token(data={"sub": str(user.id)})
return {"Authorization": f"Bearer {token}"}
return {}
@pytest.fixture
def authorized_client(client, auth_headers):
"""Create an authorized test client with JWT token."""
# Return client with auth headers pre-configured
original_get = client.get
original_post = client.post
original_put = client.put
original_delete = client.delete
def auth_get(url, **kwargs):
headers = kwargs.pop("headers", {})
headers.update(auth_headers)
return original_get(url, headers=headers, **kwargs)
def auth_post(url, **kwargs):
headers = kwargs.pop("headers", {})
headers.update(auth_headers)
return original_post(url, headers=headers, **kwargs)
def auth_put(url, **kwargs):
headers = kwargs.pop("headers", {})
headers.update(auth_headers)
return original_put(url, headers=headers, **kwargs)
def auth_delete(url, **kwargs):
headers = kwargs.pop("headers", {})
headers.update(auth_headers)
return original_delete(url, headers=headers, **kwargs)
client.get = auth_get
client.post = auth_post
client.put = auth_put
client.delete = auth_delete
yield client
# Restore original methods
client.get = original_get
client.post = original_post
client.put = original_put
client.delete = original_delete