ci/woodpecker/push/publish Pipeline was successful
Co-authored-by: fred <[email protected]>
138 lines
7.3 KiB
Bash
Executable File
138 lines
7.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Regression: issue-view.sh must show comment BODIES, on both paths, and must name
|
|
# the failure tea actually reported instead of guessing a credential cause (#1357).
|
|
#
|
|
# Four defects, each with its own case below:
|
|
# F1 tea exits 1 in any repo with extensions.worktreeconfig=true; the wrapper must
|
|
# say so (git-config condition) and fall back to the API.
|
|
# F2 the API fallback dumped raw issue JSON, which carries only a comment COUNT.
|
|
# F3 the tea path never passed --comments, so tea prompted (non-interactively: nothing).
|
|
# F4 on ANY tea failure the wrapper printed the REVOKED OR STALE TOKEN note.
|
|
#
|
|
# Verification bar (plan §6): assert a real comment BODY appears, not a count and not
|
|
# `grep -c comment` (that instrument matched the issue title and read inverted).
|
|
#
|
|
# Hermetic: mock tea and curl on PATH, sandboxed repo. Resolves no real credentials.
|
|
set -euo pipefail
|
|
|
|
WORK_ROOT="${AGENT_WORK_ROOT:-${TMPDIR:-/tmp}}"
|
|
SANDBOX="$WORK_ROOT/issue-view-comments-test-$$"
|
|
MOCK_BIN="$SANDBOX/bin"; REPO_DIR="$SANDBOX/repo"; CALLS="$SANDBOX/calls.log"
|
|
cleanup() { rm -rf "$SANDBOX"; }
|
|
trap cleanup EXIT
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
TARGET="$SCRIPT_DIR/issue-view.sh"
|
|
[ -f "$TARGET" ] || { echo "FAIL: issue-view.sh not found beside this test"; exit 1; }
|
|
fail() { echo "FAIL: $*"; exit 1; }
|
|
|
|
mkdir -p "$MOCK_BIN" "$REPO_DIR" || fail "setup: cannot create sandbox under $WORK_ROOT"
|
|
: > "$CALLS" || fail "setup: cannot write calls log at $CALLS"
|
|
cd "$REPO_DIR" || fail "setup: cannot cd into $REPO_DIR"
|
|
git init -q || fail "setup: git init failed"
|
|
git remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git || fail "setup: git remote add failed"
|
|
export PATH="$MOCK_BIN:$PATH" CALLS
|
|
export GITEA_URL="https://git.mosaicstack.dev"
|
|
export GITEA_TOKEN="redacted-test-token"
|
|
# The identity ladder must not reach for this seat's real login; the mock tea below
|
|
# defines the only login that exists in this sandbox.
|
|
unset MOSAIC_GIT_IDENTITY
|
|
# No fleet in the sandbox: on a host that runs one, get_gitea_token fails closed for an
|
|
# identity-less caller (by design), which would make this test measure the host, not
|
|
# the wrapper. An empty brain home makes the sandbox the same on every host.
|
|
export MOSAIC_BRAIN_HOME="$SANDBOX/brain"
|
|
mkdir -p "$MOSAIC_BRAIN_HOME" || fail "setup: cannot create sandbox brain home"
|
|
|
|
# Distinctive strings: a comment body that appears nowhere else, and an issue title
|
|
# that contains the word "comment" so a count-of-the-word instrument would misread.
|
|
BODY_MARKER="zebra-quill-comment-body-7731"
|
|
ISSUE_TITLE="wrapper never shows a comment"
|
|
|
|
# --- mock curl: serves the issue and its comments; logs every call --------------
|
|
cat > "$MOCK_BIN/curl" <<EOF
|
|
#!/bin/bash
|
|
url=""
|
|
while [ \$# -gt 0 ]; do
|
|
case "\$1" in
|
|
http*) url="\$1"; shift ;;
|
|
*) shift ;;
|
|
esac
|
|
done
|
|
printf 'curl %s\n' "\$url" >> "$CALLS"
|
|
case "\$url" in
|
|
*/issues/77/comments)
|
|
if [ "\${MOCK_NO_COMMENTS:-}" = "1" ]; then echo '[]'; else
|
|
echo '[{"id":1,"user":{"login":"alice"},"created_at":"2026-08-21T00:00:00Z","body":"$BODY_MARKER"}]'; fi ;;
|
|
*/issues/77)
|
|
echo '{"number":77,"title":"$ISSUE_TITLE","state":"open","user":{"login":"bob"},"created_at":"2026-08-21T00:00:00Z","labels":[],"milestone":null,"html_url":"https://git.mosaicstack.dev/mosaicstack/stack/issues/77","body":"issue body","comments":1}' ;;
|
|
*) echo '{}' ;;
|
|
esac
|
|
exit 0
|
|
EOF
|
|
chmod +x "$MOCK_BIN/curl"
|
|
|
|
# --- mock tea: MOCK_TEA_MODE selects the behaviour under test --------------------
|
|
# ok : prints the issue, and the comment body ONLY when --comments is passed (F3)
|
|
# wtconfig : exits 1 with the repositoryformatversion error (F1/F4)
|
|
# badtoken : exits 1 with tea's credential error (F4 control: credential wording allowed)
|
|
cat > "$MOCK_BIN/tea" <<EOF
|
|
#!/bin/bash
|
|
printf 'tea %s\n' "\$*" >> "$CALLS"
|
|
if [[ "\$*" == *"login list"* ]]; then
|
|
echo '[{"name":"git.mosaicstack.dev","url":"https://git.mosaicstack.dev"}]'; exit 0
|
|
fi
|
|
case "\${MOCK_TEA_MODE:-ok}" in
|
|
wtconfig) echo 'Error: core.repositoryformatversion does not support extension: worktreeconfig' >&2; exit 1 ;;
|
|
badtoken) echo 'Failed to create Gitea client: invalid username, password or token' >&2; exit 1 ;;
|
|
esac
|
|
echo "# #77 $ISSUE_TITLE (open)"
|
|
echo "issue body"
|
|
if [[ "\$*" == *"--comments"* ]]; then echo "$BODY_MARKER"; fi
|
|
exit 0
|
|
EOF
|
|
chmod +x "$MOCK_BIN/tea"
|
|
|
|
[ "$(command -v tea)" = "$MOCK_BIN/tea" ] || fail "setup: tea does not resolve inside the sandbox"
|
|
[ "$(command -v curl)" = "$MOCK_BIN/curl" ] || fail "setup: curl does not resolve inside the sandbox"
|
|
|
|
run() { bash "$TARGET" -i 77 >"$SANDBOX/out" 2>"$SANDBOX/err"; echo $?; }
|
|
|
|
# F3: tea path shows the comment body, which the mock emits only under --comments.
|
|
: > "$CALLS"
|
|
rc=$(MOCK_TEA_MODE=ok run)
|
|
[ "$rc" = 0 ] || fail "F3: expected rc=0 on the tea path, got $rc: $(cat "$SANDBOX/err")"
|
|
grep -q -- '--comments' "$CALLS" || fail "F3: tea was not invoked with --comments: $(cat "$CALLS")"
|
|
grep -q "$BODY_MARKER" "$SANDBOX/out" || fail "F3: comment body missing from tea-path output"
|
|
if grep -q '^curl' "$CALLS"; then fail "F3: tea path succeeded but the API fallback ran anyway"; fi
|
|
|
|
# F1 + F2: worktreeconfig failure is named as a git-config condition, falls back to
|
|
# the API, and the API rendering includes the comment BODY.
|
|
: > "$CALLS"
|
|
rc=$(MOCK_TEA_MODE=wtconfig run)
|
|
[ "$rc" = 0 ] || fail "F1: expected rc=0 via API fallback, got $rc: $(cat "$SANDBOX/err")"
|
|
grep -q 'worktreeconfig' "$SANDBOX/err" || fail "F1: stderr does not name the worktreeconfig cause: $(cat "$SANDBOX/err")"
|
|
grep -q 'not a credential problem' "$SANDBOX/err" || fail "F1: stderr does not rule out the credential cause"
|
|
grep -q 'issues/77/comments' "$CALLS" || fail "F2: API fallback never fetched /comments: $(cat "$CALLS")"
|
|
grep -q "$BODY_MARKER" "$SANDBOX/out" || fail "F2: comment body missing from API-path output"
|
|
grep -q "$ISSUE_TITLE" "$SANDBOX/out" || fail "F2: issue title missing from API-path output"
|
|
if grep -q 'REVOKED OR STALE' "$SANDBOX/err"; then fail "F4: stale-token note printed for a git-config failure"; fi
|
|
if grep -q '"comments": 1' "$SANDBOX/out"; then fail "F2: output is still raw JSON (comment count instead of bodies)"; fi
|
|
|
|
# F4 control: a real credential error from tea may still carry the credential note,
|
|
# and tea's own line must be relayed so the reader sees the actual cause.
|
|
: > "$CALLS"
|
|
rc=$(MOCK_TEA_MODE=badtoken run)
|
|
[ "$rc" = 0 ] || fail "F4 control: expected rc=0 via API fallback, got $rc"
|
|
grep -q 'invalid username, password or token' "$SANDBOX/err" || fail "F4: tea's own error line was not relayed"
|
|
if grep -q 'worktreeconfig' "$SANDBOX/err"; then fail "F4: git-config wording printed for a credential failure"; fi
|
|
|
|
# Negative control: an issue with no comments prints no comment section on the API
|
|
# path. Without this, a renderer that always prints a section would pass F2.
|
|
: > "$CALLS"
|
|
rc=$(MOCK_TEA_MODE=wtconfig MOCK_NO_COMMENTS=1 run)
|
|
[ "$rc" = 0 ] || fail "negative control: expected rc=0, got $rc"
|
|
if grep -q -- '--- Comments' "$SANDBOX/out"; then fail "negative control: comment section printed for an issue with no comments"; fi
|
|
if grep -q "$BODY_MARKER" "$SANDBOX/out"; then fail "negative control: a comment body appeared for an issue with no comments"; fi
|
|
|
|
echo "issue-view comments regression harness passed"
|