#!/usr/bin/env bash set -uo pipefail SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P) SKILL_DIR=$(cd "$SCRIPT_DIR/.." && pwd -P) HELPER="$SKILL_DIR/scripts/tobserver-agent" # shellcheck disable=SC1090,SC1091 # The absolute helper path is resolved at runtime. source "$HELPER" passes=0 failures=0 pass() { printf 'ok - %s\n' "$1" passes=$((passes + 1)) } fail() { printf 'not ok - %s\n' "$1" >&2 failures=$((failures + 1)) } expect_equal() { local name=$1 local expected=$2 local actual=$3 if [[ "$actual" == "$expected" ]]; then pass "$name" else printf 'expected: %q\nactual: %q\n' "$expected" "$actual" >&2 fail "$name" fi } expect_success() { local name=$1 shift if ("$@" >/dev/null 2>&1); then pass "$name" else fail "$name" fi } expect_failure() { local name=$1 shift if ("$@" >/dev/null 2>&1); then fail "$name" else pass "$name" fi } valid_pr_json() { cat <<'JSON' { "number": 17, "state": "open", "merged": false, "user": {"login": "oibot"}, "base": {"ref": "main"}, "head": { "repo": {"full_name": "oibot/Tobserver"}, "ref": "refs/pull/17/head", "label": "oibot/tobserver-agent-enable-gc-20260724-120000-abcdef", "sha": "0123456789abcdef" }, "flow": 1, "html_url": "https://codeberg.org/oibot/Tobserver/pulls/17" } JSON } expect_equal \ "branch derives helper AGit topic" \ "tobserver-agent-enable-gc-20260724-120000-abcdef" \ "$(topic_for_branch 'agent/enable-gc-20260724-120000-abcdef')" expect_equal \ "AGit topic derives local branch" \ "agent/enable-gc-20260724-120000-abcdef" \ "$(branch_for_topic 'tobserver-agent-enable-gc-20260724-120000-abcdef')" expect_failure "main is not a helper branch" topic_for_branch "main" expect_failure "nested branch suffix is rejected" topic_for_branch "agent/nested/change" expect_failure "foreign AGit topic is rejected" branch_for_topic "manual-change" encoded=$(encode_push_option_string $'line one\nGrüße') decoded=$(printf '%s' "${encoded#\{base64\}}" | base64 --decode) expect_equal "push-option base64 round trip" $'line one\nGrüße' "$decoded" expect_success \ "canonical open AGit PR is revisable" \ assert_revisable_pull_request "$(valid_pr_json)" 17 \ "tobserver-agent-enable-gc-20260724-120000-abcdef" wrong_user=$(valid_pr_json | jq '.user.login = "oibot-agent"') expect_failure \ "bot-authored PR is rejected after cutover" \ assert_revisable_pull_request "$wrong_user" 17 non_agit=$(valid_pr_json | jq '.flow = 0') expect_failure \ "non-AGit PR is rejected" \ assert_revisable_pull_request "$non_agit" 17 wrong_head=$(valid_pr_json | jq '.head.ref = "agent/unsafe"') expect_failure \ "unexpected PR head ref is rejected" \ assert_revisable_pull_request "$wrong_head" 17 expect_equal \ "canonical PR URL yields number" \ "17" \ "$(pr_number_from_url 'https://codeberg.org/oibot/Tobserver/pulls/17')" expect_failure \ "foreign PR URL is rejected" \ pr_number_from_url "https://example.invalid/oibot/Tobserver/pulls/17" if rg -n 'Authorization: token|KEYCHAIN_|read_codeberg_token|codeberg-tobserver-agent' "$HELPER" >/dev/null; then fail "helper contains no bot or write-token path" else pass "helper contains no bot or write-token path" fi if bash -n "$HELPER"; then pass "helper parses as Bash" else fail "helper parses as Bash" fi if "$HELPER" --help | grep -q 'Codeberg API token'; then pass "help documents tokenless boundary" else fail "help documents tokenless boundary" fi printf '\n%d passed; %d failed\n' "$passes" "$failures" ((failures == 0))