Files
welcome-to-codevalet-as-a-p…/tests/test_setup_args.sh
FanaticPythoner (Nathan Trudeau) 0c159e91fb Initial Commit
2026-04-27 15:56:43 -04:00

269 lines
8.6 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# scripts/setup.sh: argument parsing, --headless wiring, detection
# ladder, and prompt_choice regression. Runs hermetically against a
# sandboxed $HOME with stubbed scripts; no network, no real Gitea.
set -euo pipefail
here="$(cd "$(dirname "$0")" && pwd -P)"
root="$here/.."
pass=0
fail=0
assert() {
local msg="$1"; shift
if "$@"; then
printf '[ok] %s\n' "$msg"
pass=$((pass + 1))
else
printf '[FAIL] %s\n' "$msg"
fail=$((fail + 1))
fi
}
assert 'setup.sh parses as valid bash' bash -n "$root/scripts/setup.sh"
help_out="$(bash "$root/scripts/setup.sh" --help 2>&1)"
assert '--help prints the Usage header' \
bash -c "printf '%s' \"$help_out\" | grep -q '^Usage: just setup'"
assert '--help documents --headless' \
bash -c "printf '%s' \"$help_out\" | grep -q -- '--headless'"
assert '--help documents FORGE_SETUP_YES' \
bash -c "printf '%s' \"$help_out\" | grep -q 'FORGE_SETUP_YES'"
set +e
bash "$root/scripts/setup.sh" --not-a-flag >/dev/null 2>"$here/.bad.err"
rc=$?
set -e
assert 'unknown option exits non-zero' bash -c "[ $rc -ne 0 ]"
assert 'unknown option prints a clear error' \
grep -q 'unknown option' "$here/.bad.err"
rm -f "$here/.bad.err"
# --- Sandbox with stubbed dependencies ------------------------------
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
mkdir -p "$tmp/scripts" "$tmp/home" "$tmp/tokens"
touch "$tmp/Justfile"
cp "$root/scripts/setup.sh" "$tmp/scripts/setup.sh"
cp "$root/scripts/common.sh" "$tmp/scripts/common.sh"
cat >"$tmp/.env.example" <<'EOF'
FORGE_GITEA_URL="http://127.0.0.1:1"
FORGE_GITEA_ORG="x"
FORGE_GITEA_USERNAME="sandbox-user"
FORGE_ORCHESTRATOR_REPO_URL="http://127.0.0.1:1/x/y.git"
FORGE_WORKSPACE_ROOT="."
FSDGG_CLI_CLIENT_ID="sandbox-client"
FSDGG_CLI_REDIRECT_URI="http://127.0.0.1:38111/callback"
EOF
cp "$tmp/.env.example" "$tmp/.env"
cat >"$tmp/scripts/doctor.sh" <<'EOF'
#!/usr/bin/env bash
echo "[doctor] stubbed"
EOF
chmod +x "$tmp/scripts/doctor.sh"
cat >"$tmp/scripts/forge_login.sh" <<EOF
#!/usr/bin/env bash
printf '%s\n' "\$@" >"$tmp/forge_login.args"
mkdir -p "$tmp/tokens"
cat >"$tmp/tokens/client-auth.json" <<JSON
{"username":"sandbox-user","gitea_access_token":"t","_forge_refresh_token":"r"}
JSON
chmod 0600 "$tmp/tokens/client-auth.json"
echo "[forge_login stub] ok"
EOF
chmod +x "$tmp/scripts/forge_login.sh"
cat >"$tmp/scripts/install-git-credential-helper.sh" <<'EOF'
#!/usr/bin/env bash
echo "[install-helper stub] ok"
EOF
chmod +x "$tmp/scripts/install-git-credential-helper.sh"
cat >"$tmp/scripts/forge_auth.py" <<'EOF'
#!/usr/bin/env python3
import sys
if len(sys.argv) >= 2 and sys.argv[1] == "status":
sys.exit(1)
sys.exit(0)
EOF
chmod +x "$tmp/scripts/forge_auth.py"
mkdir -p "$tmp/fakebin"
cat >"$tmp/fakebin/curl" <<'EOF'
#!/usr/bin/env bash
for arg in "$@"; do
case "$arg" in
*"/api/v1/version")
echo '{"version":"0.0.0-stub"}'
exit 0;;
esac
done
exec /usr/bin/curl "$@"
EOF
chmod +x "$tmp/fakebin/curl"
cat >"$tmp/fakebin/git" <<EOF
#!/usr/bin/env bash
case "\$1" in
ls-remote) exit 0;;
clone)
dest=""
while [ \$# -gt 0 ]; do
case "\$1" in
--branch) shift; shift;;
-*) shift;;
*) if [ -z "\$dest" ]; then url="\$1"; shift; dest="\$1"; shift; else shift; fi;;
esac
done
mkdir -p "\$dest/.git"
exit 0;;
esac
exec /usr/bin/git "\$@"
EOF
chmod +x "$tmp/fakebin/git"
# Overriding FORGE_* explicitly is required: `just test` pre-loads the
# real repo's .env into this process, and common.sh::load_env honours
# existing env over the file.
export HOME="$tmp/home"
export PATH="$tmp/fakebin:/usr/bin:/bin"
export FSDGG_AUTH_STORE_PATH="$tmp/tokens/client-auth.json"
export FORGE_SETUP_YES=1
export FORGE_GITEA_URL="http://127.0.0.1:1"
export FORGE_GITEA_ORG="x"
export FORGE_GITEA_USERNAME="sandbox-user"
export FORGE_ORCHESTRATOR_REPO_URL="http://127.0.0.1:1/x/y.git"
export FORGE_ORCHESTRATOR_BRANCH=""
export FORGE_WORKSPACE_ROOT="."
export FSDGG_CLI_CLIENT_ID="sandbox-client"
export FSDGG_CLI_REDIRECT_URI="http://127.0.0.1:38111/callback"
# --- --headless + FORGE_SETUP_YES=1 + no stored session: guard fires
set +e
FORGE_SETUP_YES=1 bash "$tmp/scripts/setup.sh" --headless \
>"$tmp/setup_guard.out" 2>"$tmp/setup_guard.err"
rc=$?
set -e
assert 'headless + FORGE_SETUP_YES + no session -> exits non-zero (no hang)' \
bash -c "[ $rc -ne 0 ]"
assert 'headless + FORGE_SETUP_YES guard message is actionable' \
grep -q 'cannot complete a fresh login under --headless + FORGE_SETUP_YES=1' \
"$tmp/setup_guard.err"
assert 'headless + FORGE_SETUP_YES guard does NOT invoke forge_login.sh' \
bash -c "[ ! -f \"$tmp/forge_login.args\" ]"
# --- --headless (interactive) + no stored session: forge_login.sh --no-browser
rm -f "$tmp/forge_login.args"
set +e
env -u FORGE_SETUP_YES bash "$tmp/scripts/setup.sh" --headless \
>"$tmp/setup_headless.out" 2>"$tmp/setup_headless.err"
rc=$?
set -e
assert 'headless (interactive) exits 0 in sandbox' bash -c "[ $rc -eq 0 ]"
assert 'headless (interactive) invokes forge_login.sh' \
test -f "$tmp/forge_login.args"
assert 'headless (interactive) forwards --no-browser' \
grep -qxF -- '--no-browser' "$tmp/forge_login.args"
# --- Default (browser) must NOT forward --no-browser
rm -f "$tmp/forge_login.args" "$tmp/tokens/client-auth.json"
set +e
env -u FORGE_SETUP_YES bash "$tmp/scripts/setup.sh" \
>"$tmp/setup_browser.out" 2>"$tmp/setup_browser.err"
rc=$?
set -e
assert 'default (browser) invocation exits 0' bash -c "[ $rc -eq 0 ]"
assert 'default (browser) invocation does NOT pass --no-browser' \
bash -c "! grep -qxF -- '--no-browser' \"$tmp/forge_login.args\""
# --- Live token + --headless: reuse without invoking forge_login.sh
rm -f "$tmp/forge_login.args"
cat >"$tmp/tokens/client-auth.json" <<'JSON'
{"username":"sandbox-user","gitea_access_token":"live-token",
"_forge_refresh_token":"r"}
JSON
chmod 0600 "$tmp/tokens/client-auth.json"
cat >"$tmp/scripts/forge_auth.py" <<'EOF'
#!/usr/bin/env python3
import sys
sys.exit(0)
EOF
chmod +x "$tmp/scripts/forge_auth.py"
set +e
FORGE_SETUP_YES=1 bash "$tmp/scripts/setup.sh" --headless \
>"$tmp/setup_live.out" 2>"$tmp/setup_live.err"
rc=$?
set -e
assert 'live + --headless exits 0' bash -c "[ $rc -eq 0 ]"
assert 'live + --headless does NOT invoke forge_login.sh' \
bash -c "[ ! -f \"$tmp/forge_login.args\" ]"
assert 'live + --headless reports reuse (on stderr, where logs belong)' \
grep -q 'reusing the stored session' "$tmp/setup_live.err"
# --- Stale token, silent-refresh rescue: forge_login.sh still skipped
rm -f "$tmp/forge_login.args" "$tmp/tokens/client-auth.json" \
"$tmp/forge_auth.calls"
cat >"$tmp/tokens/client-auth.json" <<'JSON'
{"username":"sandbox-user","_forge_refresh_token":"r",
"gitea_access_token":""}
JSON
chmod 0600 "$tmp/tokens/client-auth.json"
cat >"$tmp/scripts/forge_auth.py" <<EOF
#!/usr/bin/env python3
import sys, os
with open(os.environ["FORGE_AUTH_CALLS_LOG"], "a") as f:
f.write(" ".join(sys.argv[1:]) + "\n")
if len(sys.argv) >= 2 and sys.argv[1] == "status":
sys.exit(1)
if len(sys.argv) >= 2 and sys.argv[1] == "refresh":
import json, time
p = "$tmp/tokens/client-auth.json"
d = json.load(open(p))
d["gitea_access_token"] = "refreshed-token"
d["gitea_token_expires_at"] = time.time() + 3600
open(p, "w").write(json.dumps(d) + "\n")
sys.exit(0)
sys.exit(0)
EOF
chmod +x "$tmp/scripts/forge_auth.py"
export FORGE_AUTH_CALLS_LOG="$tmp/forge_auth.calls"
set +e
FORGE_SETUP_YES=1 bash "$tmp/scripts/setup.sh" --headless \
>"$tmp/setup_refresh.out" 2>"$tmp/setup_refresh.err"
rc=$?
set -e
assert 'silent-refresh rescue exits 0' bash -c "[ $rc -eq 0 ]"
assert 'silent-refresh rescue skips forge_login.sh' \
bash -c "[ ! -f \"$tmp/forge_login.args\" ]"
assert 'silent-refresh rescue called forge_auth.py refresh --force' \
grep -qF 'refresh --force' "$tmp/forge_auth.calls"
assert 'silent-refresh rescue reports success (on stderr)' \
grep -q 'refreshed stored session without a browser' "$tmp/setup_refresh.err"
# --- prompt_choice regression: non-tty branch must not contaminate stdout
fake=$(bash -c "
prompt_choice() {
local msg=\"\$1\" default=\"\$2\" reply
if [ \"\${FORGE_SETUP_YES:-0}\" = '1' ] || [ ! -t 0 ]; then
printf '%s [%s] (auto: %s)\n' \"\$msg\" \"\$default\" \"\$default\" >&2
reply=\"\$default\"
fi
printf '%s' \"\$reply\"
}
FORGE_SETUP_YES=1
printf '%s' \"\$(prompt_choice 'Pick one?' 'R')\"
")
assert 'prompt_choice non-tty branch returns only the default character' \
bash -c "[ \"$fake\" = 'R' ]"
printf '\n%d pass / %d fail\n' "$pass" "$fail"
[ "$fail" -eq 0 ]