#!/bin/bash set -euo pipefail ROOT="$(dirname "$(realpath "$0")")/.." pass=0 fail=0 # Allow overriding gomplate binary path via env var gomplate="${GOMPLATE_BIN:-gomplate}" # Ensure gomplate is installed before running template tests require_gomplate() { if ! command -v "$gomplate" &>/dev/null; then echo " SKIP gomplate not found (install from https://github.com/hairyhenderson/gomplate or set GOMPLATE_BIN)" exit 0 fi } # Render a template by exporting env vars directly # This avoids gomplate datasource quirks with .env files render_via_env() { local tmpl=$1 envfile=$2 set -a # shellcheck disable=1090,1091 . "$envfile" set +a "$gomplate" -f "$tmpl" 2>/dev/null } # --------------------------------------------------------------------------- # entrypoint.sh.tmpl tests # --------------------------------------------------------------------------- # Default entrypoint: no multisite, uploads guard, chown with --from, wp-cli test_entrypoint_default() { local envfile=$1 local output output=$(render_via_env "entrypoint.sh.tmpl" "$envfile") # Should NOT have multisite config if echo "$output" | grep -q "WP_ALLOW_MULTISITE"; then echo " FAIL entrypoint default: unexpected WP_ALLOW_MULTISITE" return 1 fi # Should have uploads .htaccess guard if ! echo "$output" | grep -q "Prevent PHP execution in uploads"; then echo " FAIL entrypoint default: missing uploads htaccess" return 1 fi # Should use --from=root:root on chown if ! echo "$output" | grep -q "chown -R --from=root:root"; then echo " FAIL entrypoint default: missing --from=root:root on chown" return 1 fi # Should have wp-cli download if ! echo "$output" | grep -q "wp-cli.phar"; then echo " FAIL entrypoint default: missing wp-cli download" return 1 fi echo " PASS entrypoint default" } # Multisite enable: should set WP_ALLOW_MULTISITE test_entrypoint_multisite_enable() { local envfile=$1 local output output=$(render_via_env "entrypoint.sh.tmpl" "$envfile") if ! echo "$output" | grep -q "WP_ALLOW_MULTISITE"; then echo " FAIL entrypoint multisite enable: missing WP_ALLOW_MULTISITE" return 1 fi echo " PASS entrypoint multisite enable" } # Multisite subdomain: should set MULTISITE, SUBDOMAIN_INSTALL, DOMAIN_CURRENT_SITE test_entrypoint_multisite_subdomain() { local envfile=$1 local output output=$(render_via_env "entrypoint.sh.tmpl" "$envfile") if ! echo "$output" | grep -q "MULTISITE"; then echo " FAIL entrypoint multisite subdomain: missing MULTISITE" return 1 fi if ! echo "$output" | grep -q "SUBDOMAIN_INSTALL"; then echo " FAIL entrypoint multisite subdomain: missing SUBDOMAIN_INSTALL" return 1 fi if ! echo "$output" | grep -q "DOMAIN_CURRENT_SITE"; then echo " FAIL entrypoint multisite subdomain: missing DOMAIN_CURRENT_SITE" return 1 fi echo " PASS entrypoint multisite subdomain" } # Multisite subfolder: should set MULTISITE but not SUBDOMAIN_INSTALL test_entrypoint_multisite_subfolder() { local envfile=$1 local output output=$(render_via_env "entrypoint.sh.tmpl" "$envfile") if ! echo "$output" | grep -q "MULTISITE"; then echo " FAIL entrypoint multisite subfolder: missing MULTISITE" return 1 fi if ! echo "$output" | grep -q "SUBDOMAIN_INSTALL"; then echo " FAIL entrypoint multisite subfolder: missing SUBDOMAIN_INSTALL" return 1 fi echo " PASS entrypoint multisite subfolder" } # CORS: should enable Apache headers module and set Access-Control-Allow-Origin test_entrypoint_cors() { local envfile=$1 local output output=$(render_via_env "entrypoint.sh.tmpl" "$envfile") if ! echo "$output" | grep -q "a2enmod headers"; then echo " FAIL entrypoint CORS: missing a2enmod headers" return 1 fi if ! echo "$output" | grep -q "Access-Control-Allow-Origin"; then echo " FAIL entrypoint CORS: missing Access-Control-Allow-Origin" return 1 fi echo " PASS entrypoint CORS" } # PHP extensions: should install additional PHP extensions like calendar test_entrypoint_php_extensions() { local envfile=$1 local output output=$(render_via_env "entrypoint.sh.tmpl" "$envfile") if ! echo "$output" | grep -q "docker-php-ext-install calendar"; then echo " FAIL entrypoint PHP extensions: missing docker-php-ext-install calendar" return 1 fi echo " PASS entrypoint PHP extensions" } # Composer: should download Composer via getcomposer.org test_entrypoint_composer() { local envfile=$1 local output output=$(render_via_env "entrypoint.sh.tmpl" "$envfile") if ! echo "$output" | grep -q "getcomposer.org"; then echo " FAIL entrypoint composer: missing composer download" return 1 fi echo " PASS entrypoint composer" } # --------------------------------------------------------------------------- # htaccess.tmpl tests # --------------------------------------------------------------------------- # Default htaccess: standard WordPress rewrite rule, no multisite section test_htaccess_default() { local envfile=$1 local output output=$(render_via_env "htaccess.tmpl" "$envfile") if ! echo "$output" | grep -q "RewriteRule . /index.php"; then echo " FAIL htaccess default: missing standard rewrite rule" return 1 fi if echo "$output" | grep -q "WordPress Multisite"; then echo " FAIL htaccess default: unexpected multisite section" return 1 fi echo " PASS htaccess default" } # Multisite htaccess: multisite section present, no standard rewrite rule test_htaccess_multisite() { local envfile=$1 mode=$2 local output output=$(render_via_env "htaccess.tmpl" "$envfile") if ! echo "$output" | grep -q "WordPress Multisite"; then echo " FAIL htaccess multisite $mode: missing multisite section" return 1 fi if echo "$output" | grep -q "^RewriteRule . /index.php"; then echo " FAIL htaccess multisite $mode: has non-multisite rewrite rule" return 1 fi echo " PASS htaccess multisite $mode" } # --------------------------------------------------------------------------- # uploads.ini.tmpl tests # --------------------------------------------------------------------------- # Default uploads config: 256M upload limit, 30s execution time test_uploads_default() { local output output=$(render_via_env "uploads.ini.tmpl" "tests/fixtures/default.env") if ! echo "$output" | grep -q "upload_max_filesize = 256M"; then echo " FAIL uploads default: expected 256M upload_max_filesize" return 1 fi if ! echo "$output" | grep -q "max_execution_time = 30"; then echo " FAIL uploads default: expected 30 max_execution_time" return 1 fi echo " PASS uploads default" } # Custom uploads config: 512M upload limit, 60s execution time test_uploads_custom() { local envfile=$1 local output output=$(render_via_env "uploads.ini.tmpl" "$envfile") if ! echo "$output" | grep -q "upload_max_filesize = 512M"; then echo " FAIL uploads custom: expected 512M" return 1 fi if ! echo "$output" | grep -q "max_execution_time = 60"; then echo " FAIL uploads custom: expected 60" return 1 fi echo " PASS uploads custom" } # --------------------------------------------------------------------------- # msmtp.conf.tmpl tests # --------------------------------------------------------------------------- # Full SMTP config: host, from, auth, passwordeval, TLS, set_from_header test_msmtp_default() { local output output=$(render_via_env "msmtp.conf.tmpl" "tests/fixtures/smtp-full.env") if ! echo "$output" | grep -q "host mail.example.com"; then echo " FAIL msmtp default: missing host" return 1 fi if ! echo "$output" | grep -q "from wordpress@example.com"; then echo " FAIL msmtp default: missing from" return 1 fi if ! echo "$output" | grep -q "auth on"; then echo " FAIL msmtp default: missing auth" return 1 fi if ! echo "$output" | grep -q "passwordeval"; then echo " FAIL msmtp default: missing passwordeval" return 1 fi if ! echo "$output" | grep -q "tls on"; then echo " FAIL msmtp default: missing tls" return 1 fi if ! echo "$output" | grep -q "set_from_header on"; then echo " FAIL msmtp default: missing set_from_header" return 1 fi echo " PASS msmtp full config" } # --------------------------------------------------------------------------- # Run all template tests # --------------------------------------------------------------------------- echo "=== Template Rendering Tests ===" cd "$ROOT" echo "--- entrypoint.sh.tmpl ---" require_gomplate test_entrypoint_default "tests/fixtures/default.env" && pass=$((pass+1)) || fail=$((fail+1)) test_entrypoint_multisite_enable "tests/fixtures/multisite-enable.env" && pass=$((pass+1)) || fail=$((fail+1)) test_entrypoint_multisite_subdomain "tests/fixtures/multisite-subdomain.env" && pass=$((pass+1)) || fail=$((fail+1)) test_entrypoint_multisite_subfolder "tests/fixtures/multisite-subfolder.env" && pass=$((pass+1)) || fail=$((fail+1)) test_entrypoint_cors "tests/fixtures/cors.env" && pass=$((pass+1)) || fail=$((fail+1)) test_entrypoint_php_extensions "tests/fixtures/php-extensions.env" && pass=$((pass+1)) || fail=$((fail+1)) test_entrypoint_composer "tests/fixtures/composer.env" && pass=$((pass+1)) || fail=$((fail+1)) echo "--- htaccess.tmpl ---" test_htaccess_default "tests/fixtures/default.env" && pass=$((pass+1)) || fail=$((fail+1)) test_htaccess_multisite "tests/fixtures/multisite-subfolder.env" "subfolder" && pass=$((pass+1)) || fail=$((fail+1)) test_htaccess_multisite "tests/fixtures/multisite-subdomain.env" "subdomain" && pass=$((pass+1)) || fail=$((fail+1)) echo "--- uploads.ini.tmpl ---" test_uploads_default && pass=$((pass+1)) || fail=$((fail+1)) test_uploads_custom "tests/fixtures/upload-sizes.env" && pass=$((pass+1)) || fail=$((fail+1)) echo "--- msmtp.conf.tmpl ---" test_msmtp_default && pass=$((pass+1)) || fail=$((fail+1)) echo "---" echo "Passed: $pass Failed: $fail" # Exit with failure if any template test failed [ "$fail" -eq 0 ]