306 lines
9.8 KiB
Bash
Executable File
306 lines
9.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# BUD-09 Blob Report Test Suite
|
|
# This test is created FIRST (TDD) and will FAIL until implementation is added to src/main.c.
|
|
#
|
|
# Expected implementation in src/main.c (BUD-09 section):
|
|
# - handle_report_request() -> Parse and validate NIP-56 kind 1984 report events
|
|
# - validate_report_event() -> Verify event structure, signature, and required tags
|
|
# - process_blob_report() -> Store report, optionally take action on reported blobs
|
|
# - report_get_blob_hashes() -> Extract SHA-256 hashes from x tags
|
|
# - report_validate_hash() -> Validate SHA-256 format in x tags
|
|
#
|
|
# Integration points expected:
|
|
# - PUT /report endpoint accepts NIP-56 report events
|
|
# - Server validates event structure and signatures
|
|
# - Server responds with appropriate HTTP status codes
|
|
#
|
|
# Requirements:
|
|
# - curl, jq, nak (nostr army knife) must be available
|
|
# - Server should be running at http://localhost:9001 (restart-all.sh)
|
|
|
|
set -e
|
|
|
|
SERVER_URL="http://localhost:9001"
|
|
REPORT_ENDPOINT="${SERVER_URL}/report"
|
|
WORKDIR="tests/tmp_bud09"
|
|
|
|
# Test counters
|
|
TESTS_TOTAL=0
|
|
TESTS_PASSED=0
|
|
TESTS_FAILED=0
|
|
|
|
echo "=== BUD-09 Blob Report Test Suite ==="
|
|
|
|
# Prereq checks
|
|
if ! command -v curl >/dev/null 2>&1; then
|
|
echo "ERROR: curl not found"
|
|
exit 1
|
|
fi
|
|
if ! command -v jq >/dev/null 2>&1; then
|
|
echo "ERROR: jq not found (required for JSON parsing)"
|
|
exit 1
|
|
fi
|
|
if ! command -v nak >/dev/null 2>&1; then
|
|
echo "ERROR: nak not found (required for nostr event generation)"
|
|
echo "Install with: go install github.com/fiatjaf/nak@latest"
|
|
exit 1
|
|
fi
|
|
|
|
# Helper functions
|
|
log_test() {
|
|
echo ""
|
|
echo "=== Test $1: $2 ==="
|
|
TESTS_TOTAL=$((TESTS_TOTAL + 1))
|
|
}
|
|
|
|
validate_response() {
|
|
local response="$1"
|
|
local expected_code="$2"
|
|
local test_name="$3"
|
|
|
|
local http_code=$(echo "$response" | tail -n1 | grep "HTTP_CODE:" | cut -d: -f2)
|
|
|
|
if [ "$http_code" = "$expected_code" ]; then
|
|
echo "✅ $test_name PASSED (HTTP $http_code)"
|
|
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
else
|
|
echo "❌ $test_name FAILED (Expected HTTP $expected_code, got $http_code)"
|
|
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
fi
|
|
|
|
# Show response body for debugging
|
|
local body=$(echo "$response" | head -n -1)
|
|
if [ -n "$body" ]; then
|
|
echo "Response: $body"
|
|
fi
|
|
}
|
|
|
|
generate_report_event() {
|
|
local blob_hash="$1"
|
|
local report_type="$2"
|
|
local content="$3"
|
|
|
|
nak event -k 1984 -c "$content" -t "x=$blob_hash;$report_type"
|
|
}
|
|
|
|
generate_multi_report_event() {
|
|
local content="$1"
|
|
shift
|
|
local tags=""
|
|
|
|
for arg in "$@"; do
|
|
local hash=$(echo "$arg" | cut -d'=' -f1)
|
|
local type=$(echo "$arg" | cut -d'=' -f2)
|
|
tags="$tags -t x=$hash;$type"
|
|
done
|
|
|
|
nak event -k 1984 -c "$content" $tags
|
|
}
|
|
|
|
submit_report() {
|
|
local event_json="$1"
|
|
|
|
curl -s -w "\nHTTP_CODE:%{http_code}\n" \
|
|
-X PUT \
|
|
-H "Content-Type: application/json" \
|
|
-d "$event_json" \
|
|
"$REPORT_ENDPOINT"
|
|
}
|
|
|
|
# Create temporary working directory
|
|
mkdir -p "$WORKDIR"
|
|
|
|
# Test data - valid SHA-256 hashes
|
|
HASH1="deadbeefcafebabe0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
HASH2="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
HASH3="abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
|
|
INVALID_HASH="invalid_hash_format"
|
|
|
|
echo ""
|
|
echo "Test Configuration:"
|
|
echo " Server: $SERVER_URL"
|
|
echo " Report endpoint: $REPORT_ENDPOINT"
|
|
echo " Working directory: $WORKDIR"
|
|
echo " Test hashes: $HASH1, $HASH2, $HASH3"
|
|
|
|
# Test 1: Valid Single Blob Report (nudity)
|
|
log_test 1 "Valid Single Blob Report (nudity)"
|
|
EVENT1=$(generate_report_event "$HASH1" "nudity" "This image contains inappropriate content")
|
|
echo "Event: $EVENT1"
|
|
RESPONSE1=$(submit_report "$EVENT1")
|
|
validate_response "$RESPONSE1" "200" "Test 1"
|
|
|
|
# Test 2: Multiple Blob Report (malware)
|
|
log_test 2 "Multiple Blob Report (malware)"
|
|
EVENT2=$(generate_multi_report_event "Multiple files contain malware" "${HASH1}=malware" "${HASH2}=malware")
|
|
echo "Event: $EVENT2"
|
|
RESPONSE2=$(submit_report "$EVENT2")
|
|
validate_response "$RESPONSE2" "200" "Test 2"
|
|
|
|
# Test 3: Report Types Coverage - nudity
|
|
log_test 3a "Report Type: nudity"
|
|
EVENT3A=$(generate_report_event "$HASH1" "nudity" "Nudity content reported")
|
|
RESPONSE3A=$(submit_report "$EVENT3A")
|
|
validate_response "$RESPONSE3A" "200" "Test 3a (nudity)"
|
|
|
|
# Test 3: Report Types Coverage - malware
|
|
log_test 3b "Report Type: malware"
|
|
EVENT3B=$(generate_report_event "$HASH2" "malware" "Malware content reported")
|
|
RESPONSE3B=$(submit_report "$EVENT3B")
|
|
validate_response "$RESPONSE3B" "200" "Test 3b (malware)"
|
|
|
|
# Test 3: Report Types Coverage - profanity
|
|
log_test 3c "Report Type: profanity"
|
|
EVENT3C=$(generate_report_event "$HASH3" "profanity" "Profanity content reported")
|
|
RESPONSE3C=$(submit_report "$EVENT3C")
|
|
validate_response "$RESPONSE3C" "200" "Test 3c (profanity)"
|
|
|
|
# Test 3: Report Types Coverage - illegal
|
|
log_test 3d "Report Type: illegal"
|
|
EVENT3D=$(generate_report_event "$HASH1" "illegal" "Illegal content reported")
|
|
RESPONSE3D=$(submit_report "$EVENT3D")
|
|
validate_response "$RESPONSE3D" "200" "Test 3d (illegal)"
|
|
|
|
# Test 3: Report Types Coverage - spam
|
|
log_test 3e "Report Type: spam"
|
|
EVENT3E=$(generate_report_event "$HASH2" "spam" "Spam content reported")
|
|
RESPONSE3E=$(submit_report "$EVENT3E")
|
|
validate_response "$RESPONSE3E" "200" "Test 3e (spam)"
|
|
|
|
# Test 3: Report Types Coverage - impersonation
|
|
log_test 3f "Report Type: impersonation"
|
|
EVENT3F=$(generate_report_event "$HASH3" "impersonation" "Impersonation content reported")
|
|
RESPONSE3F=$(submit_report "$EVENT3F")
|
|
validate_response "$RESPONSE3F" "200" "Test 3f (impersonation)"
|
|
|
|
# Test 3: Report Types Coverage - other
|
|
log_test 3g "Report Type: other"
|
|
EVENT3G=$(generate_report_event "$HASH1" "other" "Other type of inappropriate content")
|
|
RESPONSE3G=$(submit_report "$EVENT3G")
|
|
validate_response "$RESPONSE3G" "200" "Test 3g (other)"
|
|
|
|
# Test 4: Report with Optional Tags (comprehensive NIP-56 structure)
|
|
log_test 4 "Report with Optional Tags"
|
|
EVENT4=$(nak event -k 1984 -c "Comprehensive report with all tags" \
|
|
-t "x=${HASH1};spam" \
|
|
-t "e=1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" \
|
|
-t "p=abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" \
|
|
-t "server=https://example.com/blob.jpg")
|
|
echo "Event: $EVENT4"
|
|
RESPONSE4=$(submit_report "$EVENT4")
|
|
validate_response "$RESPONSE4" "200" "Test 4"
|
|
|
|
# Test 5: Missing x Tags Error
|
|
log_test 5 "Missing x Tags Error"
|
|
EVENT5=$(nak event -k 1984 -c "Report without x tags" -t "p=somekey")
|
|
echo "Event: $EVENT5"
|
|
RESPONSE5=$(submit_report "$EVENT5")
|
|
validate_response "$RESPONSE5" "400" "Test 5"
|
|
|
|
# Test 6: Invalid SHA-256 Format
|
|
log_test 6 "Invalid SHA-256 Format"
|
|
EVENT6=$(generate_report_event "$INVALID_HASH" "nudity" "Invalid hash format test")
|
|
echo "Event: $EVENT6"
|
|
RESPONSE6=$(submit_report "$EVENT6")
|
|
validate_response "$RESPONSE6" "400" "Test 6"
|
|
|
|
# Test 7: Wrong Event Kind
|
|
log_test 7 "Wrong Event Kind"
|
|
EVENT7=$(nak event -k 1 -c "Wrong kind test" -t "x=${HASH1};nudity")
|
|
echo "Event: $EVENT7"
|
|
RESPONSE7=$(submit_report "$EVENT7")
|
|
validate_response "$RESPONSE7" "400" "Test 7"
|
|
|
|
# Test 8: Invalid JSON Structure
|
|
log_test 8 "Invalid JSON Structure"
|
|
INVALID_JSON='{"invalid":"json","missing":}'
|
|
echo "Invalid JSON: $INVALID_JSON"
|
|
RESPONSE8=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
|
|
-X PUT \
|
|
-H "Content-Type: application/json" \
|
|
-d "$INVALID_JSON" \
|
|
"$REPORT_ENDPOINT")
|
|
validate_response "$RESPONSE8" "400" "Test 8"
|
|
|
|
# Test 9: Unsupported HTTP Method - GET
|
|
log_test 9a "Unsupported Method: GET"
|
|
RESPONSE9A=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
|
|
-X GET \
|
|
"$REPORT_ENDPOINT")
|
|
validate_response "$RESPONSE9A" "405" "Test 9a (GET)"
|
|
|
|
# Test 9: Unsupported HTTP Method - POST
|
|
log_test 9b "Unsupported Method: POST"
|
|
RESPONSE9B=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
|
|
-X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"test":"post"}' \
|
|
"$REPORT_ENDPOINT")
|
|
validate_response "$RESPONSE9B" "405" "Test 9b (POST)"
|
|
|
|
# Test 9: Unsupported HTTP Method - DELETE
|
|
log_test 9c "Unsupported Method: DELETE"
|
|
RESPONSE9C=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
|
|
-X DELETE \
|
|
"$REPORT_ENDPOINT")
|
|
validate_response "$RESPONSE9C" "405" "Test 9c (DELETE)"
|
|
|
|
# Test 10: Empty Request Body
|
|
log_test 10 "Empty Request Body"
|
|
RESPONSE10=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
|
|
-X PUT \
|
|
-H "Content-Type: application/json" \
|
|
"$REPORT_ENDPOINT")
|
|
validate_response "$RESPONSE10" "400" "Test 10"
|
|
|
|
# Test 11: Unknown Report Type (should be accepted per spec)
|
|
log_test 11 "Unknown Report Type"
|
|
EVENT11=$(generate_report_event "$HASH1" "unknown_type" "Unknown report type test")
|
|
echo "Event: $EVENT11"
|
|
RESPONSE11=$(submit_report "$EVENT11")
|
|
validate_response "$RESPONSE11" "200" "Test 11"
|
|
|
|
# Test 12: Invalid Content-Type
|
|
log_test 12 "Invalid Content-Type"
|
|
EVENT12=$(generate_report_event "$HASH1" "nudity" "Content type test")
|
|
RESPONSE12=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
|
|
-X PUT \
|
|
-H "Content-Type: text/plain" \
|
|
-d "$EVENT12" \
|
|
"$REPORT_ENDPOINT")
|
|
validate_response "$RESPONSE12" "415" "Test 12"
|
|
|
|
# Test 13: Valid report with empty content field
|
|
log_test 13 "Empty Content Field"
|
|
EVENT13=$(generate_report_event "$HASH1" "spam" "")
|
|
echo "Event: $EVENT13"
|
|
RESPONSE13=$(submit_report "$EVENT13")
|
|
validate_response "$RESPONSE13" "200" "Test 13"
|
|
|
|
# Test 14: Very long content field
|
|
log_test 14 "Long Content Field"
|
|
LONG_CONTENT=$(printf 'A%.0s' {1..1000})
|
|
EVENT14=$(generate_report_event "$HASH1" "other" "$LONG_CONTENT")
|
|
RESPONSE14=$(submit_report "$EVENT14")
|
|
validate_response "$RESPONSE14" "200" "Test 14"
|
|
|
|
# Cleanup
|
|
rm -rf "$WORKDIR"
|
|
|
|
# Test Summary
|
|
echo ""
|
|
echo "=== BUD-09 Test Summary ==="
|
|
echo "Total tests: $TESTS_TOTAL"
|
|
echo "Passed: $TESTS_PASSED"
|
|
echo "Failed: $TESTS_FAILED"
|
|
echo ""
|
|
|
|
if [ "$TESTS_FAILED" -eq 0 ]; then
|
|
echo "🎉 All tests passed! BUD-09 implementation is working correctly."
|
|
exit 0
|
|
else
|
|
echo "❌ $TESTS_FAILED test(s) failed. BUD-09 implementation needs fixes."
|
|
exit 1
|
|
fi
|
|
|
|
echo "=== End of BUD-09 Blob Report Test Suite ===" |