#!/usr/bin/env bash # Kjører backend-testsuiten (tests/) mot en fullt isolert scratch-database -- # opprettet, migrert og ryddet opp automatisk. Rører ALDRI den ekte # teecup_db (egen database + egen rolle, droppet igjen ved slutt). # # Gjenbruker den samme teeoff_db-Postgres-containeren som all manuell # scratch-verifisering i prosjektet har brukt til nå (se CLAUDE.md), men # automatiserer opprettelse/migrering/opprydning i stedet for å gjøre det # for hånd hver gang. # # Bruk: ./scripts/run_backend_tests.sh set -euo pipefail cd "$(dirname "$0")/.." SUFFIX="$(openssl rand -hex 4)" DB_NAME="teecup_pytest_${SUFFIX}" APP_ROLE="teecup_app_pytest_${SUFFIX}" APP_PASSWORD="$(openssl rand -base64 24)" SESSION_SECRET="$(openssl rand -base64 32)" MIGRATIONS_TMPDIR="$(mktemp -d)" PATCHED_002="${MIGRATIONS_TMPDIR}/002_roles_and_grants.sql" cleanup() { echo "--- Rydder opp scratch-database ${DB_NAME} og rolle ${APP_ROLE} ---" docker exec teeoff_db psql -U teeoff_admin -d postgres -v ON_ERROR_STOP=1 \ -c "DROP DATABASE IF EXISTS ${DB_NAME};" \ -c "DROP ROLE IF EXISTS ${APP_ROLE};" >/dev/null rm -rf "${MIGRATIONS_TMPDIR}" } trap cleanup EXIT echo "--- Oppretter scratch-database ${DB_NAME} ---" docker exec teeoff_db psql -U teeoff_admin -d postgres -v ON_ERROR_STOP=1 \ -c "CREATE DATABASE ${DB_NAME};" # Migrasjon 002 hardkoder rollenavnet "teecup_app" -- det navnet finnes # allerede (cluster-globalt, delt mellom ALLE databaser på denne # Postgres-instansen, inkl. den ekte teecup_db). En scratch-testrunde MÅ # derfor bruke sin egen, midlertidige rolle -- ellers hadde testene kjørt # som (og med samme passord som) den ekte runtime-rollen. Samme sed-patch- # mønster som er brukt manuelt i alle tidligere scratch-runder. # # Migrasjonen hardkoder OGSÅ databasenavnet "teecup_db" i én GRANT CONNECT- # setning -- uten patch ville den (uskadelig, men uønsket) gitt CONNECT- # rettighet på den EKTE teecup_db til testrollen. Patches til scratch- # databasenavnet av samme grunn. sed -E "s/\bteecup_app\b/${APP_ROLE}/g; s/\bteecup_db\b/${DB_NAME}/g" \ 002_roles_and_grants.sql > "${PATCHED_002}" echo "--- Kjører migrasjoner ---" for f in [0-9][0-9][0-9]_*.sql; do if [ "$f" = "002_roles_and_grants.sql" ]; then docker cp "${PATCHED_002}" "teeoff_db:/tmp/pytest_${f}" else docker cp "$f" "teeoff_db:/tmp/pytest_${f}" fi docker exec teeoff_db psql -U teeoff_admin -d "${DB_NAME}" -v ON_ERROR_STOP=1 \ -v teecup_app_password="${APP_PASSWORD}" \ -f "/tmp/pytest_${f}" >/dev/null docker exec teeoff_db rm -f "/tmp/pytest_${f}" done echo "--- Setter passord for ${APP_ROLE} ---" # psql sin :'var'-interpolering virker upålitelig i -c-modus (samme klasse # feil som kommentaren i 002_roles_and_grants.sql selv nevner) -- passordet # er selvgenerert base64 uten enkeltfnutter, så det er trygt å sette direkte # i SQL-strengen fremfor å stole på -v her. docker exec teeoff_db psql -U teeoff_admin -d postgres -v ON_ERROR_STOP=1 \ -c "ALTER ROLE ${APP_ROLE} PASSWORD '${APP_PASSWORD}';" echo "--- Bygger testimage ---" docker build -f Dockerfile.test -t teecup-backend-test . >/dev/null echo "--- Kjører pytest (nettverk: teeoff_default, host: teeoff_db) ---" set +e docker run --rm \ --network teeoff_default \ -e TEECUP_DB_HOST=teeoff_db \ -e TEECUP_DB_PORT=5432 \ -e TEECUP_DB_NAME="${DB_NAME}" \ -e TEECUP_DB_USER="${APP_ROLE}" \ -e TEECUP_DB_PASS="${APP_PASSWORD}" \ -e TEECUP_SESSION_SECRET="${SESSION_SECRET}" \ -e TEECUP_MINIO_ROOT_USER="pytest-unused" \ -e TEECUP_MINIO_ROOT_PASSWORD="pytest-unused" \ teecup-backend-test TEST_EXIT_CODE=$? set -e exit "${TEST_EXIT_CODE}"