#!/usr/bin/env bash # Regression harness for Gitea PR metadata normalization. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/pr-metadata-gitea}" REPO_DIR="$WORK_DIR/repo" FIXTURE_DIR="$WORK_DIR/fixtures" STUB_DIR="$WORK_DIR/stubs" rm -rf "$WORK_DIR" mkdir -p "$REPO_DIR" "$FIXTURE_DIR" "$STUB_DIR" git -C "$REPO_DIR" init -q git -C "$REPO_DIR" remote add origin https://git.uscllc.com/USC/uconnect.git cat > "$FIXTURE_DIR/gitea-standard.json" <<'JSON' { "number": 1905, "title": "Smoke gate fix", "state": "open", "user": {"login": "edith"}, "head": {"ref": "edith/t_39ce717c-authentik-smoke-gate"}, "base": {"ref": "main"}, "labels": [{"name": "ci"}], "assignees": [{"login": "edith"}], "html_url": "https://git.uscllc.com/USC/uconnect/pulls/1905" } JSON cat > "$FIXTURE_DIR/gitea-fallback.json" <<'JSON' { "number": 1908, "title": "Fallback branch fields", "state": "open", "user": {"login": "edith"}, "head_branch": "fix/fallback-head", "base_branch": "main", "html_url": "https://git.uscllc.com/USC/uconnect/pulls/1908" } JSON cat > "$FIXTURE_DIR/gitea-refs-pull-label.json" <<'JSON' { "number": 1908, "title": "Closed merged PR with synthetic pull ref", "state": "closed", "user": {"login": "edith"}, "head": {"ref": "refs/pull/1908/head", "label": "fix/t_23fa9e1d-portal-health-backend"}, "base": {"ref": "main"}, "html_url": "https://git.uscllc.com/USC/uconnect/pulls/1908" } JSON cat > "$FIXTURE_DIR/gitea-error.json" <<'JSON' {"message": "user does not exist [uid: 0, name: ]", "url": "https://git.uscllc.com/api/swagger"} JSON cat > "$STUB_DIR/curl" <<'SH' #!/usr/bin/env bash set -euo pipefail output_file="" while [[ $# -gt 0 ]]; do case "$1" in -o) output_file="$2" shift 2 ;; -w|-H|-u) shift 2 ;; -s|-S|-sS) shift ;; *) shift ;; esac done if [[ -z "$output_file" ]]; then echo "curl stub expected -o " >&2 exit 2 fi case "${MOSAIC_STUB_CURL_MODE:-success}" in success) cat > "$output_file" <<'JSON' { "number": 1910, "title": "Live curl path", "state": "open", "user": {"login": "edith"}, "head": {"ref": "fix/live-curl-path"}, "base": {"ref": "main"}, "html_url": "https://git.example.test/acme/widgets/pulls/1910" } JSON printf '200' ;; cat-fails-after-2xx) rm -f -- "$output_file" ln -s /nonexistent/pr-metadata-body "$output_file" printf '200' ;; *) echo "unknown MOSAIC_STUB_CURL_MODE=${MOSAIC_STUB_CURL_MODE:-}" >&2 exit 2 ;; esac SH chmod +x "$STUB_DIR/curl" assert_tmpdir_empty() { local tmpdir="$1" leftover leftover=$(find "$tmpdir" -mindepth 1 -print -quit) if [[ -n "$leftover" ]]; then echo "Expected tmpfile cleanup, found leftover: $leftover" >&2 find "$tmpdir" -mindepth 1 -maxdepth 1 -ls >&2 exit 1 fi } run_curl_success_case() { local tmpdir="$WORK_DIR/tmp-success" stderr_file="$WORK_DIR/curl-success.stderr" local output status mkdir -p "$tmpdir" set +e output=$(cd "$REPO_DIR" && \ PATH="$STUB_DIR:$PATH" \ TMPDIR="$tmpdir" \ GITEA_TOKEN="stub-token" \ GITEA_URL="https://git.example.test" \ MOSAIC_STUB_CURL_MODE="success" \ "$SCRIPT_DIR/pr-metadata.sh" -n 1910 2>"$stderr_file") status=$? set -e if [[ "$status" -ne 0 ]]; then echo "Expected curl success path to pass, got status $status" >&2 cat "$stderr_file" >&2 exit 1 fi if grep -q "unbound variable" "$stderr_file"; then echo "curl success path emitted unbound-variable cleanup noise" >&2 cat "$stderr_file" >&2 exit 1 fi assert_tmpdir_empty "$tmpdir" PR_METADATA_OUTPUT="$output" python3 - <<'PY' import json import os data = json.loads(os.environ["PR_METADATA_OUTPUT"]) assert data["number"] == 1910, data assert data["baseRefName"] == "main", data assert data["headRefName"] == "fix/live-curl-path", data PY } run_curl_early_exit_cleanup_case() { local tmpdir="$WORK_DIR/tmp-early-exit" stderr_file="$WORK_DIR/curl-early-exit.stderr" local output status mkdir -p "$tmpdir" set +e output=$(cd "$REPO_DIR" && \ PATH="$STUB_DIR:$PATH" \ TMPDIR="$tmpdir" \ GITEA_TOKEN="stub-token" \ GITEA_URL="https://git.example.test" \ MOSAIC_STUB_CURL_MODE="cat-fails-after-2xx" \ "$SCRIPT_DIR/pr-metadata.sh" -n 1910 2>"$stderr_file") status=$? set -e if [[ "$status" -eq 0 ]]; then echo "Expected unreadable 2xx body path to fail" >&2 printf '%s\n' "$output" >&2 exit 1 fi if grep -q "unbound variable" "$stderr_file"; then echo "curl early-exit path emitted unbound-variable cleanup noise" >&2 cat "$stderr_file" >&2 exit 1 fi if ! grep -q "No such file or directory" "$stderr_file"; then echo "Expected body-read failure from broken symlink path" >&2 cat "$stderr_file" >&2 exit 1 fi if grep -q "Gitea API returned non-JSON" "$stderr_file"; then echo "curl helper masked body-read failure as later JSON parsing failure" >&2 cat "$stderr_file" >&2 exit 1 fi assert_tmpdir_empty "$tmpdir" } run_case() { local fixture="$1" expected_number="$2" expected_head="$3" local output output=$(cd "$REPO_DIR" && MOSAIC_GITEA_PR_METADATA_RAW_FILE="$fixture" "$SCRIPT_DIR/pr-metadata.sh" -n "$expected_number") PR_METADATA_OUTPUT="$output" python3 - "$expected_number" "$expected_head" <<'PY' import json import os import sys data = json.loads(os.environ["PR_METADATA_OUTPUT"]) expected_number = int(sys.argv[1]) expected_head = sys.argv[2] assert data["number"] == expected_number, data assert data["baseRefName"] == "main", data assert data["headRefName"] == expected_head, data PY } run_case "$FIXTURE_DIR/gitea-standard.json" 1905 edith/t_39ce717c-authentik-smoke-gate run_case "$FIXTURE_DIR/gitea-fallback.json" 1908 fix/fallback-head run_case "$FIXTURE_DIR/gitea-refs-pull-label.json" 1908 fix/t_23fa9e1d-portal-health-backend run_curl_success_case run_curl_early_exit_cleanup_case if cd "$REPO_DIR" && MOSAIC_GITEA_PR_METADATA_RAW_FILE="$FIXTURE_DIR/gitea-error.json" "$SCRIPT_DIR/pr-metadata.sh" -n 1909 >/dev/null 2>"$WORK_DIR/error.log"; then echo "Expected API error fixture to fail" >&2 exit 1 fi grep -q "Gitea API error" "$WORK_DIR/error.log" echo "Gitea PR metadata regression harness passed"