test_crm_endpoints.sh 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #!/usr/bin/env bash
  2. #
  3. # Teste de ponta a ponta dos webhooks de CRM.
  4. #
  5. # Para cada caso, calcula o HMAC-SHA256 do corpo CRU com o segredo da empresa,
  6. # envia no header X-Signature e confere o HTTP status retornado.
  7. #
  8. # Uso:
  9. # ./test_crm_endpoints.sh
  10. # BASE_URL=http://127.0.0.1:8080 COMPANY_ID=3 SECRET=xxxx ./test_crm_endpoints.sh
  11. #
  12. set -uo pipefail
  13. BASE_URL="${BASE_URL:-http://127.0.0.1:8080}"
  14. COMPANY_ID="${COMPANY_ID:-3}"
  15. SECRET="${SECRET:-50d5e7f5faadbdb7681edc0a63dcb7d6fce93e613d290794885d292cb10fcc5b}"
  16. URL="$BASE_URL/v1/webhooks/crm/$COMPANY_ID"
  17. # external_id único por execução para o teste de venda/idempotência ser determinístico.
  18. RUN_ID="TEST-$(date +%s)"
  19. PASS=0
  20. FAIL=0
  21. hmac() {
  22. # Assina o corpo CRU (sem newline) com o segredo, devolve o hex.
  23. printf '%s' "$1" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $NF}'
  24. }
  25. # run <descrição> <http_esperado> <corpo> [assinatura_forçada]
  26. run() {
  27. local desc="$1" expected="$2" body="$3" forced_sig="${4:-}"
  28. local sig
  29. if [[ -n "$forced_sig" ]]; then
  30. sig="$forced_sig"
  31. else
  32. sig="sha256=$(hmac "$body")"
  33. fi
  34. local resp http payload
  35. resp=$(curl -s -w $'\n%{http_code}' -X POST "$URL" \
  36. -H "Content-Type: application/json" \
  37. -H "X-Signature: $sig" \
  38. --data "$body")
  39. http=$(printf '%s' "$resp" | tail -n1)
  40. payload=$(printf '%s' "$resp" | sed '$d')
  41. if [[ "$http" == "$expected" ]]; then
  42. printf ' ✅ PASS [%s] %s\n' "$http" "$desc"
  43. PASS=$((PASS + 1))
  44. else
  45. printf ' ❌ FAIL [esperado %s, veio %s] %s\n' "$expected" "$http" "$desc"
  46. FAIL=$((FAIL + 1))
  47. fi
  48. printf ' → %s\n' "$payload"
  49. }
  50. echo "Alvo: $URL (company_id=$COMPANY_ID)"
  51. echo "------------------------------------------------------------"
  52. echo "[1] PRODUCT — cria/atualiza SKU"
  53. run "product novo" 200 \
  54. '{"type":"product","data":{"name":"Plano Pro CRM Test","value":199.90,"line":"Assinaturas","sold":0}}'
  55. echo "[2] PRODUCT — mesmo nome (atualiza, opcionais vazios permitidos)"
  56. run "product update com campos vazios" 200 \
  57. '{"type":"product","data":{"name":"Plano Pro CRM Test","value":249.90,"line":""}}'
  58. echo "[3] CLIENT — cria/atualiza cliente"
  59. run "client" 200 \
  60. '{"type":"client","data":{"phone":"+5511999990001","name":"Cliente Teste","email":"teste@crm.com","segment":"Premium"}}'
  61. echo "[4] SALE — registra venda (vincula ao produto, incrementa sku_sold)"
  62. run "sale nova" 200 \
  63. "{\"type\":\"sale\",\"data\":{\"external_id\":\"$RUN_ID\",\"amount\":199.90,\"occurred_at\":\"2026-06-11T14:30:00\",\"product_name\":\"Plano Pro CRM Test\",\"quantity\":2,\"client_phone\":\"+5511999990001\"}}"
  64. echo "[5] SALE — reenvio do mesmo external_id (idempotência: não duplica)"
  65. run "sale duplicada" 200 \
  66. "{\"type\":\"sale\",\"data\":{\"external_id\":\"$RUN_ID\",\"amount\":199.90,\"occurred_at\":\"2026-06-11T14:30:00\",\"product_name\":\"Plano Pro CRM Test\",\"quantity\":2}}"
  67. echo "------------------------------------------------------------"
  68. echo "Casos de erro (devem ser rejeitados):"
  69. echo "[6] Assinatura inválida → 401"
  70. run "assinatura errada" 401 \
  71. '{"type":"product","data":{"name":"X","value":1}}' \
  72. "sha256=deadbeef"
  73. echo "[7] Campo essencial faltando (sale sem amount) → 400"
  74. run "sale sem amount" 400 \
  75. "{\"type\":\"sale\",\"data\":{\"external_id\":\"$RUN_ID-x\",\"occurred_at\":\"2026-06-11T14:30:00\"}}"
  76. echo "[8] type desconhecido → 400"
  77. run "type invalido" 400 \
  78. '{"type":"foobar","data":{}}'
  79. echo "[9] Empresa inexistente → 404"
  80. COMPANY_ID_BKP="$COMPANY_ID"
  81. URL="$BASE_URL/v1/webhooks/crm/999999"
  82. run "company inexistente" 404 \
  83. '{"type":"product","data":{"name":"X","value":1}}'
  84. URL="$BASE_URL/v1/webhooks/crm/$COMPANY_ID_BKP"
  85. echo "------------------------------------------------------------"
  86. printf 'RESULTADO: %d passou, %d falhou\n' "$PASS" "$FAIL"
  87. [[ "$FAIL" -eq 0 ]]