Mitra joins the pasture (peers/mitra.sh) on the shared Postgres; scenarios/mitra.sh drives its Mastodon API through follows, posts, replies, likes, reposts, a reaction, a poll, edits, deletions, direct messages, the unfollow and statistics: 28 checks, with no change to PrivaPub. Mitra carries FEP-8b32 proofs made with Ed25519, which PrivaPub does not verify yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
100 lines
8.6 KiB
Bash
100 lines
8.6 KiB
Bash
# Mitra 5.9.1: follows both ways, posts, replies, likes, reposts, an emoji reaction, a poll, an edit and a deletion both
|
|
# ways, direct messages, the unfollow, statistics. Mitra signs its deliveries with RSA and carries FEP-8b32 proofs made
|
|
# with its Ed25519 key. Driven through its Mastodon API as mitrauser, with the token peers/mitra.sh got.
|
|
MI=https://mitra.test:6443
|
|
MIT=$(cat "$here/.state/mitra/mitrauser.token" 2>/dev/null)
|
|
mi() { site mitra.test -s -H "Authorization: Bearer $MIT" "$@"; }
|
|
mi_json() { local method=$1 path=$2 body=$3; mi -X "$method" "$MI$path" -H 'Content-Type: application/json' -d "$body"; }
|
|
mi_status_of() { mi "$MI/api/v1/statuses/${1:-none}"; }
|
|
p_home_has() { curl -s -H "$PH" "$P/api/v1/timelines/home?limit=40" | j "print(next(((s.get('reblog') or s)['id'] for s in d if '$1' in ((s.get('reblog') or s)['content'] or '')), ''))"; }
|
|
p_status() { curl -s -H "$PH" "$P/api/v1/statuses/$1" | j "print(d.get('$2'))"; }
|
|
|
|
echo "mitra"
|
|
[ "$(mi "$MI/api/v1/accounts/verify_credentials" | j "print(d['username'])")" = "mitrauser" ] && ok "Mitra token for mitrauser" || { ko "Mitra token"; return 1; }
|
|
PT=$(privapub_token alice_mitra)
|
|
PH="Authorization: Bearer $PT"
|
|
[ -n "$PT" ] && ok "PrivaPub token for alice_mitra" || { ko "PrivaPub token for alice_mitra"; return 1; }
|
|
run=$(date +%s)
|
|
|
|
echo " follows"
|
|
# (its search resolves an account elsewhere only when it is not limited to a type)
|
|
alice_on_mi=$(mi "$MI/api/v2/search?q=alice_mitra%40privapub.test&resolve=true" | j "print(d['accounts'][0]['id'])")
|
|
[ -n "$alice_on_mi" ] && ok "Mitra resolves alice" || ko "Mitra cannot resolve alice"
|
|
mi -o /dev/null -X POST "$MI/api/v1/accounts/$alice_on_mi/follow"
|
|
until_true 45 '[ "$(mi "$MI/api/v1/accounts/relationships?id[]=$alice_on_mi" | j "print(d[0][\"following\"])")" = "True" ]' \
|
|
&& ok "mitrauser follows alice (Accept arrived)" || ko "alice's Accept never reached Mitra"
|
|
mi_on_p=$(curl -s -H "$PH" "$P/api/v2/search?q=mitrauser@mitra.test&resolve=true&type=accounts" | j "print(d['accounts'][0]['id'])")
|
|
[ -n "$mi_on_p" ] && ok "PrivaPub resolves mitrauser" || ko "PrivaPub cannot resolve mitrauser"
|
|
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/accounts/$mi_on_p/follow"
|
|
until_true 45 '[ "$(curl -s -H "$PH" "$P/api/v1/accounts/relationships?id[]=$mi_on_p" | j "print(d[0][\"following\"])")" = "True" ]' \
|
|
&& ok "alice follows mitrauser (Accept arrived)" || ko "Mitra's Accept never arrived"
|
|
|
|
echo " posts"
|
|
mi_post=$(mi_json POST /api/v1/statuses "{\"status\":\"a Mitra post $run\",\"visibility\":\"public\"}")
|
|
mi_post_id=$(echo "$mi_post" | j "print(d['id'])")
|
|
until_true 45 '[ -n "$(p_home_has "a Mitra post $run")" ]' && ok "mitrauser's post reaches alice's home" || ko "mitrauser's post never reached alice"
|
|
mi_on_p_post=$(p_home_has "a Mitra post $run")
|
|
p_post=$(curl -s -X POST -H "$PH" $P/api/v1/statuses -d "status=a PrivaPub post for Mitra $run&visibility=public")
|
|
p_post_id=$(echo "$p_post" | j "print(d['id'])"); p_post_uri=$(echo "$p_post" | j "print(d['uri'])")
|
|
until_true 45 '[ "$(mi "$MI/api/v1/timelines/home?limit=40" | j "print(any(s[\"uri\"] == \"$p_post_uri\" for s in d))")" = "True" ]' \
|
|
&& ok "alice's post reaches mitrauser's home" || ko "alice's post never reached Mitra"
|
|
p_on_mi=$(mi "$MI/api/v1/timelines/home?limit=40" | j "print(next(s['id'] for s in d if s['uri'] == '$p_post_uri'))")
|
|
|
|
echo " replies"
|
|
mi_json POST /api/v1/statuses "{\"status\":\"@alice_mitra@privapub.test a Mitra reply $run\",\"in_reply_to_id\":\"$p_on_mi\",\"visibility\":\"public\"}" >/dev/null
|
|
until_true 45 '[ "$(curl -s -H "$PH" "$P/api/v1/statuses/$p_post_id/context" | j "print(any(\"a Mitra reply $run\" in s[\"content\"] for s in d[\"descendants\"]))")" = "True" ]' \
|
|
&& ok "mitrauser's reply threads under alice's post" || ko "mitrauser's reply missing on PrivaPub"
|
|
curl -s -o /dev/null -X POST -H "$PH" $P/api/v1/statuses -d "status=@mitrauser@mitra.test a PrivaPub reply $run&in_reply_to_id=$mi_on_p_post&visibility=public"
|
|
until_true 45 '[ "$(mi "$MI/api/v1/statuses/$mi_post_id/context" | j "print(any(\"a PrivaPub reply $run\" in s[\"content\"] for s in d[\"descendants\"]))")" = "True" ]' \
|
|
&& ok "alice's reply threads under mitrauser's post" || ko "alice's reply missing on Mitra"
|
|
|
|
echo " likes, reposts and reactions"
|
|
mi -o /dev/null -X POST "$MI/api/v1/statuses/$p_on_mi/favourite"
|
|
until_true 45 '[ "$(p_status $p_post_id favourites_count)" = "1" ]' && ok "mitrauser's like counts on PrivaPub" || ko "mitrauser's like never counted"
|
|
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/statuses/$mi_on_p_post/favourite"
|
|
until_true 45 '[ "$(mi_status_of $mi_post_id | j "print(d[\"favourites_count\"])")" = "1" ]' && ok "alice's like counts on Mitra" || ko "alice's like never counted on Mitra"
|
|
mi -o /dev/null -X POST "$MI/api/v1/statuses/$p_on_mi/reblog"
|
|
until_true 45 '[ "$(p_status $p_post_id reblogs_count)" = "1" ]' && ok "mitrauser's repost is a boost on PrivaPub" || ko "mitrauser's repost never counted"
|
|
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/statuses/$mi_on_p_post/reblog"
|
|
until_true 45 '[ "$(mi_status_of $mi_post_id | j "print(d[\"reblogs_count\"])")" = "1" ]' && ok "alice's boost counts on Mitra" || ko "alice's boost never counted on Mitra"
|
|
mi -o /dev/null -X PUT "$MI/api/v1/pleroma/statuses/$p_on_mi/reactions/%F0%9F%8E%89"
|
|
until_true 45 '[ "$(curl -s -H "$PH" "$P/api/v1/statuses/$p_post_id" | j "print(any(r[\"name\"] == \"🎉\" for r in (d.get(\"pleroma\") or {}).get(\"emoji_reactions\") or d.get(\"reactions\") or []))")" = "True" ]' \
|
|
&& ok "mitrauser's reaction reaches alice's post" || ko "mitrauser's reaction never arrived ($(curl -s -H "$PH" "$P/api/v1/statuses/$p_post_id" | j "print((d.get('pleroma') or {}).get('emoji_reactions'))"))"
|
|
|
|
echo " polls"
|
|
mi_poll=$(mi_json POST /api/v1/statuses "{\"status\":\"a Mitra poll $run\",\"visibility\":\"public\",\"poll\":{\"options\":[\"hay\",\"clover\"],\"expires_in\":3600}}")
|
|
until_true 45 '[ -n "$(p_home_has "a Mitra poll $run")" ]' && ok "mitrauser's poll reaches alice" || ko "mitrauser's poll never reached alice"
|
|
p_poll=$(curl -s -H "$PH" "$P/api/v1/statuses/$(p_home_has "a Mitra poll $run")" | j "print(d['poll']['id'] if d.get('poll') else '')")
|
|
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/polls/$p_poll/votes" -d 'choices[]=1'
|
|
until_true 45 '[ "$(mi_status_of $(echo "$mi_poll" | j "print(d[\"id\"])") | j "print(d[\"poll\"][\"votes_count\"])")" = "1" ]' \
|
|
&& ok "alice's vote counts on Mitra" || ko "alice's vote never counted on Mitra"
|
|
|
|
echo " edits and deletions"
|
|
mi_json PUT "/api/v1/statuses/$mi_post_id" "{\"status\":\"a Mitra post $run, edited\"}" >/dev/null
|
|
until_true 45 '[ "$(p_status $mi_on_p_post content | grep -c edited)" = "1" ]' && ok "mitrauser's edit reaches PrivaPub" || ko "mitrauser's edit never arrived"
|
|
curl -s -o /dev/null -X PUT -H "$PH" "$P/api/v1/statuses/$p_post_id" -d "status=a PrivaPub post for Mitra $run, edited"
|
|
until_true 45 '[ "$(mi_status_of $p_on_mi | j "print(\"edited\" in d[\"content\"])")" = "True" ]' && ok "alice's edit reaches Mitra" || ko "alice's edit never reached Mitra"
|
|
gone=$(mi_json POST /api/v1/statuses "{\"status\":\"a Mitra post to delete $run\",\"visibility\":\"public\"}" | j "print(d['id'])")
|
|
until_true 45 '[ -n "$(p_home_has "a Mitra post to delete $run")" ]'
|
|
gone_on_p=$(p_home_has "a Mitra post to delete $run")
|
|
mi -o /dev/null -X DELETE "$MI/api/v1/statuses/$gone"
|
|
until_true 45 '[ "$(curl -s -o /dev/null -w "%{http_code}" -H "$PH" "$P/api/v1/statuses/$gone_on_p")" = "404" ]' \
|
|
&& ok "mitrauser's deletion reaches PrivaPub" || ko "mitrauser's deleted post still shows on PrivaPub"
|
|
curl -s -o /dev/null -X DELETE -H "$PH" "$P/api/v1/statuses/$p_post_id"
|
|
until_true 45 '[ "$(mi -o /dev/null -w "%{http_code}" "$MI/api/v1/statuses/$p_on_mi")" = "404" ]' \
|
|
&& ok "alice's deletion reaches Mitra" || ko "alice's deleted post still on Mitra"
|
|
|
|
echo " direct messages"
|
|
mi_json POST /api/v1/statuses "{\"status\":\"@alice_mitra@privapub.test a Mitra secret $run\",\"visibility\":\"direct\"}" >/dev/null
|
|
until_true 45 'curl -s -H "$PH" "$P/api/v1/conversations" | grep -q "a Mitra secret $run"' && ok "mitrauser's DM arrives" || ko "mitrauser's DM never arrived"
|
|
curl -s -o /dev/null -X POST -H "$PH" $P/api/v1/statuses -d "status=@mitrauser@mitra.test a PrivaPub secret $run&visibility=direct"
|
|
until_true 45 'mi "$MI/api/v1/timelines/direct" "$MI/api/v1/conversations" | grep -q "a PrivaPub secret $run"' && ok "alice's DM reaches Mitra" || ko "alice's DM never reached Mitra"
|
|
|
|
echo " unfollow"
|
|
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/accounts/$mi_on_p/unfollow"
|
|
until_true 45 '[ "$(mi "$MI/api/v1/accounts/relationships?id[]=$alice_on_mi" | j "print(d[0][\"followed_by\"])")" = "False" ]' \
|
|
&& ok "alice's unfollow reaches Mitra" || ko "Mitra still counts alice as a follower"
|
|
|
|
echo " statistics"
|
|
stats_check mitra.test mitra
|