97 lines
3.0 KiB
Python
97 lines
3.0 KiB
Python
"""
|
|
Incident API 整合測試
|
|
=======================
|
|
打真實 API 端點 (https://awoooi.wooo.work),使用真實 DB
|
|
|
|
建立時間: 2026-04-04 (台北時區)
|
|
建立者: Claude Code (整合測試 Phase 1)
|
|
|
|
規則:
|
|
- 使用 httpx 打真實 HTTPS 端點
|
|
- 禁止 Mock
|
|
- 不依賴特定資料存在 (resilient assertions)
|
|
|
|
測試覆蓋:
|
|
- GET /api/v1/health — API 健康確認
|
|
- GET /api/v1/knowledge — 知識庫列表/搜尋
|
|
- GET /api/v1/monitoring/status — 監控工具狀態
|
|
|
|
注意: GET /api/v1/incidents 不在此測試
|
|
原因: 該端點是前端輪詢路徑,應維持純讀與低延遲;
|
|
是否背景觸發 AI 決策由獨立 unit test 驗證,修復建議生成改走 proposal/operator-run 入口。
|
|
"""
|
|
|
|
import os
|
|
|
|
import httpx
|
|
import pytest
|
|
|
|
API_BASE = os.environ.get("API_BASE_URL", "https://awoooi.wooo.work")
|
|
|
|
|
|
# =============================================================================
|
|
# Fixtures
|
|
# =============================================================================
|
|
|
|
@pytest.fixture
|
|
def client():
|
|
with httpx.Client(base_url=API_BASE, timeout=15.0) as c:
|
|
yield c
|
|
|
|
|
|
# =============================================================================
|
|
# Health Check
|
|
# =============================================================================
|
|
|
|
class TestHealthCheck:
|
|
|
|
def test_health_returns_200(self, client):
|
|
resp = client.get("/api/v1/health")
|
|
assert resp.status_code == 200
|
|
|
|
def test_health_has_status_field(self, client):
|
|
resp = client.get("/api/v1/health")
|
|
data = resp.json()
|
|
assert "status" in data
|
|
|
|
def test_health_db_connected(self, client):
|
|
resp = client.get("/api/v1/health")
|
|
data = resp.json()
|
|
# DB 連線正常時 status 不為 error
|
|
assert data.get("status") != "error"
|
|
|
|
|
|
# =============================================================================
|
|
# Knowledge API
|
|
# =============================================================================
|
|
|
|
class TestKnowledgeApiSmoke:
|
|
|
|
def test_knowledge_list_returns_200(self, client):
|
|
resp = client.get("/api/v1/knowledge")
|
|
assert resp.status_code == 200
|
|
|
|
def test_knowledge_list_has_items_and_total(self, client):
|
|
resp = client.get("/api/v1/knowledge")
|
|
data = resp.json()
|
|
assert "items" in data
|
|
assert "total" in data
|
|
assert isinstance(data["total"], int)
|
|
|
|
def test_knowledge_search_returns_filtered(self, client):
|
|
resp = client.get("/api/v1/knowledge?q=SLA")
|
|
data = resp.json()
|
|
# 有結果時標題或內容應包含搜尋詞
|
|
for item in data["items"]:
|
|
assert (
|
|
"SLA" in item["title"]
|
|
or "SLA" in item["content"]
|
|
or "SLA" in str(item.get("tags", []))
|
|
)
|
|
|
|
def test_knowledge_category_filter(self, client):
|
|
resp = client.get("/api/v1/knowledge?category=infrastructure")
|
|
data = resp.json()
|
|
for item in data["items"]:
|
|
assert item["category"] == "infrastructure"
|