Pixelfed 0.14.4 (FrankenPHP with Horizon and the scheduler, on the shared Postgres and Redis) and WordPress 6 with ActivityPub 9.3.1 (on a new shared MySQL, WP-Cron run by a sidecar) are peers now, each with its scenario: Pixelfed 26 checks (photos both ways with alt text, its place arriving as Rome with its coordinates, comments, likes, a boost, edits and deletes), WordPress 17 (an Article with its title, our reply, like and boost kept as comments of their kinds, its edit and removal). Pixelfed has a town driver and a pair spec: 145 checks pass, 2 expected (G-0007). What they showed: Pixelfed names our posts by their page (fixed in26dac40); on PostgreSQL its migration making caption nullable never runs, so every remote boost failed (the pasture applies it); it files a DM it fetches as followers-only (G-0007, upstream); Passport refuses a token whose user id equals its client's id. WordPress signs with RFC 9421 first, which PrivaPub now verifies (c5a69d2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
59 lines
4.9 KiB
Bash
59 lines
4.9 KiB
Bash
# WordPress 6 with ActivityPub 9.3: a persona follows an author; a published post arrives as an Article with its title;
|
|
# the persona's reply, like and boost are kept by WordPress as comments of their kind; the post's edit and its removal
|
|
# reach PrivaPub; statistics. WordPress federates from WP-Cron, run every few seconds by its sidecar. What it holds is
|
|
# read from its MySQL (database wordpress), never fetched.
|
|
WP=https://wordpress.test:6443
|
|
wpc() { curl -sk --resolve wordpress.test:6443:127.0.0.1 "$@"; }
|
|
WT=$(cat "$here/.state/wordpress.token" 2>/dev/null)
|
|
# wp_sql <sql>: one value from WordPress's database
|
|
wp_sql() { podman exec pasture-mysql mysql -upasture -ppasture wordpress -Nse "$1" 2>/dev/null; }
|
|
# a PrivaPub status in alice_wordpress's home whose title or text has the given words
|
|
p_home_id() { curl -s -H "$PH" "$P/api/v1/timelines/home?limit=40" | j "print(next((o['id'] for o in ((s.get('reblog') or s) for s in d) if '$1' in (o['content'] or '') or '$1' in ((o.get('privapub') or {}).get('title') or '')), ''))"; }
|
|
|
|
echo "wordpress"
|
|
[ -n "$WT" ] && ok "WordPress application password for wpuser" || { ko "WordPress application password"; return 1; }
|
|
PT=$(privapub_token alice_wordpress)
|
|
PH="Authorization: Bearer $PT"
|
|
[ -n "$PT" ] && ok "PrivaPub token for alice_wordpress" || { ko "PrivaPub token for alice_wordpress"; return 1; }
|
|
|
|
echo " discovery and follows"
|
|
wp_on_p=$(curl -s -H "$PH" "$P/api/v2/search?q=wpuser@wordpress.test&resolve=true&type=accounts" | j "print(d['accounts'][0]['id'])")
|
|
[ -n "$wp_on_p" ] && ok "PrivaPub resolves @wpuser@wordpress.test" || ko "PrivaPub cannot resolve wpuser"
|
|
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/accounts/$wp_on_p/follow"
|
|
until_true 45 '[ "$(curl -s -H "$PH" "$P/api/v1/accounts/relationships?id[]=$wp_on_p" | j "print(d[0][\"following\"])")" = "True" ]' \
|
|
&& ok "alice_wordpress follows wpuser (Accept arrived)" || ko "WordPress's Accept never arrived"
|
|
until_true 30 '[ "$(wp_sql "select count(*) from wp_posts where post_type = '"'ap_actor'"' and guid like '"'%alice_wordpress%'"'")" -ge 1 ]' \
|
|
&& ok "WordPress keeps alice_wordpress as a follower" || ko "WordPress does not list the follower"
|
|
|
|
echo " posts"
|
|
wp_post=$(wpc -u "$WT" -X POST "$WP/wp-json/wp/v2/posts" -H 'Content-Type: application/json' \
|
|
-d '{"title":"A WordPress article for PrivaPub","content":"<p>Written in WordPress, read in PrivaPub.</p>","status":"publish"}' | j "print(d['id'])")
|
|
[ -n "$wp_post" ] && ok "wpuser publishes a post" || ko "WordPress refused the post"
|
|
until_true 60 '[ -n "$(p_home_id "A WordPress article for PrivaPub")" ]' && ok "the post reaches alice_wordpress's home" || ko "the post never arrived"
|
|
wp_on_p_post=$(p_home_id "A WordPress article for PrivaPub")
|
|
wp_status=$(curl -s -H "$PH" "$P/api/v1/statuses/$wp_on_p_post")
|
|
[ "$(echo "$wp_status" | j "print((d.get('privapub') or {}).get('title'))")" = "A WordPress article for PrivaPub" ] && ok "it arrives as an article with its title" \
|
|
|| ko "its title is lost: $(echo "$wp_status" | j "print(d.get('privapub'))" | head -c 200)"
|
|
|
|
echo " replies, likes and boosts"
|
|
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/statuses" -d "status=@wpuser@wordpress.test a reply from PrivaPub&in_reply_to_id=$wp_on_p_post&visibility=public"
|
|
until_true 45 '[ "$(wp_sql "select count(*) from wp_comments where comment_post_ID = '"$wp_post"' and comment_content like '"'%a reply from PrivaPub%'"'")" = "1" ]' \
|
|
&& ok "alice_wordpress's reply becomes a comment on the post" || ko "the reply is not a comment on WordPress"
|
|
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/statuses/$wp_on_p_post/favourite"
|
|
until_true 45 '[ "$(wp_sql "select count(*) from wp_comments where comment_post_ID = '"$wp_post"' and comment_type = '"'like'"'")" -ge 1 ]' \
|
|
&& ok "alice_wordpress's like is kept by WordPress" || ko "the like is not kept on WordPress"
|
|
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/statuses/$wp_on_p_post/reblog"
|
|
until_true 45 '[ "$(wp_sql "select count(*) from wp_comments where comment_post_ID = '"$wp_post"' and comment_type = '"'repost'"'")" -ge 1 ]' \
|
|
&& ok "alice_wordpress's boost is kept by WordPress" || ko "the boost is not kept on WordPress"
|
|
|
|
echo " edits and removals"
|
|
wpc -o /dev/null -u "$WT" -X POST "$WP/wp-json/wp/v2/posts/$wp_post" -H 'Content-Type: application/json' -d '{"content":"<p>Written in WordPress, read in PrivaPub, then edited.</p>"}'
|
|
until_true 60 '[ "$(curl -s -H "$PH" "$P/api/v1/statuses/$wp_on_p_post" | j "print(\"then edited\" in d[\"content\"] and d[\"edited_at\"] is not None)")" = "True" ]' \
|
|
&& ok "wpuser's edit reaches PrivaPub" || ko "WordPress's edit not applied"
|
|
wpc -o /dev/null -u "$WT" -X DELETE "$WP/wp-json/wp/v2/posts/$wp_post"
|
|
until_true 60 '[ "$(curl -s -o /dev/null -w "%{http_code}" -H "$PH" "$P/api/v1/statuses/$wp_on_p_post")" = "404" ]' \
|
|
&& ok "wpuser's removal reaches PrivaPub" || ko "WordPress's removal not applied"
|
|
|
|
echo " statistics"
|
|
stats_check wordpress.test wordpress
|