# Gancio 1.28.2: its instance actor `relay` (an Application) publishes the agenda. alice_gancio follows it; an event # arrives as an Event with its start, end and place; its edit and its deletion; alice's reply kept as one of the event's # resources; the unfollow. Its API takes a bearer token from an OAuth password grant (client_id self); what it holds is # read from a copy of its sqlite. GC=https://gancio.test:6443 gc() { curl -sk --resolve gancio.test:6443:127.0.0.1 -H "Authorization: Bearer $GCT" "$@"; } # gc_sql : one value from Gancio's sqlite, copied out gc_sql() { podman cp pasture-gancio:/home/node/data/gancio.sqlite "$here/.state/gancio.sqlite" 2>/dev/null python3 -c 'import sqlite3, sys; r = sqlite3.connect(sys.argv[1]).execute(sys.argv[2]).fetchone(); print("" if r is None else r[0])' \ "$here/.state/gancio.sqlite" "$1" } p_home_has() { 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 "gancio" [ -s "$here/.state/gancio.token" ] && ok "Gancio credentials for gcadmin" || { ko "Gancio credentials"; return 1; } credentials=$(cat "$here/.state/gancio.token") GCT=$(curl -sk --resolve gancio.test:6443:127.0.0.1 -X POST "$GC/oauth/login" --data-urlencode grant_type=password \ --data-urlencode client_id=self --data-urlencode "username=${credentials%%:*}" --data-urlencode "password=${credentials#*:}" | j "print(d['access_token'])") [ -n "$GCT" ] && ok "gcadmin signs in to Gancio's API" || { ko "gcadmin cannot sign in"; return 1; } PT=$(privapub_token alice_gancio) PH="Authorization: Bearer $PT" [ -n "$PT" ] && ok "PrivaPub token for alice_gancio" || { ko "PrivaPub token for alice_gancio"; return 1; } echo " the agenda and its follower" relay_on_p=$(curl -s -H "$PH" "$P/api/v2/search?q=relay@gancio.test&resolve=true&type=accounts" | j "print(d['accounts'][0]['id'])") [ -n "$relay_on_p" ] && ok "PrivaPub resolves @relay@gancio.test" || ko "PrivaPub cannot resolve Gancio's actor" # a run before this one left the follow: unfollow first, so the follow below is a new request curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/accounts/$relay_on_p/unfollow"; sleep 3 curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/accounts/$relay_on_p/follow" until_true 45 '[ "$(curl -s -H "$PH" "$P/api/v1/accounts/relationships?id[]=$relay_on_p" | j "print(d[0][\"following\"])")" = "True" ]' \ && ok "alice_gancio follows Gancio's agenda (Accept arrived)" || ko "Gancio's Accept never arrived" echo " events" title="A concert in the pasture $(date +%s)" begins=$(date -u -d '+4 days 20:00' +%s); ends=$(date -u -d '+4 days 23:00' +%s) # (--form-string: with -F a value starting with "<" names a file to read) event=$(gc -X POST "$GC/api/event" --form-string "title=$title" --form-string "description=

bring a blanket

" -F "start_datetime=$begins" \ -F "end_datetime=$ends" -F "place_name=Villa Borghese" -F "place_address=Roma" -F "place_latitude=41.9142" -F "place_longitude=12.4922") event_id=$(echo "$event" | j "print(d['id'])") [ -n "$event_id" ] && ok "gcadmin publishes an event" || ko "the event could not be made: $(echo "$event" | cut -c1-200)" until_true 60 '[ -n "$(p_home_has "$title")" ]' && ok "the event reaches alice_gancio's home" || ko "the event never arrived" e_on_p=$(p_home_has "$title") event_json=$(curl -s -H "$PH" "$P/api/v1/statuses/$e_on_p") [ "$(echo "$event_json" | j "e = (d.get('privapub') or {}).get('event') or {}; print(e.get('start', '')[:16], e.get('end', '')[:16])")" \ = "$(date -u -d "@$begins" +%Y-%m-%dT%H:%M) $(date -u -d "@$ends" +%Y-%m-%dT%H:%M)" ] \ && ok "it arrives as an event with its start and end" || ko "the event's dates are missing ($(echo "$event_json" | j "print((d.get('privapub') or {}).get('event'))"))" echo "$event_json" | j "e = (d.get('privapub') or {}).get('event') or {}; print(any('Borghese' in ((p.get('name') or '') + (p.get('address') or '')) for p in e.get('places', [])))" | grep -q True \ && ok "and with its place" || ko "the event's place is missing" echo " replies" curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/statuses" -d "status=@relay@gancio.test see you at the concert&in_reply_to_id=$e_on_p&visibility=public" until_true 45 '[ "$(gc_sql "select count(*) from resources where data like '"'%see you at the concert%'"'")" -ge 1 ]' \ && ok "alice_gancio's reply is kept as one of the event's resources" || ko "the reply never reached Gancio" echo " edits and deletes" gc -o /dev/null -X PUT "$GC/api/event" -F "id=$event_id" --form-string "title=$title, moved indoors" -F "start_datetime=$begins" -F "end_datetime=$ends" \ -F "place_name=Villa Borghese" -F "place_address=Roma" until_true 45 'curl -s -H "$PH" "$P/api/v1/statuses/$e_on_p" | grep -q "moved indoors"' && ok "the event's edit reaches PrivaPub" || ko "the event's edit not applied" gc -o /dev/null -X DELETE "$GC/api/event/$event_id" until_true 45 '[ "$(curl -s -o /dev/null -w "%{http_code}" -H "$PH" "$P/api/v1/statuses/$e_on_p")" = "404" ]' \ && ok "the deleted event leaves PrivaPub" || ko "the deleted event stays on PrivaPub" echo " unfollow" curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/accounts/$relay_on_p/unfollow" until_true 45 '[ "$(gc_sql "select count(*) from ap_users where ap_id like '"'%alice_gancio%'"' and follower = 1")" = "0" ]' \ && ok "alice_gancio's unfollow reaches Gancio" || ko "Gancio still counts alice_gancio as a follower" echo " statistics" stats_check gancio.test gancio