test-promotion-flow.sh 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #!/usr/bin/env bash
  2. #
  3. # test-promotion-flow.sh — End-to-end integration test for promotion flows
  4. #
  5. # Tests: register → onboarding → growth-tasks → share → invite →
  6. # milestone → leaderboard → coupon
  7. #
  8. # Usage:
  9. # BASE_URL=http://localhost:9082 ./test-promotion-flow.sh
  10. #
  11. set -euo pipefail
  12. BASE_URL="${BASE_URL:-http://localhost:9082}"
  13. PASS=0
  14. FAIL=0
  15. # ── helpers ──────────────────────────────────────────────────────────
  16. header() { echo ""; echo "===== $1 ====="; }
  17. api() {
  18. local ep="$1" tok="$2" body="${3:-{}}"
  19. curl -s -X POST "${BASE_URL}${ep}" \
  20. -H "Content-Type: application/json" \
  21. $( [ -n "$tok" ] && echo "-H Authorization: Bearer ${tok}" ) \
  22. -d "$body"
  23. }
  24. json_get() {
  25. python3 -c "
  26. import sys, json
  27. d = json.load(sys.stdin)
  28. parts = '$2'.split('.')
  29. v = d
  30. for p in parts:
  31. if isinstance(v, dict):
  32. v = v.get(p, '')
  33. elif isinstance(v, list):
  34. try:
  35. idx = int(p)
  36. v = v[idx] if idx < len(v) else ''
  37. except ValueError:
  38. v = ''
  39. else:
  40. v = ''
  41. if v == '':
  42. break
  43. print(v if v != '' else '')
  44. " <<< "$1" 2>/dev/null || echo ""
  45. }
  46. passert() {
  47. local tn="$1" json="$2"
  48. if echo "$json" | python3 -c "
  49. import sys,json
  50. d=json.load(sys.stdin)
  51. exit(0 if d.get('code')==200 else 1)
  52. " 2>/dev/null; then
  53. echo " PASS: $tn"
  54. ((PASS++))
  55. else
  56. local msg
  57. msg=$(echo "$json" | python3 -c "
  58. import sys,json
  59. d=json.load(sys.stdin)
  60. print(d.get('message','no message'))
  61. " 2>/dev/null)
  62. echo " FAIL: $tn — $msg"
  63. ((FAIL++))
  64. fi
  65. }
  66. header "0. Health Check"
  67. R=$(api "/api/auth/check-phone" "" '{"phone":"13800000001"}')
  68. passert "Server reachable" "$R"
  69. header "1. Register User1 (parent)"
  70. PHONE1="138$(printf '%08d' $((RANDOM%100000000)))"
  71. R=$(api "/api/auth/direct-register" "" \
  72. "{\"phone\":\"$PHONE1\",\"nickname\":\"TestParent\",\"role\":\"parent\"}")
  73. passert "Register user1" "$R"
  74. TOKEN1=$(json_get "$R" "data.token")
  75. echo " user1: $PHONE1 id=$(json_get "$R" "data.userId")"
  76. # ── 2. Onboarding progress ───────────────────────────────────────────
  77. header "2. Onboarding Progress"
  78. R=$(api "/api/onboarding/progress" "$TOKEN1")
  79. passert "Onboarding progress" "$R"
  80. header "3. Claim REGISTER Reward"
  81. R=$(api "/api/onboarding/claim" "$TOKEN1" '{"taskType":"REGISTER"}')
  82. passert "Claim REGISTER reward" "$R"
  83. header "4. List Daily Growth Tasks"
  84. R=$(api "/api/growth-task/list" "$TOKEN1" '{"type":"DAILY"}')
  85. passert "List daily growth tasks" "$R"
  86. header "5. Get Referral Code"
  87. R=$(api "/api/invite/code" "$TOKEN1")
  88. passert "Get referral code" "$R"
  89. CODE=$(json_get "$R" "data")
  90. echo " referral code: $CODE"
  91. header "6. Register User2 + Bind Referral"
  92. PHONE2="138$(printf '%08d' $((RANDOM%100000000)))"
  93. R=$(api "/api/auth/direct-register" "" \
  94. "{\"phone\":\"$PHONE2\",\"nickname\":\"TestReferral\",\"role\":\"parent\"}")
  95. passert "Register user2" "$R"
  96. TOKEN2=$(json_get "$R" "data.token")
  97. echo " user2: $PHONE2 id=$(json_get "$R" "data.userId")"
  98. R=$(api "/api/invite/bind" "$TOKEN2" "{\"referralCode\":\"$CODE\"}")
  99. passert "Bind referral" "$R"
  100. # ── 7. Invite milestones ─────────────────────────────────────────────
  101. header "7. Invite Milestones"
  102. R=$(api "/api/invite/milestone/list" "$TOKEN1")
  103. passert "List milestones" "$R"
  104. # ── 8. Leaderboard ───────────────────────────────────────────────────
  105. header "8. Leaderboard"
  106. R=$(api "/api/leaderboard/top" "")
  107. passert "Leaderboard top 20" "$R"
  108. R=$(api "/api/leaderboard/my-rank" "$TOKEN1")
  109. passert "My rank" "$R"
  110. # ── 9. Coupon flow ───────────────────────────────────────────────────
  111. header "9. Coupon Flow"
  112. R=$(api "/api/coupon/list" "$TOKEN1")
  113. passert "List available coupons" "$R"
  114. CID=$(json_get "$R" "data.0.id")
  115. if [ -n "$CID" ]; then
  116. R=$(api "/api/coupon/claim" "$TOKEN1" "{\"couponId\":$CID}")
  117. passert "Claim coupon #$CID" "$R"
  118. UID=$(json_get "$R" "data")
  119. echo " userCouponId: $UID"
  120. if [[ "$UID" =~ ^[0-9]+$ ]]; then
  121. R=$(api "/api/coupon/apply" "$TOKEN1" \
  122. "{\"userCouponId\":$UID,\"orderType\":\"PRODUCT\",\"orderAmount\":10000}")
  123. passert "Apply coupon" "$R"
  124. fi
  125. else
  126. echo " INFO: no coupons available — claim skipped (expected on fresh system)"
  127. echo " PASS: coupon list returned (no coupons to claim)"
  128. ((PASS++))
  129. fi
  130. # ── Summary ──────────────────────────────────────────────────────────
  131. header "Results"
  132. TOTAL=$((PASS + FAIL))
  133. echo " Total: $TOTAL | Passed: $PASS | Failed: $FAIL"
  134. [ "$FAIL" -eq 0 ] && echo " ✅ ALL TESTS PASSED" || echo " ❌ $FAIL TEST(S) FAILED"
  135. exit $(( FAIL > 0 ))