69 lines
2.5 KiB
Python
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"
|