managarten/scripts/run-integration-tests.sh
Till JS 5af4ddab3c test(integration): end-to-end auth flow test with Mailpit + CI gating
Adds a 13-step integration test that exercises register → email
verification → login → JWT validation → /me/data → encryption-vault
init/key → logout against a real stack of postgres + redis + mailpit +
mana-auth + mana-notify in docker compose.

Verified locally that this catches every regression we hit on
2026-04-08 in well under a second:

  - missing nanoid dependency → register endpoint 500
  - missing MANA_AUTH_KEK env passthrough → mana-auth never starts
  - missing encryption-vault SQL migrations → vault endpoints 500
  - wrong cookie name in /api/v1/auth/login → no accessToken in response
  - mana-notify SMTP misconfigured → mailpit poll times out

Files:

- docker-compose.test.yml — minimal isolated stack on alt ports
  (postgres 5443, redis 6390, mailpit 1026/8026, mana-auth 3091,
  mana-notify 3092). Runs alongside the dev stack without collision.
  Postgres healthcheck runs a real query rather than just pg_isready
  to avoid the race where pg_isready reports healthy while the docker
  init scripts are still running on a unix socket.

- tests/integration/auth-flow.test.ts — bun test that drives the full
  flow via fetch + mailpit's REST API. Cleans up its test user from
  postgres in afterAll. Self-contained, no extra deps.

- tests/integration/README.md — what's covered, why it exists, how
  to run locally + extend.

- scripts/run-integration-tests.sh — orchestrator. Brings up the
  stack, pushes the @mana/auth Drizzle schema, applies the
  encryption-vault SQL migrations (002, 003), restarts mana-auth so
  it sees the fresh tables, runs the test, tears down on exit.
  KEEP_STACK=1 to leave it up for manual mailpit inspection.

- docker-compose.dev.yml — also adds Mailpit as a regular dev service
  (ports 1025/8025) so local development can have a working email
  capture without spinning up the test stack.

- .github/workflows/ci.yml — new auth-integration job that runs on
  every PR. Calls run-integration-tests.sh; on failure dumps
  mana-auth + mana-notify logs and the mailpit message queue. Marked
  as a required check via the existing PR validation pipeline.

Reproduced 3 clean runs and 1 negative-control run (removed nanoid
from package.json → mana-auth container exits → script aborts with
non-zero) before committing. Full happy path runs in ~22s on a warm
Docker cache.
2026-04-08 17:14:02 +02:00

76 lines
2.7 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# Run the auth-flow integration test against a fresh docker-compose.test.yml stack.
#
# Usage:
# ./scripts/run-integration-tests.sh # build, run, tear down
# KEEP_STACK=1 ./scripts/run-integration-tests.sh # leave stack up after run
#
# In CI, just call this. Locally, useful for both quick reruns and the
# "wait what does Mailpit look like" debugging step (set KEEP_STACK=1 then
# open http://127.0.0.1:8026).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
COMPOSE_FILE="$REPO_ROOT/docker-compose.test.yml"
TEST_DIR="$REPO_ROOT/tests/integration"
# Pick a docker binary that's actually on PATH. macOS layouts vary.
if command -v docker >/dev/null 2>&1; then
DOCKER=docker
elif [ -x /opt/homebrew/bin/docker ]; then
DOCKER=/opt/homebrew/bin/docker
elif [ -x /usr/local/bin/docker ]; then
DOCKER=/usr/local/bin/docker
else
echo "error: docker not found in PATH" >&2
exit 1
fi
cd "$REPO_ROOT"
cleanup() {
if [ "${KEEP_STACK:-0}" = "1" ]; then
echo
echo "==> KEEP_STACK=1, leaving the test stack up."
echo " Mailpit UI: http://127.0.0.1:8026"
echo " mana-auth: http://127.0.0.1:3091"
echo " Postgres: psql postgresql://mana:testpassword@localhost:5443/mana_platform"
echo " Tear down: $DOCKER compose -f $COMPOSE_FILE down -v"
return
fi
echo
echo "==> Tearing down test stack"
$DOCKER compose -f "$COMPOSE_FILE" down -v --remove-orphans >/dev/null 2>&1 || true
}
trap cleanup EXIT
echo "==> Building & starting test stack"
$DOCKER compose -f "$COMPOSE_FILE" up -d --build --wait
echo "==> Pushing mana-auth Drizzle schema into test postgres"
DATABASE_URL="postgresql://mana:testpassword@localhost:5443/mana_platform" \
pnpm --filter @mana/auth db:push --force >/dev/null
echo "==> Applying encryption-vault SQL migrations (002, 003)"
$DOCKER cp "$REPO_ROOT/services/mana-auth/sql/002_encryption_vaults.sql" \
mana-test-postgres:/tmp/002.sql
$DOCKER cp "$REPO_ROOT/services/mana-auth/sql/003_recovery_wrap.sql" \
mana-test-postgres:/tmp/003.sql
$DOCKER exec mana-test-postgres psql -U mana -d mana_platform -f /tmp/002.sql >/dev/null
$DOCKER exec mana-test-postgres psql -U mana -d mana_platform -f /tmp/003.sql >/dev/null
echo "==> Restarting mana-auth so it picks up the freshly-created tables"
# mana-auth's connection pool might have been opened against an empty DB. A
# quick restart guarantees a clean cache + schema view.
$DOCKER compose -f "$COMPOSE_FILE" restart mana-auth >/dev/null
$DOCKER compose -f "$COMPOSE_FILE" up -d --wait mana-auth
echo "==> Running auth-flow integration test"
cd "$TEST_DIR"
bun test auth-flow.test.ts
echo
echo "✅ integration tests passed"