Files
ewoooc/tests/test_ai_history_service.py
ogt 1b4f3a7bbe
Some checks failed
CD Pipeline / deploy (push) Failing after 59s
feat: EwoooC 初始化 — 完整專案推版至 Gitea
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml)
- 部署模式: rsync Python 檔案至 188 → docker restart (volume mount)
- Dockerfile/requirements 變動時自動重建 Docker image
- 部署通知: Telegram (開始/成功/失敗)
- 健康檢查: https://mo.wooo.work/health (最多 5 次重試)
- 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 01:21:13 +08:00

155 lines
5.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI History Service 單元測試
測試修復後的功能是否正確運作
"""
import sys
import os
import json
from datetime import datetime, timedelta
# 確保可以 import 專案模組
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from services.ai_history_service import AIHistoryService, AITemplateService
def test_safe_json_dumps():
"""測試安全 JSON 序列化"""
print("\n=== 測試 _safe_json_dumps ===")
# 測試 None
result = AIHistoryService._safe_json_dumps(None)
assert result is None, f"None 應該返回 None實際: {result}"
print("✓ None 處理正確")
# 測試正常列表
result = AIHistoryService._safe_json_dumps(["關鍵字1", "關鍵字2"])
assert result == '["關鍵字1", "關鍵字2"]', f"列表序列化失敗: {result}"
print("✓ 列表序列化正確")
# 測試空列表
result = AIHistoryService._safe_json_dumps([])
assert result == '[]', f"空列表序列化失敗: {result}"
print("✓ 空列表序列化正確")
# 測試字典
result = AIHistoryService._safe_json_dumps({"key": "value"})
assert result == '{"key": "value"}', f"字典序列化失敗: {result}"
print("✓ 字典序列化正確")
# 測試不可序列化物件(應該轉為字串)
class UnserializableObject:
pass
result = AIHistoryService._safe_json_dumps(UnserializableObject())
assert result is not None, "不可序列化物件應該被轉為字串"
print("✓ 不可序列化物件處理正確")
print("=== _safe_json_dumps 測試全部通過 ===")
def test_input_validation():
"""測試輸入驗證"""
print("\n=== 測試輸入驗證 ===")
# 模擬測試 get_history_list 的輸入驗證邏輯
def validate_pagination(page, per_page):
page = max(1, page)
per_page = max(1, min(100, per_page))
return page, per_page
# 測試負數頁碼
page, per_page = validate_pagination(-5, 20)
assert page == 1, f"負數頁碼應該被修正為 1實際: {page}"
print("✓ 負數頁碼驗證正確")
# 測試零頁碼
page, per_page = validate_pagination(0, 20)
assert page == 1, f"零頁碼應該被修正為 1實際: {page}"
print("✓ 零頁碼驗證正確")
# 測試每頁數量超出限制
page, per_page = validate_pagination(1, 500)
assert per_page == 100, f"每頁數量應該被限制為 100實際: {per_page}"
print("✓ 每頁數量上限驗證正確")
# 測試每頁數量為零
page, per_page = validate_pagination(1, 0)
assert per_page == 1, f"每頁數量零應該被修正為 1實際: {per_page}"
print("✓ 每頁數量下限驗證正確")
# 模擬測試 get_statistics 的 days 驗證邏輯
def validate_days(days):
return max(1, min(365, days))
# 測試負數天數
days = validate_days(-10)
assert days == 1, f"負數天數應該被修正為 1實際: {days}"
print("✓ 負數天數驗證正確")
# 測試超大天數
days = validate_days(1000)
assert days == 365, f"超大天數應該被限制為 365實際: {days}"
print("✓ 天數上限驗證正確")
print("=== 輸入驗證測試全部通過 ===")
def test_batch_delete_empty_list():
"""測試批次刪除空列表"""
print("\n=== 測試 batch_delete 空列表 ===")
result = AIHistoryService.batch_delete([])
assert result['success_count'] == 0, f"空列表刪除數應為 0實際: {result['success_count']}"
assert result['failed_ids'] == [], f"空列表失敗 ID 應為空,實際: {result['failed_ids']}"
print("✓ 空列表處理正確")
print("=== batch_delete 空列表測試通過 ===")
def test_service_instantiation():
"""測試服務實例化"""
print("\n=== 測試服務實例化 ===")
# 測試可以正常 import 和使用
from services.ai_history_service import ai_history_service, ai_template_service
assert ai_history_service is not None, "ai_history_service 應該存在"
assert ai_template_service is not None, "ai_template_service 應該存在"
print("✓ 全域服務實例創建成功")
print("=== 服務實例化測試通過 ===")
def run_all_tests():
"""執行所有測試"""
print("=" * 50)
print("AI History Service 單元測試")
print("=" * 50)
try:
test_safe_json_dumps()
test_input_validation()
test_batch_delete_empty_list()
test_service_instantiation()
print("\n" + "=" * 50)
print("✅ 所有測試通過!")
print("=" * 50)
return True
except AssertionError as e:
print(f"\n❌ 測試失敗: {e}")
return False
except Exception as e:
print(f"\n❌ 測試異常: {e}")
import traceback
traceback.print_exc()
return False
if __name__ == "__main__":
success = run_all_tests()
sys.exit(0 if success else 1)