All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 7m18s
- tests/integration/conftest.py: 連接 awoooi_dev PostgreSQL,每個測試後 rollback - tests/integration/test_knowledge_repository.py: 23 個真實 DB 測試 - create/get_by_id/list/update/delete(軟刪除)/search/categories/view_count - tests/integration/test_incident_api.py: 7 個 HTTPS 端點測試 - health check + knowledge API smoke test - 遵循禁止 Mock 鐵律 (feedback_no_mock_testing.md) - 本地驗證: 30/30 PASSED Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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 決策生成 (LLM 呼叫),回應時間 30s+,
|
||
不適合整合測試。應使用 smoke_test_alert_chain.py 驗證。
|
||
"""
|
||
|
||
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"
|