#!/usr/bin/env bash set -euo pipefail ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) env_file=${1:-} expected_domain=${2:-} if [[ -z "$env_file" || -z "$expected_domain" || ! -f "$env_file" ]]; then echo "Usage: $0 ENV_FILE EXPECTED_DOMAIN" >&2 exit 1 fi [[ "$(stat -c '%a' "$env_file")" == 600 ]] || { echo "Test environment must have mode 0600: $env_file" >&2 exit 1 } [[ "$(stat -c '%u' "$env_file")" == "$(id -u)" ]] || { echo "Test environment must be owned by the current operator." >&2 exit 1 } read_value() { local key=$1 awk -v key="$key" ' index($0, key "=") == 1 { print substr($0, length(key) + 2) found = 1 exit } END { if (!found) exit 1 } ' "$env_file" } require_value() { local key=$1 value value=$(read_value "$key") || true [[ -n "$value" ]] || { echo "$key is missing or empty in $env_file." >&2 exit 1 } printf '%s' "$value" } [[ "$(require_value DEPLOYMENT_ENV)" == test ]] || { echo "Test validation requires DEPLOYMENT_ENV=test." >&2 exit 1 } [[ "$(require_value DEPLOYMENT_TARGET)" == compose ]] || { echo "Test validation requires DEPLOYMENT_TARGET=compose." >&2 exit 1 } [[ "$(require_value COMPOSE_PROJECT_NAME)" == who_need_help_test ]] || { echo "The test checkout must use COMPOSE_PROJECT_NAME=who_need_help_test." >&2 exit 1 } [[ "$(require_value APP_IMAGE)" == who-need-help:test-* ]] || { echo "The test checkout must use a test-specific APP_IMAGE." >&2 exit 1 } [[ "$(require_value SOCKET_PROXY_IMAGE)" == who-need-help:socket-proxy-test-* ]] || { echo "The test checkout must use a test-specific socket-proxy image." >&2 exit 1 } [[ "$(require_value POSTGIS_IMAGE)" == who-need-help:postgis-test-* ]] || { echo "The test checkout must use a test-specific PostGIS image." >&2 exit 1 } [[ "$(require_value DATABASE_MODE)" == container ]] || { echo "The test checkout must use its project-owned database container." >&2 exit 1 } [[ "$(require_value POSTGRES_DB)" == who_need_help_test ]] || { echo "The test database must be named who_need_help_test." >&2 exit 1 } [[ "$(require_value DATABASE_URL)" == ecto://*"@db/who_need_help_test" ]] || { echo "The test DATABASE_URL must target its own Compose database." >&2 exit 1 } email_delivery_provider=$(require_value EMAIL_DELIVERY_PROVIDER) case "$email_delivery_provider" in smtp) smtp_relay=$(require_value SMTP_RELAY) if [[ "$smtp_relay" != mailpit ]]; then require_value SMTP_PORT >/dev/null smtp_auth=$(require_value SMTP_AUTH) smtp_username=$(read_value SMTP_USERNAME 2>/dev/null || true) smtp_password=$(read_value SMTP_PASSWORD 2>/dev/null || true) [[ "$smtp_auth" != always || (-n "$smtp_username" && -n "$smtp_password") ]] || { echo "External test SMTP requires SMTP_USERNAME and SMTP_PASSWORD when SMTP_AUTH=always." >&2 exit 1 } [[ (-z "$smtp_username" && -z "$smtp_password") || (-n "$smtp_username" && -n "$smtp_password") ]] || { echo "SMTP_USERNAME and SMTP_PASSWORD must be configured together." >&2 exit 1 } fi ;; unisender_go) require_value UNISENDER_GO_API_KEY >/dev/null unisender_base_url=$(require_value UNISENDER_GO_BASE_URL) [[ "$unisender_base_url" == https://* ]] || { echo "UNISENDER_GO_BASE_URL must use HTTPS." >&2 exit 1 } ;; *) echo "EMAIL_DELIVERY_PROVIDER must be smtp or unisender_go." >&2 exit 1 ;; esac require_value EMAIL_FROM_ADDRESS >/dev/null [[ "$(require_value PHX_HOST)" == "$expected_domain" && "$(require_value WNH_BASE_URL)" == "https://$expected_domain" ]] || { echo "The test public origin does not match EXPECTED_DOMAIN." >&2 exit 1 } [[ "$(require_value PUBLIC_UPSTREAM_NAME)" == who-need-help-test ]] || { echo "The test public upstream alias must be who-need-help-test." >&2 exit 1 } google_id=$(read_value GOOGLE_OAUTH_CLIENT_ID 2>/dev/null || true) google_secret=$(read_value GOOGLE_OAUTH_CLIENT_SECRET 2>/dev/null || true) if [[ -n "$google_id" || -n "$google_secret" ]]; then [[ -n "$google_id" && -n "$google_secret" ]] || { echo "Test Google OAuth ID and secret must be configured together." >&2 exit 1 } fi secrets=( "$(require_value POSTGRES_PASSWORD)" "$(require_value SECRET_KEY_BASE)" "$(require_value HANDOVER_SECRET)" "$(require_value RELEASE_COOKIE)" "$(require_value METRICS_TOKEN)" ) for ((left = 0; left < ${#secrets[@]}; left++)); do for ((right = left + 1; right < ${#secrets[@]}; right++)); do [[ "${secrets[$left]}" != "${secrets[$right]}" ]] || { echo "Test secrets must be independent." >&2 exit 1 } done done "$ROOT/scripts/compose.sh" "$env_file" config --quiet echo "Test environment isolation and Compose structure passed validation."