#!/usr/bin/env bash set -euo pipefail PORT=17654 BASE="http://127.0.0.1:$PORT" PID="" TMPDIR=$(mktemp -d) cleanup() { if [[ -n "$PID" ]]; then kill "$PID" 2>/dev/null || true wait "$PID" 2>/dev/null || true fi rm -rf "$TMPDIR" } trap cleanup EXIT # -- Build ---------------------------------------------------------------- echo "==> Building..." cargo build --quiet # -- Set up temp config & test repo (never touches ~/.config) ------------- TEST_REPO="$TMPDIR/repos/test-repo" mkdir -p "$TEST_REPO" echo "hello" > "$TEST_REPO/README.md" git -C "$TEST_REPO" init -q git -C "$TEST_REPO" add -A git -C "$TEST_REPO" commit -q -m "init" TEST_CONFIG="$TMPDIR/config.json" cat > "$TEST_CONFIG" < Starting zed-bridge on port $PORT..." ZED_BRIDGE_CONFIG="$TEST_CONFIG" ./target/debug/zed-bridge & PID=$! sleep 0.3 if ! kill -0 "$PID" 2>/dev/null; then echo "FAIL: server did not start" exit 1 fi # -- Test helpers --------------------------------------------------------- PASS=0 FAIL=0 check() { local label="$1" url="$2" expect="$3" local status status=$(curl -s -o /dev/null -w '%{http_code}' --max-time 3 -0 "$url" 2>/dev/null || echo "000") if [[ "$status" == "$expect" ]]; then echo " PASS $label (HTTP $status)" PASS=$((PASS + 1)) else echo " FAIL $label expected $expect got $status" FAIL=$((FAIL + 1)) fi } check_body() { local label="$1" url="$2" pattern="$3" local body body=$(curl -s --max-time 3 -0 "$url" 2>/dev/null || true) if echo "$body" | grep -q "$pattern"; then echo " PASS $label (body contains '$pattern')" PASS=$((PASS + 1)) else echo " FAIL $label body missing '$pattern'" echo " got: ${body:0:500}" FAIL=$((FAIL + 1)) fi } # -- Tests ---------------------------------------------------------------- echo "==> Running tests..." check "health endpoint" \ "$BASE/health" 200 check_body "health JSON" \ "$BASE/health" '"status":"ok"' check "unknown endpoint" \ "$BASE/nope" 404 check "missing params" \ "$BASE/open" 400 check "missing file param" \ "$BASE/open?repo=test-repo" 400 check "unknown repo" \ "$BASE/open?repo=nonexistent&file=x" 404 # repo_dirs auto-detection check "repo_dirs resolve (test-repo)" \ "$BASE/open?repo=test-repo&file=README.md" 200 # explicit repos entry check "explicit repos entry" \ "$BASE/open?repo=explicit&file=README.md" 200 # file not found within valid repo check "file not found" \ "$BASE/open?repo=test-repo&file=nope.txt" 404 # path traversal — returns 404 (file doesn't exist) or 403 (file exists but outside repo) check "path traversal blocked" \ "$BASE/open?repo=test-repo&file=../../../etc/passwd" 404 # clean file → auto-close check_body "clean file auto-closes" \ "$BASE/open?repo=test-repo&file=README.md" "close automatically" # dirty file → stays open with warning echo "modified" >> "$TEST_REPO/README.md" check_body "dirty file warns" \ "$BASE/open?repo=test-repo&file=README.md" "local modifications" # pull endpoint — missing repo check "pull missing repo" \ "$BASE/pull" 400 # pull endpoint — unknown repo check_body "pull unknown repo" \ "$BASE/pull?repo=nonexistent" "Unknown repo" # pull endpoint — valid repo (no remote, will fail but returns JSON) check_body "pull returns JSON" \ "$BASE/pull?repo=test-repo" '"ok"' # -- Summary -------------------------------------------------------------- echo "" echo "==> $PASS passed, $FAIL failed" [[ "$FAIL" -eq 0 ]]