Files
Gov-chat-bot/backend/tests/test_middleware.py
2026-03-26 12:49:43 +09:00

69 lines
2.5 KiB
Python

import pytest
import pytest_asyncio
from httpx import AsyncClient, ASGITransport
from sqlalchemy import select
from app.core.middleware import tenanted_query, system_query, TenantMiddleware
from app.models.knowledge import FAQ
from app.main import app
@pytest.mark.asyncio
async def test_health_exempt_no_tenant_required(client):
"""GET /health → 200."""
response = await client.get("/health")
assert response.status_code == 200
@pytest.mark.asyncio
async def test_token_endpoint_exempt(client):
"""POST /api/admin/token → 400이 아닌 응답 (tenant 오류 아님)."""
response = await client.post("/api/admin/token")
# 엔드포인트가 없으면 404, 있으면 422/200 — 어떤 경우든 400(tenant_required)이 아님
assert response.status_code != 400 or response.json().get("error") != "tenant_required"
@pytest.mark.asyncio
async def test_api_request_without_auth_returns_401(client):
"""GET /api/admin/faqs (인증 없음) → 401 (admin 경로는 미들웨어 exempt, JWT 필요)."""
response = await client.get("/api/admin/faqs")
assert response.status_code == 401
def test_tenanted_query_without_tenant_id_raises_runtime_error():
"""tenanted_query(select(FAQ), FAQ, None) → RuntimeError 발생."""
with pytest.raises(RuntimeError):
tenanted_query(select(FAQ), FAQ, None)
def test_tenanted_query_with_tenant_id_adds_filter():
"""생성된 SQL에 'tenant_id' 포함 확인."""
query = tenanted_query(select(FAQ), FAQ, "test-tenant-id")
sql = str(query.compile())
assert "tenant_id" in sql
def test_tenanted_query_with_empty_string_raises():
"""tenanted_query(select(FAQ), FAQ, '') → RuntimeError 발생."""
with pytest.raises(RuntimeError):
tenanted_query(select(FAQ), FAQ, "")
def test_system_query_has_no_tenant_filter():
"""system_query(q) == q (변경 없음)."""
q = select(FAQ)
result = system_query(q)
assert result is q
@pytest.mark.asyncio
async def test_request_state_has_tenant_id_after_middleware(client):
"""X-Tenant-Slug 헤더 포함 요청 시 request.state.tenant_id 주입 확인."""
# 미들웨어가 tenant_id를 설정하면 400 대신 다른 응답 코드가 나와야 함
response = await client.get(
"/api/admin/faqs",
headers={"X-Tenant-Slug": "test-tenant"}
)
# tenant_required 오류가 아니어야 함 (404 또는 다른 응답)
assert response.status_code != 400 or response.json().get("error") != "tenant_required"