| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- #!/usr/bin/env bash
- #
- # Teste de ponta a ponta dos webhooks de CRM.
- #
- # Para cada caso, calcula o HMAC-SHA256 do corpo CRU com o segredo da empresa,
- # envia no header X-Signature e confere o HTTP status retornado.
- #
- # Uso:
- # ./test_crm_endpoints.sh
- # BASE_URL=http://127.0.0.1:8080 COMPANY_ID=3 SECRET=xxxx ./test_crm_endpoints.sh
- #
- set -uo pipefail
- BASE_URL="${BASE_URL:-http://127.0.0.1:8080}"
- COMPANY_ID="${COMPANY_ID:-3}"
- SECRET="${SECRET:-50d5e7f5faadbdb7681edc0a63dcb7d6fce93e613d290794885d292cb10fcc5b}"
- URL="$BASE_URL/v1/webhooks/crm/$COMPANY_ID"
- # external_id único por execução para o teste de venda/idempotência ser determinístico.
- RUN_ID="TEST-$(date +%s)"
- PASS=0
- FAIL=0
- hmac() {
- # Assina o corpo CRU (sem newline) com o segredo, devolve o hex.
- printf '%s' "$1" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $NF}'
- }
- # run <descrição> <http_esperado> <corpo> [assinatura_forçada]
- run() {
- local desc="$1" expected="$2" body="$3" forced_sig="${4:-}"
- local sig
- if [[ -n "$forced_sig" ]]; then
- sig="$forced_sig"
- else
- sig="sha256=$(hmac "$body")"
- fi
- local resp http payload
- resp=$(curl -s -w $'\n%{http_code}' -X POST "$URL" \
- -H "Content-Type: application/json" \
- -H "X-Signature: $sig" \
- --data "$body")
- http=$(printf '%s' "$resp" | tail -n1)
- payload=$(printf '%s' "$resp" | sed '$d')
- if [[ "$http" == "$expected" ]]; then
- printf ' ✅ PASS [%s] %s\n' "$http" "$desc"
- PASS=$((PASS + 1))
- else
- printf ' ❌ FAIL [esperado %s, veio %s] %s\n' "$expected" "$http" "$desc"
- FAIL=$((FAIL + 1))
- fi
- printf ' → %s\n' "$payload"
- }
- echo "Alvo: $URL (company_id=$COMPANY_ID)"
- echo "------------------------------------------------------------"
- echo "[1] PRODUCT — cria/atualiza SKU"
- run "product novo" 200 \
- '{"type":"product","data":{"name":"Plano Pro CRM Test","value":199.90,"line":"Assinaturas","sold":0}}'
- echo "[2] PRODUCT — mesmo nome (atualiza, opcionais vazios permitidos)"
- run "product update com campos vazios" 200 \
- '{"type":"product","data":{"name":"Plano Pro CRM Test","value":249.90,"line":""}}'
- echo "[3] CLIENT — cria/atualiza cliente"
- run "client" 200 \
- '{"type":"client","data":{"phone":"+5511999990001","name":"Cliente Teste","email":"teste@crm.com","segment":"Premium"}}'
- echo "[4] SALE — registra venda (vincula ao produto, incrementa sku_sold)"
- run "sale nova" 200 \
- "{\"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\"}}"
- echo "[5] SALE — reenvio do mesmo external_id (idempotência: não duplica)"
- run "sale duplicada" 200 \
- "{\"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}}"
- echo "------------------------------------------------------------"
- echo "Casos de erro (devem ser rejeitados):"
- echo "[6] Assinatura inválida → 401"
- run "assinatura errada" 401 \
- '{"type":"product","data":{"name":"X","value":1}}' \
- "sha256=deadbeef"
- echo "[7] Campo essencial faltando (sale sem amount) → 400"
- run "sale sem amount" 400 \
- "{\"type\":\"sale\",\"data\":{\"external_id\":\"$RUN_ID-x\",\"occurred_at\":\"2026-06-11T14:30:00\"}}"
- echo "[8] type desconhecido → 400"
- run "type invalido" 400 \
- '{"type":"foobar","data":{}}'
- echo "[9] Empresa inexistente → 404"
- COMPANY_ID_BKP="$COMPANY_ID"
- URL="$BASE_URL/v1/webhooks/crm/999999"
- run "company inexistente" 404 \
- '{"type":"product","data":{"name":"X","value":1}}'
- URL="$BASE_URL/v1/webhooks/crm/$COMPANY_ID_BKP"
- echo "------------------------------------------------------------"
- printf 'RESULTADO: %d passou, %d falhou\n' "$PASS" "$FAIL"
- [[ "$FAIL" -eq 0 ]]
|