mirror of
https://github.com/IliesAllali/parenthese.git
synced 2026-11-06 23:32:08 +00:00
Utilisateurs - Suppression de compte depuis l'écran « Votre compte », confirmée par mot de passe : arbres possédés et médias effacés, email retiré des contributions, sessions fermées partout. - Suppression d'arbre définitive, en base et sur le disque. - Ajout d'un frère ou d'une sœur relié aux parents existants ; relations parent et enfant corrigées en mode démo. - Liste d'attente retirée (route, envoi d'emails, dépendance Resend). Projet ouvert - CI : front, landing, backend avec vérification des migrations, test Docker de bout en bout. - Déploiement lancé seulement après une CI réussie sur main. - Image API : CLI Prisma installée à part pour que les migrations tournent au démarrage. - SECURITY.md, CONTRIBUTING.md, modèles d'issue et de pull request. - Migration renommée avec un nom descriptif, contenu identique. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
135 lines
4.7 KiB
Bash
135 lines
4.7 KiB
Bash
#!/usr/bin/env bash
|
|
# Test de fumée d'une instance Parenthèse, par le port web uniquement, comme un vrai utilisateur.
|
|
#
|
|
# bash tools/docker-smoke.sh instance sur http://localhost
|
|
# bash tools/docker-smoke.sh http://localhost:8080 si WEB_PORT=8080
|
|
#
|
|
# Vérifie : page d'accueil, /health (direct et via /api), création de compte, connexion,
|
|
# création d'une galaxie, lecture de son graphe, puis suppression de la galaxie.
|
|
# Le compte de test (smoke-...@example.com) reste en base : l'API n'a pas de route de suppression de compte.
|
|
# Nécessite curl et jq. Code de sortie 0 si tout passe, 1 sinon.
|
|
set -euo pipefail
|
|
|
|
BASE_URL="${1:-${BASE_URL:-http://localhost}}"
|
|
BASE_URL="${BASE_URL%/}"
|
|
WAIT_SECONDS="${SMOKE_WAIT_SECONDS:-90}"
|
|
|
|
for cmd in curl jq; do
|
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
|
echo "Commande manquante : $cmd" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
WORK_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$WORK_DIR"' EXIT
|
|
BODY="$WORK_DIR/body"
|
|
|
|
fail() {
|
|
echo "ÉCHEC : $*" >&2
|
|
if [ -s "$BODY" ]; then
|
|
echo "Réponse reçue :" >&2
|
|
head -c 2000 "$BODY" >&2
|
|
echo >&2
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
ok() {
|
|
echo "ok $*"
|
|
}
|
|
|
|
# request MÉTHODE CHEMIN [CORPS_JSON] [JETON] : écrit le corps dans $BODY et affiche le code HTTP.
|
|
request() {
|
|
local method="$1" path="$2" body="${3:-}" token="${4:-}"
|
|
local args=(-sS -o "$BODY" -w '%{http_code}' -X "$method" --max-time 30)
|
|
if [ -n "$body" ]; then
|
|
args+=(-H 'Content-Type: application/json' --data "$body")
|
|
fi
|
|
if [ -n "$token" ]; then
|
|
args+=(-H "Authorization: Bearer $token")
|
|
fi
|
|
curl "${args[@]}" "$BASE_URL$path"
|
|
}
|
|
|
|
expect_status() {
|
|
local got="$1" expected="$2" label="$3"
|
|
[ "$got" = "$expected" ] || fail "$label : HTTP $got, attendu $expected"
|
|
}
|
|
|
|
echo "Instance testée : $BASE_URL"
|
|
|
|
# 0. Attente de l'API derrière nginx
|
|
deadline=$((SECONDS + WAIT_SECONDS))
|
|
until curl -fsS --max-time 5 -o /dev/null "$BASE_URL/health" 2>/dev/null; do
|
|
if [ "$SECONDS" -ge "$deadline" ]; then
|
|
: > "$BODY"
|
|
fail "$BASE_URL/health ne répond pas après ${WAIT_SECONDS} s"
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
# 1. Page d'accueil servie par nginx
|
|
status="$(curl -sS -o "$BODY" -w '%{http_code} %{content_type}' --max-time 30 "$BASE_URL/")" \
|
|
|| fail "page d'accueil injoignable"
|
|
code="${status%% *}"
|
|
content_type="${status#* }"
|
|
expect_status "$code" 200 "GET /"
|
|
case "$content_type" in
|
|
text/html*) ;;
|
|
*) fail "GET / : type $content_type, attendu text/html" ;;
|
|
esac
|
|
grep -q 'id="root"' "$BODY" || fail "GET / : la page ne contient pas l'application"
|
|
ok "GET / (HTML)"
|
|
|
|
# 2. Santé de l'API, relayée telle quelle et via le préfixe /api retiré par nginx
|
|
for path in /health /api/health; do
|
|
code="$(request GET "$path")" || fail "$path injoignable"
|
|
expect_status "$code" 200 "GET $path"
|
|
jq -e '.ok == true' "$BODY" >/dev/null || fail "GET $path : réponse inattendue"
|
|
ok "GET $path"
|
|
done
|
|
|
|
# 3. Création de compte
|
|
stamp="$(date +%s)-$RANDOM"
|
|
email="smoke-$stamp@example.com"
|
|
password="smoke-$RANDOM$RANDOM$RANDOM"
|
|
credentials="$(jq -nc --arg email "$email" --arg password "$password" \
|
|
'{firstName: "Test", email: $email, password: $password}')"
|
|
|
|
code="$(request POST /auth/register "$credentials")" || fail "POST /auth/register injoignable"
|
|
expect_status "$code" 201 "POST /auth/register"
|
|
jq -e '(.token | type == "string" and length > 0) and .user.email == $email' --arg email "$email" "$BODY" >/dev/null \
|
|
|| fail "POST /auth/register : jeton ou utilisateur absent"
|
|
ok "POST /auth/register ($email)"
|
|
|
|
# 4. Connexion
|
|
code="$(request POST /auth/login "$credentials")" || fail "POST /auth/login injoignable"
|
|
expect_status "$code" 200 "POST /auth/login"
|
|
token="$(jq -r '.token // empty' "$BODY")"
|
|
[ -n "$token" ] || fail "POST /auth/login : jeton absent"
|
|
ok "POST /auth/login"
|
|
|
|
# 5. Création d'une galaxie
|
|
tree_payload="$(jq -nc --arg slug "smoke-$stamp" \
|
|
'{name: "Galaxie de test", slug: $slug, visitorPassword: "visiteur-test-1", contributorPassword: "contributeur-test-1"}')"
|
|
code="$(request POST /trees "$tree_payload" "$token")" || fail "POST /trees injoignable"
|
|
expect_status "$code" 201 "POST /trees"
|
|
tree_id="$(jq -r '.tree.id // empty' "$BODY")"
|
|
[ -n "$tree_id" ] || fail "POST /trees : identifiant absent"
|
|
ok "POST /trees ($tree_id)"
|
|
|
|
# 6. Lecture du graphe
|
|
code="$(request GET "/trees/$tree_id/graph" "" "$token")" || fail "GET /trees/:id/graph injoignable"
|
|
expect_status "$code" 200 "GET /trees/:id/graph"
|
|
jq -e --arg id "$tree_id" '.treeId == $id and (.graph.persons | type == "array")' "$BODY" >/dev/null \
|
|
|| fail "GET /trees/:id/graph : graphe inattendu"
|
|
ok "GET /trees/:id/graph"
|
|
|
|
# 7. Suppression de la galaxie de test
|
|
code="$(request DELETE "/trees/$tree_id" "" "$token")" || fail "DELETE /trees/:id injoignable"
|
|
expect_status "$code" 200 "DELETE /trees/:id"
|
|
ok "DELETE /trees/:id"
|
|
|
|
echo "Instance opérationnelle."
|