test: 支付链路自动化测试(SQL间隔一致性+部署后支付流程测试)
This commit is contained in:
116
lib/test.sh
116
lib/test.sh
@@ -151,6 +151,121 @@ test_migration_status() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# ---------- 支付链路测试 ----------
|
||||
|
||||
test_payment_flow() {
|
||||
log_info "开始支付链路测试..."
|
||||
|
||||
# 阶段 1:检查订单到期时间计算与套餐天数是否一致
|
||||
# 通过 SQL 直接创建测试订单(避免 JWT 依赖),验证 order.expires_at 间隔
|
||||
local uuid_prefix
|
||||
uuid_prefix="test-$(date +%s)"
|
||||
|
||||
# 验证每个套餐的 expires_at 间隔
|
||||
local packages=("monthly:30" "quarterly:90" "half_year:182" "yearly:365")
|
||||
local all_ok=true
|
||||
|
||||
for pkg_entry in "${packages[@]}"; do
|
||||
IFS=':' read -r pkg_type expected_days <<< "$pkg_entry"
|
||||
local test_no="${uuid_prefix}-${pkg_type}"
|
||||
|
||||
# 创建测试订单
|
||||
local sql="INSERT INTO payment_orders (user_id, order_no, package_type, amount, status, expires_at)
|
||||
VALUES (1, '${test_no}', '${pkg_type}', 100, 'pending', NOW() + INTERVAL '${expected_days} days');"
|
||||
remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${sql}\"" 2>/dev/null || true
|
||||
|
||||
# 验证到期时间间隔
|
||||
local interval_days
|
||||
interval_days=$(remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -tAc \"
|
||||
SELECT EXTRACT(DAY FROM (expires_at - created_at)) FROM payment_orders WHERE order_no = '${test_no}';
|
||||
\"" 2>/dev/null || echo "0")
|
||||
interval_days=${interval_days%.*}
|
||||
|
||||
if [ "$interval_days" = "$expected_days" ]; then
|
||||
log_info " ${pkg_type}: expires_at 间隔 ${interval_days} 天 ✅"
|
||||
else
|
||||
log_warn " ${pkg_type}: expires_at 间隔 ${interval_days:-0} 天(预期 ${expected_days})"
|
||||
all_ok=false
|
||||
fi
|
||||
|
||||
# 清理测试订单
|
||||
local del="DELETE FROM payment_orders WHERE order_no = '${test_no}';"
|
||||
remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${del}\"" 2>/dev/null || true
|
||||
done
|
||||
|
||||
# 阶段 2:测试提交订单后的会员时长(仅开发环境有 mock 支付)
|
||||
if [ "${MOCK_PAY_ENABLED:-false}" = "true" ]; then
|
||||
local mock_key
|
||||
mock_key=$(remote "grep 'MOCK_PAY_KEY' /etc/systemd/system/${SERVICE_NAME} 2>/dev/null | head -1 | sed 's/.*MOCK_PAY_KEY=//'" 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$mock_key" ]; then
|
||||
log_info " Mock 支付可用,测试完整支付链路..."
|
||||
|
||||
# 1. 获取 mock JWT
|
||||
local login_resp
|
||||
login_resp=$(remote "curl -s --max-time 10 'http://127.0.0.1:${BACKEND_PORT}/api/mock-login' -H 'X-Mock-Key: ${mock_key}'" 2>/dev/null || echo "")
|
||||
local token
|
||||
token=$(echo "$login_resp" | grep -o '"token":"[^"]*"' | head -1 | cut -d'"' -f4 || echo "")
|
||||
|
||||
if [ -n "$token" ]; then
|
||||
# 2. 创建月度订单
|
||||
local order_page
|
||||
order_page=$(remote "curl -s --max-time 10 'http://127.0.0.1:${BACKEND_PORT}/payment/page?package=monthly&jwt=${token}'" 2>/dev/null || echo "")
|
||||
|
||||
# 3. 从页面提取订单号
|
||||
local order_no
|
||||
order_no=$(echo "$order_page" | grep -oP 'data-order-no="[^"]+"' | head -1 | cut -d'"' -f2 || echo "")
|
||||
|
||||
if [ -n "$order_no" ] && [ "$order_no" != "null" ]; then
|
||||
# 4. Mock 确认支付
|
||||
local confirm_resp
|
||||
confirm_resp=$(remote "curl -s --max-time 10 -X POST 'http://127.0.0.1:${BACKEND_PORT}/api/payment/mock-confirm' \
|
||||
-H 'Authorization: Bearer ${token}' \
|
||||
-H 'X-Mock-Key: ${mock_key}' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{\"order_id\":\"${order_no}\"}'" 2>/dev/null || echo "")
|
||||
|
||||
# 5. 验证会员时长
|
||||
local member_expires
|
||||
member_expires=$(remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -tAc \"
|
||||
SELECT EXTRACT(DAY FROM (membership_expires_at - NOW()))::int
|
||||
FROM users WHERE id = 1;
|
||||
\"" 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$member_expires" -ge 25 ]; then
|
||||
log_info " 支付链路完整测试通过:会员增加 ${member_expires} 天 ✅"
|
||||
else
|
||||
log_warn " 会员仅增加 ${member_expires} 天(预期 >= 25)"
|
||||
all_ok=false
|
||||
fi
|
||||
|
||||
# 6. 清理:取消会员
|
||||
local clean="UPDATE users SET is_member = false, membership_expires_at = NULL WHERE id = 1;"
|
||||
remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${clean}\"" 2>/dev/null || true
|
||||
local cancel="UPDATE payment_orders SET status = 'cancelled' WHERE order_no = '${order_no}' AND status = 'paid';"
|
||||
remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${cancel}\"" 2>/dev/null || true
|
||||
else
|
||||
log_warn " 未获取到订单号,跳过 mock 确认测试"
|
||||
fi
|
||||
else
|
||||
log_warn " 获取 mock JWT 失败,跳过完整支付链路测试"
|
||||
fi
|
||||
else
|
||||
log_info " 未配置 MOCK_PAY_KEY(生产环境正常),跳过 mock 确认测试"
|
||||
fi
|
||||
else
|
||||
log_info " 非开发环境,跳过 mock 支付链路测试"
|
||||
fi
|
||||
|
||||
if $all_ok; then
|
||||
log_info "支付链路测试通过"
|
||||
return 0
|
||||
else
|
||||
log_warn "支付链路测试有异常"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------- 主测试入口 ----------
|
||||
run_tests() {
|
||||
log_step "执行部署后测试..."
|
||||
@@ -166,6 +281,7 @@ run_tests() {
|
||||
"test_response_content:响应内容验证"
|
||||
"test_mock_login:Mock 登录 + 通知接口"
|
||||
"test_payment_endpoints:支付端点"
|
||||
"test_payment_flow:支付链路"
|
||||
"test_migration_status:迁移状态"
|
||||
)
|
||||
local i=1 total=${#tests[@]}
|
||||
|
||||
Reference in New Issue
Block a user