crowncode-backend / tests /test_commend.py
Rthur2003's picture
fix: add tests for auth failure without API key and ensure rate limiting applies regardless of auth
de799a3
"""Tests for Crown Commend endpoints."""
from __future__ import annotations
from fastapi.testclient import TestClient
def test_commend_health(client: TestClient) -> None:
"""Commend health endpoint should return status information."""
response = client.get("/api/commend/health")
assert response.status_code == 200
data = response.json()
assert "status" in data
assert "geminiConfigured" in data
assert "youtubeConfigured" in data
def test_commend_styles(client: TestClient) -> None:
"""Styles endpoint should return available comment styles."""
response = client.get("/api/commend/styles")
assert response.status_code == 200
data = response.json()
assert "styles" in data
assert len(data["styles"]) > 0
def test_commend_generate_rejects_invalid_url(client: TestClient) -> None:
"""Generate endpoint should reject a non-YouTube URL."""
response = client.post(
"/api/commend/generate",
json={
"videoUrl": "https://example.com",
"language": "English",
"commentStyle": "supportive",
},
)
# 400 (invalid url), 401 (auth), 422 (validation), 503 (auth not configured)
assert response.status_code in (400, 401, 422, 429, 503)
def test_commend_generate_rejects_empty_url(client: TestClient) -> None:
"""Generate endpoint should reject empty URL."""
response = client.post(
"/api/commend/generate",
json={
"videoUrl": "",
"language": "English",
"commentStyle": "supportive",
},
)
# 422 (Pydantic min_length), 401 (auth), 503 (auth not configured)
assert response.status_code in (401, 422, 429, 503)
def test_commend_post_disabled_by_default(client: TestClient) -> None:
"""Post endpoint should be disabled by default (feature flag)."""
response = client.post(
"/api/commend/post",
json={
"videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"commentText": "Test comment",
},
)
# 401 (auth), 403 (feature flag disabled), 503 (auth not configured)
assert response.status_code in (401, 403, 429, 503)
def test_commend_post_error_envelope_format(client: TestClient) -> None:
"""Error responses should use {code, message} envelope format."""
response = client.post(
"/api/commend/post",
json={
"videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"commentText": "Test comment",
},
)
if response.status_code in (401, 403, 503):
data = response.json()
detail = data.get("detail", {})
if isinstance(detail, dict):
assert "code" in detail
assert "message" in detail
def test_commend_auth_fail_closed_without_key(client: TestClient) -> None:
"""Without COMMEND_API_KEY set, protected endpoints should reject (fail-closed)."""
response = client.post(
"/api/commend/generate",
json={
"videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"language": "English",
"commentStyle": "supportive",
},
)
# With COMMEND_REQUIRE_AUTH=true (default) and no key, expect 429 or 503
assert response.status_code in (429, 503)
def test_commend_rate_limit_independent_of_auth(client: TestClient) -> None:
"""Rate limiting should apply regardless of auth configuration."""
# Send multiple rapid requests — rate limit should apply even without auth key
statuses = []
for _ in range(15):
response = client.post(
"/api/commend/generate",
json={
"videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"language": "English",
"commentStyle": "supportive",
},
)
statuses.append(response.status_code)
# Should see at least one 429 in the batch (rate limit is 10/min)
assert 429 in statuses, f"Expected 429 in statuses but got: {set(statuses)}"