test: smoke coverage for search, private messages, webhook/SSO
The fake smoke Discourse now serves /search.json (title substring matches over created topics), accepts private-message creation on POST /posts.json (targets comma-joined on the wire, deliveries recorded and exposed via /__pms.json), and the smoke script drives the real CLI through it: search hits, PM send + recipient assertion, webhook verify with a python-computed HMAC (good sig exits 0, bad sig exits 2 with the typed message), and sso verify decoding a signed Discourse Connect payload (tamper case exits 2). No live forum is contacted. Part of Redmine 507 (Discourse Go client).
This commit is contained in:
@@ -96,6 +96,38 @@ CLI posts update "$POST_ID" -raw "edited body" -reason smoke | tee -a "$capture"
|
||||
echo "--- raw passthrough"
|
||||
CLI raw GET /latest.json | tee -a "$capture" | grep -q '"topic_list"' || { echo "smoke: raw GET failed" >&2; exit 1; }
|
||||
|
||||
echo "--- search"
|
||||
CLI search "Smoke Topic" | tee -a "$capture" | grep -q '"Smoke Topic"' || { echo "smoke: search failed" >&2; exit 1; }
|
||||
|
||||
echo "--- private message send + delivery record"
|
||||
CLI messages send -title "Smoke PM" -to ops,reachableceo -raw "pm body" | tee -a "$capture" | grep -q '"topic_slug": "smoke-pm"' || { echo "smoke: PM send failed" >&2; exit 1; }
|
||||
CLI raw GET /__pms.json | tee -a "$capture" | grep -q '"target_usernames": "ops,reachableceo"' || { echo "smoke: PM recipients not recorded" >&2; exit 1; }
|
||||
|
||||
echo "--- webhook verify: good sig exits 0, bad sig exits 2"
|
||||
WHSEC="smoke-webhook-secret"
|
||||
printf '{"post":{"id":101}}' > .smoke/hook-body
|
||||
SIG=$(python3 -c 'import hmac,hashlib,sys; print("sha256="+hmac.new(sys.argv[1].encode(),open(sys.argv[2],"rb").read(),hashlib.sha256).hexdigest())' "$WHSEC" .smoke/hook-body)
|
||||
( set -a; DISCOURSE_WEBHOOK_SECRET="$WHSEC"; set +a; exec ./bin/discourse-go webhook verify "$SIG" ) < .smoke/hook-body >>"$capture" 2>&1 \
|
||||
|| { echo "smoke: webhook verify (good sig) failed" >&2; exit 1; }
|
||||
set +e
|
||||
( set -a; DISCOURSE_WEBHOOK_SECRET="$WHSEC"; set +a; exec ./bin/discourse-go webhook verify "sha256=deadbeef" ) < .smoke/hook-body >"$PWD/.smoke/badsig" 2>&1
|
||||
code=$?
|
||||
set -e
|
||||
if [ "$code" -ne 2 ]; then echo "smoke: bad webhook sig exit=$code want 2" >&2; exit 1; fi
|
||||
grep -q "bad signature" "$PWD/.smoke/badsig" || { echo "smoke: bad-signature message missing" >&2; exit 1; }
|
||||
|
||||
echo "--- sso verify: decoded payload + tamper rejection"
|
||||
SSOSEC="smoke-sso-secret"
|
||||
SSO=$(python3 -c 'import base64; print(base64.b64encode(b"nonce=smoke123&return_sso_url=https%3A%2F%2Fapp.test%2Fcb").decode())')
|
||||
SSIG=$(python3 -c 'import hmac,hashlib,sys; print(hmac.new(sys.argv[1].encode(),sys.argv[2].encode(),hashlib.sha256).hexdigest())' "$SSOSEC" "$SSO")
|
||||
( set -a; DISCOURSE_SSO_SECRET="$SSOSEC"; set +a; exec ./bin/discourse-go sso verify "$SSO" "$SSIG" ) | tee -a "$capture" | grep -q '"nonce": "smoke123"' \
|
||||
|| { echo "smoke: sso verify failed" >&2; exit 1; }
|
||||
set +e
|
||||
( set -a; DISCOURSE_SSO_SECRET="$SSOSEC"; set +a; exec ./bin/discourse-go sso verify "$SSO" "deadbeef" ) >/dev/null 2>&1
|
||||
code=$?
|
||||
set -e
|
||||
if [ "$code" -ne 2 ]; then echo "smoke: bad sso sig exit=$code want 2" >&2; exit 1; fi
|
||||
|
||||
echo "--- redaction: no key material in any captured output"
|
||||
if grep -q "$SMOKE_KEY" "$capture"; then
|
||||
echo "smoke: KEY LEAKED in output" >&2
|
||||
|
||||
Reference in New Issue
Block a user