#!/bin/bash # Integrationstest för helmd. Körs i en isolerad container (se # scripts/run-integration.sh) men fungerar var som helst där tmux, # curl och binären finns och där HOME får smutsas ner. set -eu BIN="${HELMD_BIN:-./build/helmd}" export HOME="${TEST_HOME:-$(mktemp -d)}" export HELMD_CONFIG="$HOME/helmd-config.json" API=http://127.0.0.1:8788 PASS=0; FAIL=0 say() { printf '\n== %s\n' "$*"; } ok() { PASS=$((PASS+1)); echo " OK: $*"; } fail() { FAIL=$((FAIL+1)); echo " FAIL: $*" >&2; } expect_contains() { # haystackfil, nål, beskrivning if grep -qF "$2" "$1"; then ok "$3"; else fail "$3 — hittade inte: $2"; cat "$1" | tail -20; fi } curl_api() { curl -sS -H "Authorization: Bearer $TOKEN" "$@"; } wait_for() { # beskrivning, timeout-sek, kommando... local desc="$1" t="$2"; shift 2 for _ in $(seq 1 $((t*2))); do if "$@" >/dev/null 2>&1; then ok "$desc"; return 0; fi sleep 0.5 done fail "$desc (timeout ${t}s)"; return 1 } say "startar helmd" TOKEN=$("$BIN" token) "$BIN" serve --listen 127.0.0.1:8788 & HELMD_PID=$! trap 'kill $HELMD_PID 2>/dev/null || true; tmux kill-server 2>/dev/null || true' EXIT wait_for "servern svarar på /api/health" 10 \ curl -fsS -H "Authorization: Bearer $TOKEN" $API/api/health say "auth" CODE=$(curl -s -o /dev/null -w '%{http_code}' $API/api/sessions) [ "$CODE" = 401 ] && ok "utan token => 401" || fail "utan token gav $CODE" CODE=$(curl -s -o /dev/null -w '%{http_code}' "$API/api/sessions?token=$TOKEN") [ "$CODE" = 200 ] && ok "query-token => 200" || fail "query-token gav $CODE" say "stäng av ntfy för testet (PUT /api/config)" curl_api -X PUT -d '{"ntfy":{"server":"https://ntfy.brasse-pc.eu","topic":"agent-helm","allowed_topics":["agent-helm","claude"],"enabled":false,"notify_on_question":false}}' \ $API/api/config > /tmp/cfg.json expect_contains /tmp/cfg.json '"saved":true' "config sparad" curl_api $API/api/config | grep -q '"enabled":false' && ok "ntfy avstängd" || fail "ntfy fortfarande på" say "session: skapa med mock-agent" MOCK="$(cd "$(dirname "$0")/.." && pwd)/testdata/mock-agent.sh" curl_api -X POST -d "{\"name\":\"prov\",\"cmd\":\"bash $MOCK\",\"cwd\":\"/tmp\"}" \ $API/api/sessions > /tmp/sess.json expect_contains /tmp/sess.json '"name":"prov"' "session skapad" say "fråga 1: onumrerad trust-fråga (pilnavigering)" q_has_two_options() { curl_api $API/api/sessions/prov/question | grep -q '"No, exit"'; } wait_for "trust-frågan detekterad" 10 q_has_two_options curl_api $API/api/sessions/prov/question > /tmp/q1.json expect_contains /tmp/q1.json '"selected":0' "markören står på första valet" curl_api -X POST -d '{"option":2}' $API/api/sessions/prov/answer > /tmp/a1.json expect_contains /tmp/a1.json '"answered":true' "svar skickat" screen_has() { curl_api "$API/api/sessions/prov/screen" | grep -qF "$1"; } wait_for "mocken fick svaret (ned+enter => val 1)" 10 screen_has "TRUST_ANSWER=1" say "prompt" curl_api -X POST -d '{"text":"hej från testet"}' $API/api/sessions/prov/prompt > /dev/null wait_for "prompten nådde agenten" 10 screen_has "ECHO: hej från testet" say "fråga 2: numrerad godkännandefråga (sifferval)" curl_api -X POST -d '{"text":"ask-numbered"}' $API/api/sessions/prov/prompt > /dev/null q2_detected() { curl_api $API/api/sessions/prov/question | grep -q '"numbered":true'; } wait_for "numrerad fråga detekterad" 10 q2_detected curl_api -X POST -d '{"option":3}' $API/api/sessions/prov/answer > /dev/null wait_for "mocken fick siffran 3" 10 screen_has "PICKED=3" say "raw keys + mode" curl_api -X POST -d '{"keys":["Enter"]}' $API/api/sessions/prov/keys | grep -q '"sent":true' \ && ok "keys-endpoint" || fail "keys-endpoint" curl_api -X POST -d '{"action":"cycle"}' $API/api/sessions/prov/mode | grep -q '"sent":true' \ && ok "mode cycle (BTab)" || fail "mode cycle" say "SSE-events" (curl_api -N --max-time 4 "$API/api/events" > /tmp/events.txt 2>/dev/null || true) & SSE_PID=$! sleep 0.5 curl_api -X POST -d '{"text":"sse-test"}' $API/api/sessions/prov/prompt > /dev/null wait $SSE_PID || true expect_contains /tmp/events.txt 'event: hello' "SSE hello" expect_contains /tmp/events.txt 'event: screen' "SSE screen-event vid ändring" say "fildelning" printf '