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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user