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

301 lines
6.3 KiB
Bash

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/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 "BASE_URL: $BASE_URL"
echo "========================================"
}
# 测试步骤
step() {
echo ""
info "$1"
}
# 测试结束
test_end() {
echo ""
success "测试完成"
}