You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/scripts/tests/lib.sh

300 lines
6.3 KiB
Bash

#!/bin/bash
#
# 测试公共函数库
#
# 注意:不在库文件中设置 set -e由调用脚本控制
# 配置
BASE_URL="${BASE_URL:-http://localhost:4000}"
TEST_TIMESTAMP="${TEST_TIMESTAMP:-$(date +%s)}"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# ========================================
# 辅助函数
# ========================================
# 打印带颜色的信息
info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
success() {
echo -e "${GREEN}[PASS]${NC} $1"
}
error() {
echo -e "${RED}[FAIL]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# 检查上一个命令是否成功(传递状态码)
# $1: 描述
# $2: 状态码(可选,默认使用 $?
check_success() {
local status=${2:-$?}
if [ $status -eq 0 ]; then
success "$1"
return 0
else
error "$1"
return 1
fi
}
# 检查上一个命令是否失败(用于测试权限拒绝)
check_fail() {
if [ $? -ne 0 ]; then
success "$1 (预期失败)"
return 0
else
error "$1 (应该失败但没有)"
return 1
fi
}
# 检查HTTP响应码
# $1: 响应内容
# $2: 期望状态码(默认 200
check_http_code() {
local response="$1"
local expected="${2:-200}"
local code
# 处理空响应(成功时可能返回空体)
if [ -z "$response" ]; then
code="200"
else
# 提取 code 字段,如果不存在则认为是 200
local json_code
json_code=$(echo "$response" | jq -r '.code // empty')
if [ -z "$json_code" ] || [ "$json_code" = "empty" ]; then
code="200"
elif [[ "$json_code" =~ ^[0-9]+$ ]]; then
code="$json_code"
else
# code 字段存在但不是数字(可能是业务字段,如 org.code视为成功 200
code="200"
fi
fi
if [ "$code" = "$expected" ]; then
return 0
else
error "期望状态码: $expected, 实际: $code"
info "响应: $response"
return 1
fi
}
# 检查服务是否运行
check_service() {
if ! curl -s "$BASE_URL/api/auth/login-methods" > /dev/null 2>&1; then
error "服务未启动,请先启动服务"
info "运行: go run cli/main.go -db.type=sqlite -db.dsn /tmp/vb.sqlite -p 4000"
exit 1
fi
success "服务正在运行"
}
# ========================================
# API 请求封装
# ========================================
# GET 请求
api_get() {
local path="$1"
local token="${2:-}"
local curl_opts=("-s" "-X" "GET")
if [ -n "$token" ]; then
curl_opts+=("-H" "Authorization: Bearer $token")
fi
curl "${curl_opts[@]}" "$BASE_URL$path"
}
# POST 请求
api_post() {
local path="$1"
local data="$2"
local token="${3:-}"
local extra_headers="${4:-}"
local curl_opts=("-s" "-X" "POST" "-H" "Content-Type: application/json")
if [ -n "$token" ]; then
curl_opts+=("-H" "Authorization: Bearer $token")
fi
if [ -n "$extra_headers" ]; then
# 将 extra_headers 按空格分割添加到数组
for header in $extra_headers; do
curl_opts+=("-H" "$header")
done
fi
curl "${curl_opts[@]}" "$BASE_URL$path" -d "$data"
}
# PATCH 请求
api_patch() {
local path="$1"
local data="$2"
local token="${3:-}"
local extra_headers="${4:-}"
local curl_opts=("-s" "-X" "PATCH" "-H" "Content-Type: application/json")
if [ -n "$token" ]; then
curl_opts+=("-H" "Authorization: Bearer $token")
fi
if [ -n "$extra_headers" ]; then
for header in $extra_headers; do
curl_opts+=("-H" "$header")
done
fi
curl "${curl_opts[@]}" "$BASE_URL$path" -d "$data"
}
# DELETE 请求
api_delete() {
local path="$1"
local token="${2:-}"
local extra_headers="${3:-}"
local curl_opts=("-s" "-X" "DELETE")
if [ -n "$token" ]; then
curl_opts+=("-H" "Authorization: Bearer $token")
fi
if [ -n "$extra_headers" ]; then
for header in $extra_headers; do
curl_opts+=("-H" "$header")
done
fi
curl "${curl_opts[@]}" "$BASE_URL$path"
}
# ========================================
# 用户相关操作
# ========================================
# 注册用户
# 返回: 注册响应
register_user() {
local username="$1"
local password="$2"
local email="$3"
api_post "/api/auth/register" \
"{\"username\": \"$username\", \"password\": \"$password\", \"email\": \"$email\"}"
}
# 登录用户
# 返回: 登录响应
login_user() {
local username="$1"
local password="$2"
api_post "/api/auth/login" \
"{\"username\": \"$username\", \"password\": \"$password\"}"
}
# 提取 access_token
get_token() {
local login_response="$1"
echo "$login_response" | jq -r '.access_token'
}
# 提取 refresh_token
get_refresh_token() {
local login_response="$1"
echo "$login_response" | jq -r '.refresh_token'
}
# 提取用户ID
get_user_id() {
local login_response="$1"
echo "$login_response" | jq -r '.user.id'
}
# ========================================
# 组织相关操作
# ========================================
# 创建组织
create_org() {
local token="$1"
local code="$2"
local name="$3"
local desc="${4:-}"
api_post "/api/orgs" \
"{\"code\": \"$code\", \"name\": \"$name\", \"description\": \"$desc\"}" \
"$token"
}
# 更新组织
update_org() {
local token="$1"
local org_id="$2"
local data="$3"
api_patch "/api/orgs/$org_id" "$data" "$token" "-H X-Org-ID: $org_id"
}
# 添加组织成员
add_org_member() {
local token="$1"
local org_id="$2"
local user_id="$3"
local role="${4:-member}"
api_post "/api/orgs/$org_id/members" \
"{\"user_id\": \"$user_id\", \"role\": \"$role\"}" \
"$token" \
"-H X-Org-ID: $org_id"
}
# ========================================
# 测试框架
# ========================================
# 测试开始
test_start() {
local name="$1"
echo ""
echo "========================================"
echo "测试: $name"
echo "========================================"
}
# 测试步骤
step() {
echo ""
info "$1"
}
# 测试结束
test_end() {
echo ""
success "测试完成"
}