Files
wx-win-agent/docs/validation/raw/cursor-http-transcript.sh
T

60 lines
3.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
binary=${CONTROL_PLANE_BIN:-./control-plane}
work=$(mktemp -d)
port=${P4_CURSOR_PORT:-18091}
addr="127.0.0.1:${port}"
base="http://${addr}"
cleanup() { [[ -n "${pid:-}" ]] && kill "$pid" 2>/dev/null || true; rm -rf "$work"; }
trap cleanup EXIT
WXAGENT_CONTROL_PLANE_ADDR="$addr" \
WXAGENT_CONTROL_PLANE_DATA="$work/control-plane.json" \
WXAGENT_CONTROL_PLANE_BACKUP_DIR="$work/backups" \
WXAGENT_NODE_ID=node-cursor \
WXAGENT_NODE_TOKEN=node-cursor-token \
WXAGENT_WEB_USER=admin \
WXAGENT_WEB_PASSWORD=fixture-password \
"$binary" >"$work/server.log" 2>&1 &
pid=$!
for _ in $(seq 1 40); do code=$(curl -sS -o /dev/null -w '%{http_code}' "$base/v1/auth/login" || true); [[ "$code" != "000" ]] && break; sleep .1; done
curl -fsS -X POST "$base/v1/nodes/register" \
-H 'Authorization: Bearer node-cursor-token' -H 'Content-Type: application/json' \
-d '{"node_id":"node-cursor","connection_id":"connection-cursor","agent_version":"fixture","protocol_version":"v1","capabilities":["sync-data"],"accounts":[{"account_id":"account-cursor","active":true,"verified":true,"allowed_chats":[{"chat_id":"chat-cursor","chat_type":"Private"}]}]}' >/dev/null
token=$(curl -fsS -X POST "$base/v1/auth/login" -H 'Content-Type: application/json' \
-d '{"username":"admin","password":"fixture-password"}' | jq -r .access_token)
post_batch() {
local batch_id=$1 sequence=$2 payload=$3 messages
if [[ $sequence == 1 ]]; then
messages='[{"message_id":"message-2","chat_id":"chat-cursor","chat_type":"Private","source_message_id":"source-2","direction":"incoming","message_type":"text","text":"fixture-two","source_time":"2026-01-01T00:00:02Z","observed_at":"2026-01-01T00:00:02Z","source_version":"fixture","payload_hash":"message-hash-2"},{"message_id":"message-1","chat_id":"chat-cursor","chat_type":"Private","source_message_id":"source-1","direction":"incoming","message_type":"text","text":"fixture-one","source_time":"2026-01-01T00:00:01Z","observed_at":"2026-01-01T00:00:01Z","source_version":"fixture","payload_hash":"message-hash-1"}]'
else
messages='[{"message_id":"message-3","chat_id":"chat-cursor","chat_type":"Private","source_message_id":"source-3","direction":"incoming","message_type":"text","text":"fixture-newer","source_time":"2026-01-01T00:00:03Z","observed_at":"2026-01-01T00:00:03Z","source_version":"fixture","payload_hash":"message-hash-3"}]'
fi
jq -n --arg batch "$batch_id" --arg payload "$payload" --argjson messages "$messages" \
--argjson sequence "$sequence" --argjson cursor_end "$((sequence+1))" \
'{node_id:"node-cursor",account_id:"account-cursor",batch_id:$batch,source_generation:"account-cursor",stream_key:"messages",sequence:$sequence,cursor_start:($sequence|tostring),cursor_end:($cursor_end|tostring),payload_hash:$payload,coverage_state:"complete",conversations:[],messages:$messages}' |
curl -fsS -X POST "$base/v1/data/batches" \
-H 'Authorization: Bearer node-cursor-token' -H 'Content-Type: application/json' --data-binary @- >/dev/null
}
request_page() {
local label=$1 url=$2
local body="$work/$label.json" status
status=$(curl -fsS -o "$body" -w '%{http_code}' "$url" -H "Authorization: Bearer $token")
echo "REQUEST $label GET $url"
echo "HTTP $status"
jq '{items:[.items[]|{message_id,source_time,text}],limit,has_more,next_cursor}' "$body"
}
post_batch batch-cursor-1 1 payload-cursor-1
first_url="$base/v1/data/accounts/account-cursor/messages?chat_id=chat-cursor&limit=1"
request_page first "$first_url"
cursor=$(jq -r .next_cursor "$work/first.json")
post_batch batch-cursor-2 2 payload-cursor-2
second_url="$base/v1/data/accounts/account-cursor/messages?chat_id=chat-cursor&limit=10&cursor=$(python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=""))' "$cursor")"
request_page second "$second_url"