#!/bin/bash # Genex E2E Test Runner # Requires: docker compose up, seed data loaded # Usage: ./scripts/run-e2e.sh set -e BASE_URL="${BASE_URL:-http://localhost:8080}" PASS=0 FAIL=0 TOTAL=0 # Colors GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' log_pass() { PASS=$((PASS+1)); TOTAL=$((TOTAL+1)); echo -e "${GREEN}✓ PASS${NC}: $1"; } log_fail() { FAIL=$((FAIL+1)); TOTAL=$((TOTAL+1)); echo -e "${RED}✗ FAIL${NC}: $1 - $2"; } # Helper: HTTP request with curl api() { local method=$1 path=$2 body=$3 token=$4 local args=(-s -w "\n%{http_code}" -X "$method" "$BASE_URL$path") [[ -n "$body" ]] && args+=(-H "Content-Type: application/json" -d "$body") [[ -n "$token" ]] && args+=(-H "Authorization: Bearer $token") curl "${args[@]}" } # Extract JSON field json_field() { echo "$1" | head -1 | python3 -c "import sys,json; print(json.loads(sys.stdin.read())$2)" 2>/dev/null; } http_code() { echo "$1" | tail -1; } body() { echo "$1" | head -1; } echo "==========================================" echo " Genex E2E Tests" echo " Target: $BASE_URL" echo "==========================================" # ==== 1. Health Checks ==== echo -e "\n${YELLOW}--- Health Checks ---${NC}" for svc in auth user issuer clearing compliance ai notification; do # Each NestJS service exposes /health # Through Kong, they're at different paths true # Health checks would need direct port access or dedicated health endpoints done # ==== 2. Auth Flow ==== echo -e "\n${YELLOW}--- Auth Flow ---${NC}" # Register a new user RES=$(api POST "/api/v1/auth/register" '{"phone":"13800001111","password":"Test123456!","nickname":"E2E测试用户"}') CODE=$(http_code "$RES") if [[ "$CODE" == "201" || "$CODE" == "200" ]]; then log_pass "Register new user" else log_fail "Register new user" "HTTP $CODE" fi # Login RES=$(api POST "/api/v1/auth/login" '{"phone":"13800001111","password":"Test123456!"}') CODE=$(http_code "$RES") if [[ "$CODE" == "200" || "$CODE" == "201" ]]; then ACCESS_TOKEN=$(json_field "$RES" "['data']['accessToken']") REFRESH_TOKEN=$(json_field "$RES" "['data']['refreshToken']") log_pass "Login" else log_fail "Login" "HTTP $CODE" fi # Refresh token if [[ -n "$REFRESH_TOKEN" ]]; then RES=$(api POST "/api/v1/auth/refresh" "{\"refreshToken\":\"$REFRESH_TOKEN\"}") CODE=$(http_code "$RES") if [[ "$CODE" == "200" || "$CODE" == "201" ]]; then ACCESS_TOKEN=$(json_field "$RES" "['data']['accessToken']") log_pass "Refresh token" else log_fail "Refresh token" "HTTP $CODE" fi fi # ==== 3. User Profile ==== echo -e "\n${YELLOW}--- User Profile ---${NC}" RES=$(api GET "/api/v1/users/me" "" "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Get profile" || log_fail "Get profile" "HTTP $CODE" RES=$(api PUT "/api/v1/users/me" '{"nickname":"E2E更新昵称","avatar":"https://example.com/avatar.png"}' "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Update profile" || log_fail "Update profile" "HTTP $CODE" # ==== 4. Wallet ==== echo -e "\n${YELLOW}--- Wallet ---${NC}" RES=$(api GET "/api/v1/wallet" "" "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Get wallet balance" || log_fail "Get wallet balance" "HTTP $CODE" RES=$(api POST "/api/v1/wallet/deposit" '{"amount":"10000","channel":"bank_transfer"}' "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" || "$CODE" == "201" ]] && log_pass "Deposit funds" || log_fail "Deposit funds" "HTTP $CODE" RES=$(api GET "/api/v1/wallet/transactions" "" "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Get transactions" || log_fail "Get transactions" "HTTP $CODE" # ==== 5. Coupons ==== echo -e "\n${YELLOW}--- Coupons ---${NC}" RES=$(api GET "/api/v1/coupons?page=1&limit=10" "" "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "List coupons" || log_fail "List coupons" "HTTP $CODE" RES=$(api GET "/api/v1/coupons?search=美食" "" "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Search coupons" || log_fail "Search coupons" "HTTP $CODE" # ==== 6. Messages ==== echo -e "\n${YELLOW}--- Messages ---${NC}" RES=$(api GET "/api/v1/messages" "" "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "List messages" || log_fail "List messages" "HTTP $CODE" RES=$(api GET "/api/v1/messages/unread-count" "" "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Unread count" || log_fail "Unread count" "HTTP $CODE" # ==== 7. Trading ==== echo -e "\n${YELLOW}--- Trading ---${NC}" # Place a buy order (needs a coupon ID from seed data) RES=$(api POST "/api/v1/trades/orders" '{"couponId":"00000000-0000-4000-a000-000000000001","side":"buy","type":"limit","price":"85.00","quantity":1}' "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" || "$CODE" == "201" ]] && log_pass "Place buy order" || log_fail "Place buy order" "HTTP $CODE" # ==== 8. AI Service ==== echo -e "\n${YELLOW}--- AI Service ---${NC}" RES=$(api POST "/api/v1/ai/chat" '{"message":"什么是券金融?","sessionId":"e2e-test"}' "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" || "$CODE" == "201" ]] && log_pass "AI chat" || log_fail "AI chat" "HTTP $CODE" RES=$(api GET "/api/v1/ai/health" "" "$ACCESS_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "AI health check" || log_fail "AI health check" "HTTP $CODE" # ==== 9. Admin Flow ==== echo -e "\n${YELLOW}--- Admin Flow ---${NC}" # Login as admin (from seed data) RES=$(api POST "/api/v1/auth/login" '{"phone":"13800000001","password":"Test123456!"}') CODE=$(http_code "$RES") if [[ "$CODE" == "200" || "$CODE" == "201" ]]; then ADMIN_TOKEN=$(json_field "$RES" "['data']['accessToken']") log_pass "Admin login" else log_fail "Admin login" "HTTP $CODE" fi if [[ -n "$ADMIN_TOKEN" ]]; then # Dashboard RES=$(api GET "/api/v1/admin/dashboard/stats" "" "$ADMIN_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Admin dashboard stats" || log_fail "Admin dashboard stats" "HTTP $CODE" # User management RES=$(api GET "/api/v1/admin/users?page=1&limit=10" "" "$ADMIN_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Admin list users" || log_fail "Admin list users" "HTTP $CODE" # Issuer management RES=$(api GET "/api/v1/admin/issuers" "" "$ADMIN_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Admin list issuers" || log_fail "Admin list issuers" "HTTP $CODE" # Finance RES=$(api GET "/api/v1/admin/finance/summary" "" "$ADMIN_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Admin finance summary" || log_fail "Admin finance summary" "HTTP $CODE" # Risk RES=$(api GET "/api/v1/admin/risk/dashboard" "" "$ADMIN_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Admin risk dashboard" || log_fail "Admin risk dashboard" "HTTP $CODE" # Compliance RES=$(api GET "/api/v1/admin/compliance/sar" "" "$ADMIN_TOKEN") CODE=$(http_code "$RES") [[ "$CODE" == "200" ]] && log_pass "Admin compliance SAR" || log_fail "Admin compliance SAR" "HTTP $CODE" fi # ==== Summary ==== echo -e "\n==========================================" echo -e " Results: ${GREEN}$PASS passed${NC}, ${RED}$FAIL failed${NC}, $TOTAL total" echo "==========================================" [[ $FAIL -eq 0 ]] && exit 0 || exit 1