#!/usr/bin/env bash # Phase 8 definition of done (AUD-112). # # - GET /capabilities returns the routing topics for `compass_nhs` # - POST /ask answers "what does Harry have on today at school?" in one sentence # - POST /notify is authenticated and refuses a bad request without delivering # - an unsigned request is refused (401), and an unset token closes the API (503) # # Run on .13 from the project folder. It reads SCHOOL_HUB_TOKEN from # environment.d/school-service.env (gitignored) and never prints it. /notify is # not made to deliver a real message: the token is proven with a validation # refusal. Pass --send to deliver one real message to Sam. # # Read-only against the school (AGENTS.md ยง10 rule 1): nothing here calls the # school. /ask reads SQLite only. set -u BASE="${SCHOOL_VERIFY_BASE:-http://127.0.0.1:8792}" ENV_FILE="${SCHOOL_ENV_FILE:-environment.d/school-service.env}" SEND=0 [ "${1:-}" = "--send" ] && SEND=1 TMP="$(mktemp -d)" trap 'rm -rf "$TMP"' EXIT fail=0 pass() { printf 'PASS %s\n' "$1"; } bad() { printf 'FAIL %s\n' "$1"; fail=1; } skip() { printf 'SKIP %s\n' "$1"; } token="${SCHOOL_HUB_TOKEN:-}" if [ -z "$token" ] && [ -f "$ENV_FILE" ]; then token="$(sed -n 's/^SCHOOL_HUB_TOKEN=//p' "$ENV_FILE" | head -1)" fi echo "== GET /health ==" code="$(curl -sS -o "$TMP/health.json" -w '%{http_code}' "$BASE/health" || echo 000)" printf 'HTTP %s\n' "$code" cat "$TMP/health.json" 2>/dev/null; echo if [ "$code" = "200" ] && grep -q '"ok":true' "$TMP/health.json"; then pass "/health 200 with ok true" else bad "/health did not return 200 ok true" fi echo echo "== GET /capabilities without a token ==" code="$(curl -sS -o "$TMP/caps401.json" -w '%{http_code}' "$BASE/capabilities" || echo 000)" if [ "$code" = "401" ]; then pass "/capabilities refused an unsigned request" elif [ "$code" = "503" ]; then bad "/capabilities answered 503: SCHOOL_HUB_TOKEN is not set on the service" else bad "/capabilities answered $code without a token, want 401" fi if [ -z "$token" ]; then skip "no SCHOOL_HUB_TOKEN in the environment or $ENV_FILE; the authenticated checks cannot run" else echo echo "== GET /capabilities ==" code="$(curl -sS -H "Authorization: Bearer $token" -o "$TMP/caps.json" -w '%{http_code}' "$BASE/capabilities" || echo 000)" printf 'HTTP %s\n' "$code" cat "$TMP/caps.json" 2>/dev/null; echo if [ "$code" = "200" ] && grep -q '"project":"compass_nhs"' "$TMP/caps.json"; then pass "/capabilities names compass_nhs" else bad "/capabilities did not name compass_nhs (HTTP $code)" fi echo echo "== POST /ask: what does Harry have on today at school? ==" code="$(curl -sS -H "Authorization: Bearer $token" -H 'Content-Type: application/json' \ -d '{"question":"what does Harry have on today at school?","asker":"sam","person":"harry","source":"esp32"}' \ -o "$TMP/ask.json" -w '%{http_code}' "$BASE/ask" || echo 000)" printf 'HTTP %s\n' "$code" cat "$TMP/ask.json" 2>/dev/null; echo if [ "$code" = "200" ] && grep -q '"answer":"' "$TMP/ask.json"; then pass "/ask returned an answer" else bad "/ask did not return an answer (HTTP $code)" fi echo echo "== POST /notify: token proven without delivering ==" code="$(curl -sS -H "Authorization: Bearer $token" -H 'Content-Type: application/json' \ -d '{"from":"verify","level":"nonsense","message":"validation probe","person":"Sam"}' \ -o "$TMP/notify.json" -w '%{http_code}' "$BASE/notify" || echo 000)" printf 'HTTP %s\n' "$code" cat "$TMP/notify.json" 2>/dev/null; echo if [ "$code" = "400" ]; then pass "/notify rejected an invalid level (auth worked, nothing delivered)" else bad "/notify answered $code for a bad level, want 400" fi if [ "$SEND" = "1" ]; then echo echo "== POST /notify: real delivery to Sam (--send) ==" code="$(curl -sS -H "Authorization: Bearer $token" -H 'Content-Type: application/json' \ -d '{"from":"verify-phase8","level":"info","message":"Compass / NHS Hub API check.","person":"Sam"}' \ -o "$TMP/send.json" -w '%{http_code}' "$BASE/notify" || echo 000)" printf 'HTTP %s\n' "$code" cat "$TMP/send.json" 2>/dev/null; echo if [ "$code" = "200" ] && grep -q '"ok":true' "$TMP/send.json"; then pass "/notify delivered a real message" else bad "/notify did not deliver (HTTP $code)" fi else skip "real /notify delivery not attempted; rerun with --send" fi fi echo if [ "$fail" = "0" ]; then echo "RESULT: Phase 8 verified" else echo "RESULT: Phase 8 verification FAILED" fi exit "$fail"