wordpress-rest-curl/tests/run_tests.sh
2026-07-30 18:15:42 +02:00

144 lines
5.8 KiB
Bash
Executable File

#!/bin/bash
# Test suite for post.sh, run against tests/mock_wp_server.py so no real
# WordPress install is needed. Requires curl, jq, python3, python3-markdown2.
set -u
cd "$(dirname "$0")/.."
for bin in curl jq python3; do
command -v "$bin" >/dev/null || { echo "missing dependency: $bin"; exit 1; }
done
python3 -c "import markdown2" 2>/dev/null || { echo "missing dependency: python3-markdown2"; exit 1; }
PORT=8899
WORKDIR=$(mktemp -d)
trap 'kill $SERVER_PID 2>/dev/null; rm -rf "$WORKDIR"' EXIT
export MOCK_WP_PORT=$PORT
export MOCK_WP_CONTROL_FILE="$WORKDIR/control.json"
export MOCK_WP_REQUEST_FILE="$WORKDIR/request.json"
python3 -u tests/mock_wp_server.py &
SERVER_PID=$!
for i in $(seq 1 20); do
curl -s -o /dev/null "http://127.0.0.1:$PORT/" && break
sleep 0.2
done
export HOME="$WORKDIR/home"
mkdir -p "$HOME/.config/wordpress-rest-curl"
cat > "$HOME/.config/wordpress-rest-curl/config.sh" <<EOF
TRANSFORM=('title' 'markdown')
USER="tester"
PASSWORD="testpass"
SERVER="http://127.0.0.1:$PORT"
CATEGORIES="3,7"
TAGS="10"
EOF
# Deliberately sparse: only the fields that differ from config.sh, to prove
# --site layers on top of the default config rather than replacing it.
cat > "$HOME/.config/wordpress-rest-curl/othersite.sh" <<EOF
USER="other-tester"
PASSWORD="other-pass"
CATEGORIES="1"
EOF
POST_FILE="$WORKDIR/post.md"
cat > "$POST_FILE" <<'EOF2'
# My Test Title
Some **markdown** content here.
EOF2
run_post_sh() {
printf "" | "$PWD/post.sh" "$@"
}
FAIL=0
assert_eq() {
local desc="$1" expected="$2" actual="$3"
if [[ "$expected" != "$actual" ]]; then
echo "FAIL: $desc (expected [$expected], got [$actual])"
FAIL=1
else
echo "PASS: $desc"
fi
}
# --- create + publish ---
rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"
run_post_sh --file "$POST_FILE" --publish >/dev/null
assert_eq "create: exit code" "0" "$?"
REQ=$(cat "$MOCK_WP_REQUEST_FILE")
assert_eq "create: path" "/wp-json/wp/v2/posts/" "$(jq -r '.path' <<<"$REQ")"
assert_eq "create: title extracted from heading" "My Test Title" "$(jq -r '.payload.title' <<<"$REQ")"
assert_eq "create: status" "publish" "$(jq -r '.payload.status' <<<"$REQ")"
assert_eq "create: categories sent as array" "[3,7]" "$(jq -c '.payload.categories' <<<"$REQ")"
assert_eq "create: tags sent as array" "[10]" "$(jq -c '.payload.tags' <<<"$REQ")"
assert_eq "create: content rendered as markdown" "true" "$(jq -r '.payload.content | test("<strong>markdown</strong>")' <<<"$REQ")"
assert_eq "create: sends a non-default user agent" "true" "$(jq -r '.user_agent != "" and (.user_agent | test("^curl/") | not)' <<<"$REQ")"
# --- USER_AGENT is configurable, e.g. to dodge a host's DDoS protection ---
rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"
cat >> "$HOME/.config/wordpress-rest-curl/config.sh" <<'EOF3'
USER_AGENT="Mozilla/5.0 (test override)"
EOF3
run_post_sh --file "$POST_FILE" >/dev/null
assert_eq "user agent: exit code" "0" "$?"
REQ=$(cat "$MOCK_WP_REQUEST_FILE")
assert_eq "user agent: override from config is sent" "Mozilla/5.0 (test override)" "$(jq -r '.user_agent' <<<"$REQ")"
# --- trailing slash on SERVER doesn't produce a double slash in the URL ---
rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"
cat >> "$HOME/.config/wordpress-rest-curl/config.sh" <<EOF3
SERVER="http://127.0.0.1:$PORT/"
EOF3
run_post_sh --file "$POST_FILE" >/dev/null
assert_eq "trailing slash: exit code" "0" "$?"
REQ=$(cat "$MOCK_WP_REQUEST_FILE")
assert_eq "trailing slash: path has no double slash" "/wp-json/wp/v2/posts/" "$(jq -r '.path' <<<"$REQ")"
# --- edit an existing post ---
rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"
run_post_sh --file "$POST_FILE" --edit 99 >/dev/null
assert_eq "edit: exit code" "0" "$?"
REQ=$(cat "$MOCK_WP_REQUEST_FILE")
assert_eq "edit: path includes post ID" "/wp-json/wp/v2/posts/99" "$(jq -r '.path' <<<"$REQ")"
assert_eq "edit: status defaults to draft" "draft" "$(jq -r '.payload.status' <<<"$REQ")"
# --- --site layers on top of config.sh: overrides what it sets, inherits the rest ---
rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"
run_post_sh --site othersite --file "$POST_FILE" >/dev/null
assert_eq "site: exit code" "0" "$?"
REQ=$(cat "$MOCK_WP_REQUEST_FILE")
assert_eq "site: categories overridden by site config" "[1]" "$(jq -c '.payload.categories' <<<"$REQ")"
assert_eq "site: tags inherited from default config" "[10]" "$(jq -c '.payload.tags' <<<"$REQ")"
assert_eq "site: title transform inherited from default config" "My Test Title" "$(jq -r '.payload.title' <<<"$REQ")"
rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"
OUT=$(run_post_sh --site does-not-exist --file "$POST_FILE" 2>&1)
assert_eq "site: unknown site exits non-zero" "1" "$?"
assert_eq "site: unknown site error message" "true" "$(grep -q "Config file not found" <<<"$OUT" && echo true || echo false)"
# --- no --site and no default config.sh: clean error, not a crash ---
mv "$HOME/.config/wordpress-rest-curl/config.sh" "$WORKDIR/config.sh.bak"
OUT=$(run_post_sh --file "$POST_FILE" 2>&1)
assert_eq "no config: exits non-zero" "1" "$?"
assert_eq "no config: error message" "true" "$(grep -q "No site specified and no default config found" <<<"$OUT" && echo true || echo false)"
mv "$WORKDIR/config.sh.bak" "$HOME/.config/wordpress-rest-curl/config.sh"
# --- non-2xx response is surfaced and script exits non-zero ---
rm -f "$MOCK_WP_REQUEST_FILE"
echo '{"status": 401, "body": {"code": "rest_forbidden", "message": "Sorry, you are not allowed to do that."}}' > "$MOCK_WP_CONTROL_FILE"
OUT=$(run_post_sh --file "$POST_FILE" 2>&1)
assert_eq "error: exit code" "1" "$?"
assert_eq "error: HTTP status surfaced" "true" "$(grep -q "HTTP 401" <<<"$OUT" && echo true || echo false)"
rm -f "$MOCK_WP_CONTROL_FILE"
echo
if [[ $FAIL -eq 0 ]]; then
echo "All tests passed."
else
echo "Some tests FAILED."
fi
exit $FAIL