Add CLI args and tests

This commit is contained in:
Dejvino
2026-07-30 17:44:40 +02:00
parent 0a86cfaee6
commit 160388194a
5 changed files with 236 additions and 15 deletions
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env python3
# Minimal mock of the WordPress REST API /wp/v2/posts endpoint, for testing
# post.sh without a real WordPress install.
#
# Behavior is controlled by two files (paths given via env vars):
# MOCK_WP_CONTROL_FILE - optional JSON {"status": int, "body": {...}} that
# determines the response to the next request. If absent, responds
# 201 with the submitted fields echoed back under an "id".
# MOCK_WP_REQUEST_FILE - overwritten on every request with
# {"path": ..., "payload": ...} so a test can assert on what was sent.
#
# Listens on 127.0.0.1:$MOCK_WP_PORT (default 8899).
import http.server
import json
import os
PORT = int(os.environ.get("MOCK_WP_PORT", "8899"))
CONTROL_FILE = os.environ["MOCK_WP_CONTROL_FILE"]
REQUEST_FILE = os.environ["MOCK_WP_REQUEST_FILE"]
class Handler(http.server.BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", 0))
body = self.rfile.read(length)
try:
data = json.loads(body) if body else {}
except json.JSONDecodeError:
data = {"_raw": body.decode(errors="replace")}
with open(REQUEST_FILE, "w") as f:
json.dump({"path": self.path, "payload": data}, f)
status, resp_body = 201, {"id": 1, **data}
if os.path.exists(CONTROL_FILE):
with open(CONTROL_FILE) as f:
control = json.load(f)
status = control.get("status", status)
resp_body = control.get("body", resp_body)
payload = json.dumps(resp_body).encode()
self.send_response(status)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(payload)))
self.end_headers()
self.wfile.write(payload)
def log_message(self, format, *args):
pass
if __name__ == "__main__":
http.server.HTTPServer(("127.0.0.1", PORT), Handler).serve_forever()
+94
View File
@@ -0,0 +1,94 @@
#!/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
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")"
# --- 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")"
# --- 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