#!/usr/bin/env bash set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" INSTALL_SCRIPT="$REPO_ROOT/scripts/setup-neuledge-context.sh" SECURE_SCRIPT="$REPO_ROOT/scripts/secure-context-config.sh" PASS=0 FAIL=0 pass() { echo " PASS: $1"; PASS=$((PASS + 1)); } fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); } # Fake bin directory — npm and context stubs go here FAKE_BIN="$(mktemp -d)" trap 'rm -rf "$FAKE_BIN"' EXIT # --- setup-neuledge-context.sh --- echo "" echo "--- install: already at target version, skips npm ---" # context returns target version; npm must NOT be called printf '#!/bin/sh\necho "1.2.0"\n' > "$FAKE_BIN/context"; chmod +x "$FAKE_BIN/context" printf '#!/bin/sh\necho "npm called unexpectedly" >&2; exit 1\n' > "$FAKE_BIN/npm"; chmod +x "$FAKE_BIN/npm" OUT="$(PATH="$FAKE_BIN:$PATH" bash "$INSTALL_SCRIPT" "1.2.0" 2>&1)" if echo "$OUT" | grep -q "nothing to do"; then pass "skips install when already at target version" else fail "expected 'nothing to do' — got: $OUT" fi echo "" echo "--- install: missing version, runs npm ---" # context not found; npm installs and context then returns the version rm -f "$FAKE_BIN/context" printf '#!/bin/sh\necho ""\n' > "$FAKE_BIN/context"; chmod +x "$FAKE_BIN/context" # npm installs and makes context return the right version on next call FAKE_BIN2="$(mktemp -d)" trap 'rm -rf "$FAKE_BIN2"' EXIT cat > "$FAKE_BIN2/npm" <<'SH' #!/bin/sh # After npm runs, replace the context stub to return the installed version printf '#!/bin/sh\necho "1.2.0"\n' > "${FAKE_BIN_DIR}/context" chmod +x "${FAKE_BIN_DIR}/context" exit 0 SH chmod +x "$FAKE_BIN2/npm" export FAKE_BIN_DIR="$FAKE_BIN" OUT="$(PATH="$FAKE_BIN2:$FAKE_BIN:$PATH" bash "$INSTALL_SCRIPT" "1.2.0" 2>&1)" if echo "$OUT" | grep -q "Done:"; then pass "installs when context absent" else fail "expected 'Done:' — got: $OUT" fi echo "" echo "--- install: version mismatch after npm — exits non-zero ---" # npm runs but context still reports wrong version printf '#!/bin/sh\necho "1.1.0"\n' > "$FAKE_BIN/context"; chmod +x "$FAKE_BIN/context" printf '#!/bin/sh\necho "npm ok"; exit 0\n' > "$FAKE_BIN/npm"; chmod +x "$FAKE_BIN/npm" if PATH="$FAKE_BIN:$PATH" bash "$INSTALL_SCRIPT" "1.2.0" >/dev/null 2>&1; then fail "expected non-zero exit when installed version mismatches target" else pass "exits non-zero when installed version does not match target" fi echo "" echo "--- install: upgrade path message ---" printf '#!/bin/sh\necho "1.1.0"\n' > "$FAKE_BIN/context"; chmod +x "$FAKE_BIN/context" cat > "$FAKE_BIN/npm" <<'SH' #!/bin/sh printf '#!/bin/sh\necho "1.2.0"\n' > "${FAKE_BIN_DIR}/context" chmod +x "${FAKE_BIN_DIR}/context" exit 0 SH chmod +x "$FAKE_BIN/npm" OUT="$(FAKE_BIN_DIR="$FAKE_BIN" PATH="$FAKE_BIN:$PATH" bash "$INSTALL_SCRIPT" "1.2.0" 2>&1)" if echo "$OUT" | grep -q "Upgrading"; then pass "prints 'Upgrading' when bumping from an older version" else fail "expected 'Upgrading' — got: $OUT" fi # --- secure-context-config.sh --- echo "" echo "--- secure: skips when config file does not exist ---" FAKE_HOME="$(mktemp -d)" trap 'rm -rf "$FAKE_HOME"' EXIT OUT="$(HOME="$FAKE_HOME" bash "$SECURE_SCRIPT" 2>&1)" if echo "$OUT" | grep -q "Skipped"; then pass "skips when config file absent" else fail "expected 'Skipped' — got: $OUT" fi echo "" echo "--- secure: sets 600 on existing config ---" mkdir -p "$FAKE_HOME/.context" echo '{"servers":[]}' > "$FAKE_HOME/.context/config.json" chmod 644 "$FAKE_HOME/.context/config.json" HOME="$FAKE_HOME" bash "$SECURE_SCRIPT" > /dev/null PERMS="$(stat -c '%a' "$FAKE_HOME/.context/config.json")" if [ "$PERMS" = "600" ]; then pass "config.json set to 600" else fail "expected 600, got $PERMS" fi echo "" echo "--- secure: idempotent on already-600 file ---" HOME="$FAKE_HOME" bash "$SECURE_SCRIPT" > /dev/null PERMS="$(stat -c '%a' "$FAKE_HOME/.context/config.json")" if [ "$PERMS" = "600" ]; then pass "idempotent: 600 remains 600 on re-run" else fail "expected 600 after second run, got $PERMS" fi echo "" echo "--- install: npm exits non-zero — script propagates failure ---" printf '#!/bin/sh\necho ""\n' > "$FAKE_BIN/context"; chmod +x "$FAKE_BIN/context" printf '#!/bin/sh\necho "npm error" >&2; exit 1\n' > "$FAKE_BIN/npm"; chmod +x "$FAKE_BIN/npm" if PATH="$FAKE_BIN:$PATH" bash "$INSTALL_SCRIPT" "1.2.0" >/dev/null 2>&1; then fail "expected non-zero exit when npm fails" else pass "exits non-zero when npm exits with error" fi echo "" echo "--- install: no arg uses default version 1.2.0 ---" printf '#!/bin/sh\necho "1.2.0"\n' > "$FAKE_BIN/context"; chmod +x "$FAKE_BIN/context" printf '#!/bin/sh\necho "npm called unexpectedly" >&2; exit 1\n' > "$FAKE_BIN/npm"; chmod +x "$FAKE_BIN/npm" OUT="$(PATH="$FAKE_BIN:$PATH" bash "$INSTALL_SCRIPT" 2>&1)" if echo "$OUT" | grep -q "nothing to do"; then pass "default version 1.2.0 used when no arg given" else fail "expected default version skip — got: $OUT" fi echo "" echo "--- install: fresh install prints 'Installing' not 'Upgrading' ---" printf '#!/bin/sh\necho ""\n' > "$FAKE_BIN/context"; chmod +x "$FAKE_BIN/context" FAKE_BIN3="$(mktemp -d)" trap 'rm -rf "$FAKE_BIN3"' EXIT cat > "$FAKE_BIN3/npm" <<'SH' #!/bin/sh printf '#!/bin/sh\necho "1.2.0"\n' > "${FAKE_BIN_DIR}/context" chmod +x "${FAKE_BIN_DIR}/context" exit 0 SH chmod +x "$FAKE_BIN3/npm" OUT="$(FAKE_BIN_DIR="$FAKE_BIN" PATH="$FAKE_BIN3:$FAKE_BIN:$PATH" bash "$INSTALL_SCRIPT" "1.2.0" 2>&1)" if echo "$OUT" | grep -q "Installing"; then pass "fresh install prints 'Installing'" else fail "expected 'Installing' on fresh install — got: $OUT" fi if echo "$OUT" | grep -q "Upgrading"; then fail "fresh install should not print 'Upgrading'" else pass "fresh install does not print 'Upgrading'" fi echo "" echo "--- install: context --version with v-prefix is parsed correctly ---" printf '#!/bin/sh\necho "v1.2.0"\n' > "$FAKE_BIN/context"; chmod +x "$FAKE_BIN/context" printf '#!/bin/sh\necho "npm called unexpectedly" >&2; exit 1\n' > "$FAKE_BIN/npm"; chmod +x "$FAKE_BIN/npm" OUT="$(PATH="$FAKE_BIN:$PATH" bash "$INSTALL_SCRIPT" "1.2.0" 2>&1)" if echo "$OUT" | grep -q "nothing to do"; then pass "v-prefixed version output parsed correctly as match" else fail "expected 'nothing to do' for v-prefixed version — got: $OUT" fi echo "" echo "--- secure: downgrades world-writable (777) permissions to 600 ---" FAKE_HOME2="$(mktemp -d)" trap 'rm -rf "$FAKE_HOME2"' EXIT mkdir -p "$FAKE_HOME2/.context" echo '{"servers":[]}' > "$FAKE_HOME2/.context/config.json" chmod 777 "$FAKE_HOME2/.context/config.json" HOME="$FAKE_HOME2" bash "$SECURE_SCRIPT" > /dev/null PERMS="$(stat -c '%a' "$FAKE_HOME2/.context/config.json")" if [ "$PERMS" = "600" ]; then pass "777 permissions correctly downgraded to 600" else fail "expected 600 from 777, got $PERMS" fi echo "" echo "Results: $PASS passed, $FAIL failed" [[ $FAIL -eq 0 ]]