#!/usr/bin/env bash # Curl-based smoke test (§13): register → login → healthz → board against a # running stack (docker compose up -d). set -euo pipefail BASE_URL="${BASE_URL:-http://localhost:8787}" JAR=$(mktemp) trap 'rm -f "$JAR" /tmp/smoke-*.json' EXIT fail() { echo "SMOKE FAIL: $*" >&2; exit 1; } echo "smoke: $BASE_URL" # 1. health endpoints code=$(curl -fsS -o /tmp/smoke-healthz.json -w '%{http_code}' "$BASE_URL/healthz") \ || fail "healthz unreachable" [ "$code" = "200" ] || fail "healthz returned $code" grep -q '"ok"' /tmp/smoke-healthz.json || fail "healthz body unexpected" echo " healthz ok" code=$(curl -sS -o /tmp/smoke-readyz.json -w '%{http_code}' "$BASE_URL/readyz") \ || fail "readyz unreachable" [ "$code" = "200" ] || fail "readyz returned $code: $(cat /tmp/smoke-readyz.json)" echo " readyz ok" curl -fsS "$BASE_URL/metricsz" | grep -q '"counters"' || fail "metricsz body unexpected" echo " metricsz ok" # 2. register a throwaway developer EMAIL="smoke-$(date +%s)-$RANDOM@example.com" code=$(curl -sS -c "$JAR" -o /tmp/smoke-reg.json -w '%{http_code}' \ -H 'Content-Type: application/json' \ -d "{\"email\":\"$EMAIL\",\"name\":\"Smoke Test\",\"password\":\"smoke-pass-123\"}" \ "$BASE_URL/api/v1/auth/register") [ "$code" = "201" ] || fail "register returned $code: $(cat /tmp/smoke-reg.json)" echo " register ok ($EMAIL)" # 3. logout, then login again CSRF=$(awk '$6=="bb_csrf" {print $7}' "$JAR") curl -fsS -b "$JAR" -X POST -H "X-CSRF-Token: $CSRF" \ "$BASE_URL/api/v1/auth/logout" -o /dev/null || fail "logout failed" code=$(curl -sS -c "$JAR" -o /tmp/smoke-login.json -w '%{http_code}' \ -H 'Content-Type: application/json' \ -d "{\"email\":\"$EMAIL\",\"password\":\"smoke-pass-123\"}" \ "$BASE_URL/api/v1/auth/login") [ "$code" = "200" ] || fail "login returned $code" echo " login ok" # 4. authenticated me + developer board curl -fsS -b "$JAR" "$BASE_URL/api/v1/auth/me" | grep -q "$EMAIL" || fail "me missing email" echo " me ok" code=$(curl -sS -b "$JAR" -o /tmp/smoke-board.json -w '%{http_code}' "$BASE_URL/api/v1/board") [ "$code" = "200" ] || fail "board returned $code: $(cat /tmp/smoke-board.json)" grep -q '"tasks"' /tmp/smoke-board.json || fail "board body unexpected" echo " board ok" # 5. pages render curl -fsS "$BASE_URL/login" | grep -q 'Log in · Bounty Board' || fail "login page broken" curl -fsS "$BASE_URL/api/docs" | grep -q 'Bounty Board API' || fail "api docs broken" echo " pages ok" echo "SMOKE PASS"