|
|
@@ -0,0 +1,247 @@
|
|
|
+#!/usr/bin/env bash
|
|
|
+#
|
|
|
+# test_endpoints.sh — Testa todos os endpoints da API nettown_backend.
|
|
|
+#
|
|
|
+# Faz login (POST /v1/login), obtém o JWT e reutiliza nas rotas protegidas.
|
|
|
+#
|
|
|
+# Uso:
|
|
|
+# ./test_endpoints.sh
|
|
|
+# BASE_URL=http://localhost:8080 EMAIL=admin@empresa.com PASSWORD=12345678 ./test_endpoints.sh
|
|
|
+# RUN_WRITE=1 ./test_endpoints.sh # inclui endpoints que ESCREVEM no banco
|
|
|
+#
|
|
|
+# Variáveis de ambiente:
|
|
|
+# BASE_URL Host da API (default: http://localhost:8080)
|
|
|
+# API_PREFIX Prefixo das rotas (default: /v1)
|
|
|
+# EMAIL E-mail de login (default: admin@empresa.com)
|
|
|
+# PASSWORD Senha de login (default: 12345678)
|
|
|
+# RUN_WRITE "1" para rodar também os endpoints de escrita (register,
|
|
|
+# change-password, agents, sla/configs). Default: 0 (somente leitura).
|
|
|
+#
|
|
|
+# Saída: 0 se nenhum teste falhou, 1 caso contrário.
|
|
|
+
|
|
|
+set -uo pipefail
|
|
|
+
|
|
|
+BASE_URL="${BASE_URL:-http://localhost:8080}"
|
|
|
+API_PREFIX="${API_PREFIX:-/v1}"
|
|
|
+EMAIL="${EMAIL:-admin@empresa.com}"
|
|
|
+PASSWORD="${PASSWORD:-12345678}"
|
|
|
+RUN_WRITE="${RUN_WRITE:-0}"
|
|
|
+
|
|
|
+BASE="${BASE_URL}${API_PREFIX}"
|
|
|
+TOKEN=""
|
|
|
+
|
|
|
+# Cores (desativadas se a saída não for um terminal).
|
|
|
+if [[ -t 1 ]]; then
|
|
|
+ C_GREEN=$'\033[32m'; C_RED=$'\033[31m'; C_YELLOW=$'\033[33m'
|
|
|
+ C_BLUE=$'\033[34m'; C_DIM=$'\033[2m'; C_RESET=$'\033[0m'
|
|
|
+else
|
|
|
+ C_GREEN=""; C_RED=""; C_YELLOW=""; C_BLUE=""; C_DIM=""; C_RESET=""
|
|
|
+fi
|
|
|
+
|
|
|
+PASS=0; FAIL=0; SKIP=0
|
|
|
+
|
|
|
+have_jq() { command -v jq >/dev/null 2>&1; }
|
|
|
+
|
|
|
+# json_get <json> <jq_path> — extrai um valor do JSON (usa jq; senão, grep básico).
|
|
|
+json_get() {
|
|
|
+ local json="$1" path="$2"
|
|
|
+ if have_jq; then
|
|
|
+ printf '%s' "$json" | jq -r "$path // empty" 2>/dev/null
|
|
|
+ return
|
|
|
+ fi
|
|
|
+ # Fallback simples: pega o último campo com o nome final do path (ex.: .data.token -> token).
|
|
|
+ local key="${path##*.}"
|
|
|
+ printf '%s' "$json" | grep -o "\"${key}\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" \
|
|
|
+ | head -n1 | sed -E "s/.*:[[:space:]]*\"([^\"]*)\"/\1/"
|
|
|
+}
|
|
|
+
|
|
|
+# Imprime um trecho curto do corpo da resposta.
|
|
|
+preview_body() {
|
|
|
+ local body="$1"
|
|
|
+ if have_jq; then
|
|
|
+ printf '%s' "$body" | jq -c '{status, code, message}' 2>/dev/null || printf '%s' "$body" | head -c 200
|
|
|
+ else
|
|
|
+ printf '%s' "$body" | head -c 200
|
|
|
+ fi
|
|
|
+}
|
|
|
+
|
|
|
+LAST_BODY=""
|
|
|
+LAST_CODE=""
|
|
|
+
|
|
|
+# call <method> <path> [json_data] — executa a requisição e popula LAST_BODY/LAST_CODE.
|
|
|
+call() {
|
|
|
+ local method="$1" path="$2" data="${3:-}"
|
|
|
+ local args=(-sS -X "$method" -H "Accept: application/json" -w $'\n%{http_code}' --max-time 30)
|
|
|
+ if [[ -n "$TOKEN" ]]; then
|
|
|
+ args+=(-H "Authorization: Bearer ${TOKEN}")
|
|
|
+ fi
|
|
|
+ if [[ -n "$data" ]]; then
|
|
|
+ args+=(-H "Content-Type: application/json" -d "$data")
|
|
|
+ fi
|
|
|
+
|
|
|
+ local resp
|
|
|
+ resp=$(curl "${args[@]}" "${BASE}${path}" 2>/dev/null)
|
|
|
+ LAST_CODE=$(printf '%s' "$resp" | tail -n1)
|
|
|
+ LAST_BODY=$(printf '%s' "$resp" | sed '$d')
|
|
|
+}
|
|
|
+
|
|
|
+# check <label> <method> <path> [json_data] — chama e avalia (2xx = passou).
|
|
|
+check() {
|
|
|
+ local label="$1" method="$2" path="$3" data="${4:-}"
|
|
|
+ call "$method" "$path" "$data"
|
|
|
+
|
|
|
+ local mark color
|
|
|
+ if [[ "$LAST_CODE" =~ ^2 ]]; then
|
|
|
+ mark="PASS"; color="$C_GREEN"; PASS=$((PASS + 1))
|
|
|
+ elif [[ "$LAST_CODE" =~ ^[45] ]]; then
|
|
|
+ mark="FAIL"; color="$C_RED"; FAIL=$((FAIL + 1))
|
|
|
+ else
|
|
|
+ mark="FAIL"; color="$C_RED"; FAIL=$((FAIL + 1))
|
|
|
+ [[ -z "$LAST_CODE" ]] && LAST_CODE="ERR"
|
|
|
+ fi
|
|
|
+
|
|
|
+ printf ' %s%-4s%s %-7s %-34s %shttp %s%s\n' \
|
|
|
+ "$color" "$mark" "$C_RESET" "$method" "$path" "$C_DIM" "$LAST_CODE" "$C_RESET"
|
|
|
+ printf ' %s%s%s\n' "$C_DIM" "$(preview_body "$LAST_BODY")" "$C_RESET"
|
|
|
+}
|
|
|
+
|
|
|
+skip() {
|
|
|
+ local path="$1" reason="$2"
|
|
|
+ SKIP=$((SKIP + 1))
|
|
|
+ printf ' %sSKIP%s %-7s %-34s %s%s%s\n' "$C_YELLOW" "$C_RESET" "-" "$path" "$C_DIM" "$reason" "$C_RESET"
|
|
|
+}
|
|
|
+
|
|
|
+section() { printf '\n%s== %s ==%s\n' "$C_BLUE" "$1" "$C_RESET"; }
|
|
|
+
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+# 0. Sanity check
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+printf '%sAlvo:%s %s %sleitura+escrita:%s %s\n' \
|
|
|
+ "$C_DIM" "$C_RESET" "$BASE" "$C_DIM" "$C_RESET" \
|
|
|
+ "$([[ "$RUN_WRITE" == "1" ]] && echo sim || echo 'somente leitura')"
|
|
|
+have_jq || printf '%s(jq não encontrado — usando parser básico; instale jq para melhor saída)%s\n' "$C_YELLOW" "$C_RESET"
|
|
|
+
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+# 1. Login (obrigatório — sem token não dá para testar o resto)
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+section "Autenticação"
|
|
|
+LOGIN_PAYLOAD=$(printf '{"email":"%s","password":"%s"}' "$EMAIL" "$PASSWORD")
|
|
|
+check "login" POST "/login" "$LOGIN_PAYLOAD"
|
|
|
+
|
|
|
+TOKEN=$(json_get "$LAST_BODY" '.data.token')
|
|
|
+if [[ -z "$TOKEN" ]]; then
|
|
|
+ printf '\n%sNão foi possível obter o JWT do login. Verifique BASE_URL/EMAIL/PASSWORD.%s\n' "$C_RED" "$C_RESET"
|
|
|
+ printf 'Resposta: %s\n' "$LAST_BODY"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+printf ' %stoken obtido (%s...)%s\n' "$C_DIM" "${TOKEN:0:24}" "$C_RESET"
|
|
|
+
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+# 2. Perfil
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+section "Perfil"
|
|
|
+check "me" GET "/me"
|
|
|
+
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+# 3. Dashboards (somente leitura)
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+section "Dashboards (GET)"
|
|
|
+check "dashboard" GET "/dashboard/overview"
|
|
|
+check "analytics" GET "/analytics/sentiment/dashboard"
|
|
|
+check "personas" GET "/personas/overview"
|
|
|
+check "evolution" GET "/evolution/overview"
|
|
|
+check "executive" GET "/executive/dashboard"
|
|
|
+
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+# 4. Interações
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+section "Interações (GET)"
|
|
|
+check "interactions" GET "/interactions?page=1&per_page=5"
|
|
|
+
|
|
|
+# Tenta extrair um conversation_id da listagem para testar os detalhes.
|
|
|
+CONV_ID=""
|
|
|
+if have_jq; then
|
|
|
+ CONV_ID=$(printf '%s' "$LAST_BODY" | jq -r '.data.items[0].conversationId // empty' 2>/dev/null)
|
|
|
+else
|
|
|
+ CONV_ID=$(printf '%s' "$LAST_BODY" | grep -o '"conversationId":[0-9]*' | head -n1 | grep -o '[0-9]*')
|
|
|
+fi
|
|
|
+
|
|
|
+if [[ -n "$CONV_ID" ]]; then
|
|
|
+ check "interaction-details" GET "/interactions/details?conversation_id=${CONV_ID}"
|
|
|
+else
|
|
|
+ skip "/interactions/details" "nenhum conversation_id disponível na listagem"
|
|
|
+fi
|
|
|
+
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+# 5. Agentes (GET)
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+section "Agentes (GET)"
|
|
|
+check "agents" GET "/agents"
|
|
|
+
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+# 6. SLA (GET)
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+section "SLA (GET)"
|
|
|
+check "sla-configs" GET "/sla/configs"
|
|
|
+check "sla-live-status" GET "/sla/live-status"
|
|
|
+
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+# 7. Endpoints de ESCRITA (apenas com RUN_WRITE=1)
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+section "Escrita (POST)"
|
|
|
+if [[ "$RUN_WRITE" != "1" ]]; then
|
|
|
+ skip "/register" "RUN_WRITE!=1 (cria usuário)"
|
|
|
+ skip "/agents" "RUN_WRITE!=1 (cria/edita agente)"
|
|
|
+ skip "/agents/status" "RUN_WRITE!=1 (altera status)"
|
|
|
+ skip "/agents/escalation" "RUN_WRITE!=1 (altera escalonamento)"
|
|
|
+ skip "/sla/configs" "RUN_WRITE!=1 (cria/edita SLA)"
|
|
|
+ skip "/me/change-password" "RUN_WRITE!=1 (altera senha; revertido se rodado)"
|
|
|
+else
|
|
|
+ TS=$(date +%s)
|
|
|
+
|
|
|
+ # 7.1 Register — cria usuário com e-mail único para não colidir.
|
|
|
+ REG_PAYLOAD=$(printf '{"name":"Teste %s","phone":"5511999990000","email":"teste+%s@example.com","role":"agent","password":"senha12345"}' "$TS" "$TS")
|
|
|
+ check "register" POST "/register" "$REG_PAYLOAD"
|
|
|
+
|
|
|
+ # 7.2 Agents — cria um agente e captura o id para os toggles.
|
|
|
+ AGENT_PAYLOAD=$(printf '{"name":"Agente Teste %s","email":"agent+%s@example.com","department":"SAC","channels":["whatsapp"],"status":"Ativo","availableForEscalation":true}' "$TS" "$TS")
|
|
|
+ check "agents-save" POST "/agents" "$AGENT_PAYLOAD"
|
|
|
+
|
|
|
+ AGENT_ID=""
|
|
|
+ if have_jq; then
|
|
|
+ AGENT_ID=$(printf '%s' "$LAST_BODY" | jq -r '.data.id // empty' 2>/dev/null)
|
|
|
+ else
|
|
|
+ AGENT_ID=$(printf '%s' "$LAST_BODY" | grep -o '"id":[0-9]*' | head -n1 | grep -o '[0-9]*')
|
|
|
+ fi
|
|
|
+
|
|
|
+ if [[ -n "$AGENT_ID" ]]; then
|
|
|
+ check "agents-status" POST "/agents/status" "$(printf '{"id":%s}' "$AGENT_ID")"
|
|
|
+ check "agents-escalation" POST "/agents/escalation" "$(printf '{"id":%s}' "$AGENT_ID")"
|
|
|
+ else
|
|
|
+ skip "/agents/status" "agente de teste não retornou id"
|
|
|
+ skip "/agents/escalation" "agente de teste não retornou id"
|
|
|
+ fi
|
|
|
+
|
|
|
+ # 7.3 SLA config — cria/atualiza um departamento de teste.
|
|
|
+ SLA_PAYLOAD=$(printf '{"name":"TESTE %s","firstResponseH":1,"firstResponseM":30,"resolutionH":24,"alertPct":80}' "$TS")
|
|
|
+ check "sla-save" POST "/sla/configs" "$SLA_PAYLOAD"
|
|
|
+
|
|
|
+ # 7.4 Change password — troca e reverte para não travar o login.
|
|
|
+ NEW_PW="${PASSWORD}_tmp1"
|
|
|
+ check "change-password" POST "/me/change-password" \
|
|
|
+ "$(printf '{"currentPassword":"%s","newPassword":"%s","confirmPassword":"%s"}' "$PASSWORD" "$NEW_PW" "$NEW_PW")"
|
|
|
+ if [[ "$LAST_CODE" =~ ^2 ]]; then
|
|
|
+ # Reverte para a senha original.
|
|
|
+ check "change-password (revert)" POST "/me/change-password" \
|
|
|
+ "$(printf '{"currentPassword":"%s","newPassword":"%s","confirmPassword":"%s"}' "$NEW_PW" "$PASSWORD" "$PASSWORD")"
|
|
|
+ fi
|
|
|
+fi
|
|
|
+
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+# Resumo
|
|
|
+# ----------------------------------------------------------------------------
|
|
|
+printf '\n%s== Resumo ==%s\n' "$C_BLUE" "$C_RESET"
|
|
|
+printf ' %spassou:%s %d %sfalhou:%s %d %spulado:%s %d\n' \
|
|
|
+ "$C_GREEN" "$C_RESET" "$PASS" "$C_RED" "$C_RESET" "$FAIL" "$C_YELLOW" "$C_RESET" "$SKIP"
|
|
|
+
|
|
|
+[[ "$FAIL" -eq 0 ]] && exit 0 || exit 1
|