#!/usr/bin/env bats # Seam: the homepage site block in dankclaw/Caddyfile. Since the Anubis # rollout, www holds the homepage as a guarded vhost (the naked domain # redirects onto it at the TLS edge): the public listener proxies www # through Anubis (bot challenge), and the Authentik SSO flow runs on # Caddy's internal listener (http://:8016) after Anubis has verified the # client. caddy is not on the dev box, so the tests assert the structure # statically. load helpers setup() { CADDY="$REPO_ROOT/dankclaw/Caddyfile" } @test "the homepage serves /srv/homepage" { grep -q "root \* /srv/homepage" "$CADDY" grep -q "file_server" "$CADDY" } @test "the /admin/ page serves admin.html and / serves index.html" { # Each page is served by its own 'handle' block via 'try_files'. grep -qE "handle[[:space:]]+/admin\*" "$CADDY" grep -qE "try_files[[:space:]]+/admin.html" "$CADDY" grep -qE "try_files[[:space:]]+/index.html" "$CADDY" } @test "the shared data + assets are served to any authenticated user" { # The data (services.json, status.json) and assets are fetched by both the # user page and the admin page. With forward_auth, any authenticated user # can access them (the browser's Authentik session covers these fetches). grep -qE "@data[[:space:]]+path[[:space:]]+/services\.json[[:space:]]+/status\.json" "$CADDY" grep -qE "handle[[:space:]]+@data" "$CADDY" # docs screenshots (/img/*) must be served from disk, not answered by the # index.html catch-all (2026-10-08: PNGs came back as 200 text/html). grep -qE "@data[[:space:]]+path.*(/img/\*|/img/\*\")" "$CADDY" # the model panel's unit voices ride the same allowlist grep -qE "@data[[:space:]]+path.*/sfx/\*" "$CADDY" } @test "the homepage revalidates its assets (no stale cache after deploys)" { # Deploys overwrite /srv/homepage in place; without a revalidation header # a browser keeps serving the pre-deploy CSS/JS/HTML from cache. local block block=$(awk '/handle @home \{/,/^\t\}$/' "$CADDY") echo "$block" | grep -q 'header Cache-Control "no-cache"' } @test "the homepage vhost chains Anubis (public) before Authentik SSO (internal listener)" { # Public listener: www proxies everything through Anubis; the naked # domain never enters the chain (it redirects at the TLS edge first). local block block=$(awk '/^www\.franksdank\.cloud[[:space:]]*\{/,/^}/' "$CADDY") echo "$block" | grep -q 'reverse_proxy anubis:8923' # forwards accepted traffic to; Host survives the hop, so per-vhost # routing resumes there — guarded vhosts proxy the whole request # through Authentik, which forwards authenticated traffic back on the # post-auth listener (http://:8017) that routes straight to the app. grep -q 'http://:8016' "$CADDY" awk '/^http:\/\/:8016/,/^\}/' "$CADDY" | grep -q 'reverse_proxy authentik-server:9000' }