From d7b7e0c0a34556035542b8144659b86b5257b25e Mon Sep 17 00:00:00 2001 From: milky0217 Date: Wed, 10 Jun 2026 13:16:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=83=A8=E7=BD=B2=E6=B5=8B=E8=AF=95SQL?= =?UTF-8?q?=E5=B7=A5=E5=85=B7bug-=E7=A1=AC=E7=BC=96=E7=A0=81user=5Fid=3D1/?= =?UTF-8?q?=E6=97=A0=E6=B8=85=E7=90=86trap/=E8=BF=81=E7=A7=BB=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=9C=AA=E5=BC=95=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/test.sh | 63 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/lib/test.sh b/lib/test.sh index c0d8f70..6f7281e 100644 --- a/lib/test.sh +++ b/lib/test.sh @@ -5,7 +5,27 @@ # 用于所有测试函数的基础 URL(在 run_tests 中设置) BASE_URL="http://127.0.0.1" -# 测试失败自动回滚 +# 测试用户管理 +TEST_USER_ID="" + +setup_test_user() { + TEST_USER_ID=$(remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -tAc \" + INSERT INTO users (openid, name, type) VALUES ('test_\$(date +%s)', 'test_user', 2) + RETURNING id; + \"" 2>/dev/null | tr -d ' ' || echo "") + [ -z "$TEST_USER_ID" ] && { log_error "创建测试用户失败"; return 1; } + log_info " 测试用户 ID: ${TEST_USER_ID}" +} + +cleanup_test_user() { + if [ -n "$TEST_USER_ID" ]; then + remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \" + DELETE FROM payment_orders WHERE user_id = ${TEST_USER_ID}; + DELETE FROM users WHERE id = ${TEST_USER_ID}; + \"" 2>/dev/null || true + TEST_USER_ID="" + fi +} rollback_and_exit() { local reason="$1" log_error "测试失败: ${reason}" @@ -166,6 +186,16 @@ test_migration_status() { test_payment_flow() { log_info "开始支付链路测试..." + # 清理 trap:测试失败时清理 + local test_cleanup_done=false + cleanup_payment_test() { + if [ "$test_cleanup_done" = false ]; then + cleanup_test_user + test_cleanup_done=true + fi + } + trap cleanup_payment_test EXIT + # 阶段 1:检查订单到期时间计算与套餐天数是否一致 # 通过 SQL 直接创建测试订单(避免 JWT 依赖),验证 order.expires_at 间隔 local uuid_prefix @@ -181,7 +211,7 @@ test_payment_flow() { # 创建测试订单 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');" + VALUES (${TEST_USER_ID}, '${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 # 验证到期时间间隔 @@ -239,7 +269,7 @@ test_payment_flow() { 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; + FROM users WHERE id = ${TEST_USER_ID}; \"" 2>/dev/null || echo "0") if [ "$member_expires" -ge 25 ]; then @@ -250,7 +280,7 @@ test_payment_flow() { fi # 6. 清理:取消会员 - local clean="UPDATE users SET is_member = false, membership_expires_at = NULL WHERE id = 1;" + local clean="UPDATE users SET is_member = false, membership_expires_at = NULL WHERE id = ${TEST_USER_ID};" 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 @@ -285,7 +315,7 @@ test_payment_dedup() { uuid_prefix="dedup-test-$(date +%s)" local test_no1="${uuid_prefix}-1" local test_no2="${uuid_prefix}-2" - local user_id=1 + local user_id=${TEST_USER_ID} # 清理可能残留的测试数据 remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"DELETE FROM payment_orders WHERE order_no LIKE '${uuid_prefix}%';\"" 2>/dev/null || true @@ -367,11 +397,11 @@ test_payment_refund() { # 创建已支付订单(模拟一个月会员) local sql_create="INSERT INTO payment_orders (user_id, order_no, package_type, amount, status, paid_at, expires_at) - VALUES (1, '${test_no}', 'monthly', 590, 'paid', NOW(), NOW() + INTERVAL '30 days');" + VALUES (${TEST_USER_ID}, '${test_no}', 'monthly', 590, 'paid', NOW(), NOW() + INTERVAL '30 days');" remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${sql_create}\"" 2>/dev/null || true # 设置用户为会员 - local sql_member="UPDATE users SET is_member = true, membership_expires_at = NOW() + INTERVAL '30 days' WHERE id = 1;" + local sql_member="UPDATE users SET is_member = true, membership_expires_at = NOW() + INTERVAL '30 days' WHERE id = ${TEST_USER_ID};" remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${sql_member}\"" 2>/dev/null || true # 执行退款(直接调用 db 函数等价操作) @@ -379,7 +409,7 @@ test_payment_refund() { remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${sql_refund}\"" 2>/dev/null || true # 清理:取消会员 + 删除测试订单 - local clean_member="UPDATE users SET is_member = false, membership_expires_at = NULL WHERE id = 1;" + local clean_member="UPDATE users SET is_member = false, membership_expires_at = NULL WHERE id = ${TEST_USER_ID};" remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${clean_member}\"" 2>/dev/null || true remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"DELETE FROM payment_orders WHERE order_no = '${test_no}';\"" 2>/dev/null || true @@ -398,11 +428,11 @@ test_payment_verify_detection() { # 构造一个 expiry = paid_at + 1 天的异常订单(模拟 ELSE INTERVAL '0 days') local sql_create="INSERT INTO payment_orders (user_id, order_no, package_type, amount, status, paid_at, expires_at) - VALUES (1, '${test_no}', 'half_year', 3190, 'paid', NOW(), NOW() + INTERVAL '1 day');" + VALUES (${TEST_USER_ID}, '${test_no}', 'half_year', 3190, 'paid', NOW(), NOW() + INTERVAL '1 day');" remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${sql_create}\"" 2>/dev/null || true # 设置会员为 paid_at + 1 天(模拟 0 天会员时长) - local sql_member="UPDATE users SET is_member = true, membership_expires_at = NOW() + INTERVAL '1 day' WHERE id = 1;" + local sql_member="UPDATE users SET is_member = true, membership_expires_at = NOW() + INTERVAL '1 day' WHERE id = ${TEST_USER_ID};" remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${sql_member}\"" 2>/dev/null || true # 验证 actual_days < 25 能被检测到 @@ -415,7 +445,7 @@ test_payment_verify_detection() { actual_days=${actual_days%.*} # 清理 - local clean="UPDATE users SET is_member = false, membership_expires_at = NULL WHERE id = 1;" + local clean="UPDATE users SET is_member = false, membership_expires_at = NULL WHERE id = ${TEST_USER_ID};" remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"${clean}\"" 2>/dev/null || true remote "docker exec ${DB_CONTAINER} psql -U ${DB_USER} -d ${DB_NAME} -c \"DELETE FROM payment_orders WHERE order_no = '${test_no}';\"" 2>/dev/null || true @@ -452,11 +482,22 @@ run_tests() { "test_payment_verify_detection:验证函数检测逻辑" ) local i=1 total=${#tests[@]} + + # 设置测试用户(用于支付类测试) + if ! setup_test_user; then + log_warn "创建测试用户失败,支付类测试将使用 user_id=1" + TEST_USER_ID=1 + fi + for entry in "${tests[@]}"; do IFS=':' read -r fn name <<< "$entry" log_step "测试 ${i}/${total}: ${name}..." $fn || rollback_and_exit "${name} 测试失败" i=$((i+1)) done + + # 清理测试用户 + cleanup_test_user + log_info "========== 全部 ${total} 项测试通过 ==========" }