test-open-api.sh
5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/bin/bash
# ============================================================
# Open API 人工测试脚本
# 用法: ./start.sh & 然后运行 bash scripts/test-open-api.sh
# ============================================================
BASE="http://localhost:3000/api/open"
KEY="sk-test-key-001"
H="-H X-API-Key:$KEY"
GREEN='\033[0;32m'; RED='\033[0;31m'; CYAN='\033[0;36m'; NC='\033[0m'
PASS=0; FAIL=0
check() {
if [ $1 -eq 0 ]; then echo -e "${GREEN}✓ PASS${NC} — $2"; PASS=$((PASS+1))
else echo -e "${RED}✗ FAIL${NC} — $2"; FAIL=$((FAIL+1)); fi
}
echo ""
echo "════════════════════════════════════════"
echo " Open API Integration Test"
echo "════════════════════════════════════════"
# ── T1: 无 Key → 401 ──
echo -e "\n${CYAN}T1: 认证 — 无 Key${NC}"
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/skills/search?q=test")
[ "$STATUS" = "401" ]; check $? "无 Key 返回 401 (got $STATUS)"
# ── T2: 错误 Key → 401 ──
echo -e "${CYAN}T2: 认证 — 错误 Key${NC}"
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "X-API-Key: wrong" "$BASE/skills/search?q=test")
[ "$STATUS" = "401" ]; check $? "错误 Key 返回 401 (got $STATUS)"
# ── T3: 搜索命中 ──
echo -e "\n${CYAN}T3: 搜索命中 — writer${NC}"
RESP=$(curl -s -H "X-API-Key: $KEY" "$BASE/skills/search?q=writer")
TOTAL=$(echo "$RESP" | python3 -c "import json,sys; print(json.load(sys.stdin)['total'])" 2>/dev/null)
[ "$TOTAL" -gt 0 ] 2>/dev/null; check $? "搜索 'writer' 命中 $TOTAL 个 Skill"
# ── T4: 搜索中文 ──
echo -e "${CYAN}T4: 搜索中文 — 诗歌${NC}"
RESP=$(curl -s -G -H "X-API-Key: $KEY" --data-urlencode "q=诗歌" "$BASE/skills/search")
TOTAL=$(echo "$RESP" | python3 -c "import json,sys; print(json.load(sys.stdin)['total'])" 2>/dev/null)
[ "$TOTAL" -gt 0 ] 2>/dev/null; check $? "搜索 '诗歌' 命中 $TOTAL 个 Skill"
# ── T5: Skill 详情 ──
echo -e "\n${CYAN}T5: Skill 详情 — novel_writer${NC}"
RESP=$(curl -s -H "X-API-Key: $KEY" "$BASE/skills/novel_writer")
NAME=$(echo "$RESP" | python3 -c "import json,sys; print(json.load(sys.stdin).get('skillName',''))" 2>/dev/null)
DIR=$(echo "$RESP" | python3 -c "import json,sys; print('directory' in json.load(sys.stdin))" 2>/dev/null)
[ "$NAME" = "novel_writer" ]; check $? "返回 skillName=novel_writer"
[ "$DIR" = "False" ]; check $? "不泄露 directory 字段"
# ── T6: 404 Skill ──
echo -e "${CYAN}T6: 不存在的 Skill${NC}"
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "X-API-Key: $KEY" "$BASE/skills/nonexistent_xyz")
[ "$STATUS" = "404" ]; check $? "返回 404 (got $STATUS)"
# ── T7: 下载 .zip ──
echo -e "\n${CYAN}T7: 下载 Skill — novel_writer.zip${NC}"
TMPZIP="/tmp/test_novel_writer_$$.zip"
curl -s -H "X-API-Key: $KEY" -o "$TMPZIP" "$BASE/skills/novel_writer/download"
FILETYPE=$(file "$TMPZIP" 2>/dev/null)
echo "$FILETYPE" | grep -qi "zip"; check $? "返回的是 Zip 文件"
FILECOUNT=$(unzip -l "$TMPZIP" 2>/dev/null | tail -1 | awk '{print $2}')
[ "$FILECOUNT" -gt 1 ] 2>/dev/null; check $? "Zip 包含 $FILECOUNT 个文件"
# 检查内部结构
unzip -l "$TMPZIP" 2>/dev/null | grep -q "SKILL.md"; check $? "Zip 包含 SKILL.md"
unzip -l "$TMPZIP" 2>/dev/null | grep -q "manifest.json"; check $? "Zip 包含 manifest.json"
rm -f "$TMPZIP"
# ── T8: Job 列表 ──
echo -e "\n${CYAN}T8: Job 列表${NC}"
RESP=$(curl -s -H "X-API-Key: $KEY" "$BASE/jobs")
echo "$RESP" | python3 -c "import json,sys; json.load(sys.stdin)['total']" >/dev/null 2>&1
check $? "Job 列表返回正常"
# ── T9: 搜索未命中 → 自动创建 ──
echo -e "\n${CYAN}T9: 搜索未命中 → autoCreate${NC}"
RESP=$(curl -s -G -H "X-API-Key: $KEY" --data-urlencode "q=量子计算模拟器XYZ" "$BASE/skills/search")
TOTAL=$(echo "$RESP" | python3 -c "import json,sys; print(json.load(sys.stdin)['total'])" 2>/dev/null)
JOBID=$(echo "$RESP" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('autoCreate',{}).get('jobId',''))" 2>/dev/null)
[ "$TOTAL" = "0" ]; check $? "搜索结果为空 (total=0)"
[ -n "$JOBID" ] && [ "$JOBID" != "" ]; check $? "自动创建返回 jobId=$JOBID"
# 查询 job 状态
if [ -n "$JOBID" ] && [ "$JOBID" != "" ]; then
echo -e "${CYAN} → 查询 Job 状态${NC}"
JOB_STATUS=$(curl -s -H "X-API-Key: $KEY" "$BASE/jobs/$JOBID" | python3 -c "import json,sys; print(json.load(sys.stdin).get('status',''))" 2>/dev/null)
[ -n "$JOB_STATUS" ]; check $? "Job 状态: $JOB_STATUS"
fi
# ── T10: API 日志 ──
echo -e "\n${CYAN}T10: API 访问日志${NC}"
LOGFILE="apiconversation/$(date +%Y-%m-%d).jsonl"
[ -f "$LOGFILE" ]; check $? "日志文件存在: $LOGFILE"
if [ -f "$LOGFILE" ]; then
LINES=$(wc -l < "$LOGFILE" | tr -d '[:space:]')
[ "$LINES" -gt 0 ] 2>/dev/null; check $? "日志已记录 $LINES 条请求"
fi
# ── 结果 ──
echo ""
echo "════════════════════════════════════════"
echo -e " 结果: ${GREEN}$PASS PASS${NC} / ${RED}$FAIL FAIL${NC}"
echo "════════════════════════════════════════"
echo ""