#!/usr/bin/env bash # ----------------------------------------------------------------------------- # tests/smoke.sh # # Appelle les endpoints clés de l'API et vérifie les codes HTTP attendus. # Sortie non-zéro si au moins un appel échoue. # # Usage : # ADMIN_TOKEN=xxxxx [INFOLAB_URL=http://localhost:8003] ./tests/smoke.sh # # Idempotent : un cleanup best-effort en début de script supprime les ressources # de test (projet "nos-ecoles" + membre "collectif-des-ecoles-de-marseille"). # ----------------------------------------------------------------------------- set -uo pipefail URL="${INFOLAB_URL:-http://localhost:8003}" TOKEN="${ADMIN_TOKEN:-}" if [[ -z "$TOKEN" ]]; then echo "ERR: variable d'env ADMIN_TOKEN requise" >&2 exit 2 fi PASS=0 FAIL=0 BODY="$(mktemp -t smoke.XXXXXX 2>/dev/null || mktemp)" trap 'rm -f "$BODY"' EXIT # Appelle un endpoint et vérifie le code HTTP. Logue un extrait du body. # Args : label expected_code method path [body_json] call() { local label="$1" expected="$2" method="$3" path="$4" body="${5:-}" local -a headers=(-H 'Accept: application/json') if [[ -n "$body" ]]; then headers+=(-H 'Content-Type: application/json') fi if [[ "$method" != "GET" ]]; then headers+=(-H "Authorization: Bearer $TOKEN") fi local code if [[ -n "$body" ]]; then # Important : on pipe le body via stdin avec --data-binary @-, pas via argv. # Sur Windows/Git Bash, passer un body UTF-8 en argument à curl convertit # les bytes multi-octets en cp1252 et casse le JSON. stdin = binary safe. code=$(printf '%s' "$body" \ | curl -sS -o "$BODY" -w '%{http_code}' -X "$method" "${headers[@]}" --data-binary @- "$URL$path") else code=$(curl -sS -o "$BODY" -w '%{http_code}' -X "$method" "${headers[@]}" "$URL$path") fi local snip snip=$(head -c 220 "$BODY" 2>/dev/null || echo '') if [[ "$code" == "$expected" ]]; then printf ' OK [%s] %-6s %s — %s\n' "$code" "$method" "$path" "$label" printf ' > %s\n' "$snip" PASS=$((PASS+1)) else printf ' FAIL [%s, attendu %s] %-6s %s — %s\n' "$code" "$expected" "$method" "$path" "$label" printf ' > %s\n' "$snip" FAIL=$((FAIL+1)) fi } # Extrait le 1er "id":N du body courant. extract_id() { sed -n 's/.*"id":[[:space:]]*\([0-9][0-9]*\).*/\1/p' "$BODY" | head -1 } # Compte les occurrences de "id":N dans le body (approximation suffisante pour les listes). count_ids() { grep -oE '"id":[[:space:]]*[0-9]+' "$BODY" | wc -l | tr -d ' ' } echo "== Smoke test infolab @ $URL ==" # Cleanup best-effort : autorise les ré-exécutions. curl -sS -o /dev/null -X DELETE -H "Authorization: Bearer $TOKEN" "$URL/api/projects/nos-ecoles" >/dev/null 2>&1 || true curl -sS -o /dev/null -X DELETE -H "Authorization: Bearer $TOKEN" "$URL/api/members/collectif-des-ecoles-de-marseille" >/dev/null 2>&1 || true # 1) Sanity call "Health" 200 GET /api/health # 2) Catégories seedées call "Categories list" 200 GET /api/categories count=$(count_ids) if [[ "$count" == "6" ]]; then echo " OK categories.length = 6" PASS=$((PASS+1)) else echo " FAIL categories.length = $count (attendu 6)" FAIL=$((FAIL+1)) fi # Récupère l'id de "education-ecoles" pour ne pas dépendre de l'auto-increment. curl -sS -o "$BODY" "$URL/api/categories/education-ecoles" >/dev/null CAT_ID=$(extract_id) CAT_ID="${CAT_ID:-6}" # 3) Création du membre MEMBER_BODY=$(cat <<'JSON' {"display_name":"Collectif des écoles de Marseille","kind":"collective","bio":"Réseau citoyen pour les écoles publiques marseillaises."} JSON ) call "Create member" 201 POST /api/members "$MEMBER_BODY" # 4) Création du projet (ré-utilise CAT_ID dynamique) PROJECT_BODY=$(cat <