Files
timi/scicam_api_test.sh

271 lines
8.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# SciCam Logger API Client Test Suite
# Usage: ./scicam_api_test.sh <device-ip>
IP=${1:-}
if [ -z "$IP" ]; then
echo "Usage: $0 <device-ip>"
echo "Example: $0 192.168.1.42"
exit 1
fi
BASE="http://${IP}:8080"
PASS=0
FAIL=0
# Helper functions
ok() { echo " [PASS] $1"; ((PASS+=1)) || true; }
err() { echo " [FAIL] $1"; ((FAIL+=1)) || true; }
req() {
local method=$1 endpoint=$2 extra_args="${3:-}"
local url="${BASE}${endpoint}"
if [ -n "$extra_args" ]; then
curl -s -w "\n%{http_code}" -X "$method" $extra_args "$url"
else
curl -s -w "\n%{http_code}" -X "$method" "$url"
fi
}
echo "========================================"
echo "SciCam API Client Tests"
echo "Target: $BASE"
echo "========================================"
echo
# Test 1: GET /api
echo "Test 1: GET /api (metadata)"
RESPONSE=$(req GET "/api")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ] && echo "$BODY" | grep -q '"name":"SciCam API"'; then
ok "Returns 200 with API metadata"
else
err "Expected 200 + API metadata, got HTTP $CODE / $BODY"
fi
echo
# Test 2: GET /status
echo "Test 2: GET /status (current state)"
RESPONSE=$(req GET "/status")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ] && echo "$BODY" | grep -q '"item_id"'; then
ok "Returns 200 with status fields"
else
err "Expected 200 + status JSON, got HTTP $CODE / $BODY"
fi
echo
# Test 3: POST /settings - set item_id and tags
echo "Test 3: POST /settings (update metadata)"
RESPONSE=$(req POST "/settings" "-H Content-Type:application/json -d {\"item_id\":\"API-TEST-001\",\"tags\":\"api-test,client\"}")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ] && echo "$BODY" | grep -q '"item_id":"API-TEST-001"'; then
ok "Returns 200 and reflects updated item_id"
else
err "Expected 200 + updated state, got HTTP $CODE / $BODY"
fi
echo
# Test 4: POST /settings - toggle lock
echo "Test 4: POST /settings (toggle AE/AWB lock)"
RESPONSE=$(req POST "/settings" "-H Content-Type:application/json -d {\"lock\":true}")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ] && echo "$BODY" | grep -q '"locked":true'; then
ok "Returns 200 and lock is true"
else
err "Expected 200 + locked=true, got HTTP $CODE / $BODY"
fi
# Unlock for subsequent tests
req POST "/settings" "-H Content-Type:application/json -d {\"lock\":false}" >/dev/null
ok "Unlocked AE/AWB after test"
echo
# Test 5: POST /capture
echo "Test 5: POST /capture (trigger photo)"
RESPONSE=$(req POST "/capture" "--max-time 15")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ] && echo "$BODY" | grep -q '"success":true'; then
ok "Returns 200 and capture succeeded"
elif echo "$BODY" | grep -q '"error":"Camera not ready"'; then
err "Camera not ready (may need a few seconds after app launch)"
else
err "Expected 200 + success, got HTTP $CODE / $BODY"
fi
echo
# Test 6: GET /capture should return 404
echo "Test 6: GET /capture (wrong method)"
RESPONSE=$(req GET "/capture")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "404" ] || [ "$CODE" = "405" ]; then
ok "Returns 404/405 for GET as expected"
else
err "Expected 404/405 for GET /capture, got HTTP $CODE"
fi
echo
# Test 7: POST /api should return 404
echo "Test 7: POST /api (wrong method)"
RESPONSE=$(req POST "/api")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "404" ] || [ "$CODE" = "405" ]; then
ok "Returns 404/405 for POST as expected"
else
err "Expected 404/405 for POST /api, got HTTP $CODE"
fi
echo
# Test 8: Verify status after capture
echo "Test 8: GET /status (verify last_capture populated)"
RESPONSE=$(req GET "/status")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ] && echo "$BODY" | grep -q '"last_capture"'; then
ok "Returns 200 with last_capture field"
else
err "Expected 200 + last_capture, got HTTP $CODE / $BODY"
fi
echo
# Test 9: POST /auto-capture enable
echo "Test 9: POST /auto-capture (enable)"
RESPONSE=$(req POST "/auto-capture" "-H Content-Type:application/json -d {\"enabled\":true}")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ] && echo "$BODY" | grep -q '"auto_capture":true'; then
ok "Returns 200 and auto_capture is true"
else
err "Expected 200 + auto_capture=true, got HTTP $CODE / $BODY"
fi
echo
# Test 10: POST /auto-capture disable
echo "Test 10: POST /auto-capture (disable)"
RESPONSE=$(req POST "/auto-capture" "-H Content-Type:application/json -d {\"enabled\":false}")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ] && echo "$BODY" | grep -q '"auto_capture":false'; then
ok "Returns 200 and auto_capture is false"
else
err "Expected 200 + auto_capture=false, got HTTP $CODE / $BODY"
fi
echo
# Test 11: GET /auto-capture should return 404
echo "Test 11: GET /auto-capture (wrong method)"
RESPONSE=$(req GET "/auto-capture")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "404" ] || [ "$CODE" = "405" ]; then
ok "Returns 404/405 for GET as expected"
else
err "Expected 404/405 for GET /auto-capture, got HTTP $CODE"
fi
echo
# Test 12: GET /photo/last should return 404 when no capture exists yet or a photo if capture succeeded
# Note: If Test 5 passed, a photo exists and /photo/last should return 200. If Test 5 failed, 404 is expected.
echo "Test 12: GET /photo/last (download most recent photo)"
RESPONSE=$(curl -s -w "\n%{http_code}" -X GET "${BASE}/photo/last")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ]; then
# Content-Type should be image/jpeg; we only have headers here because -o wasn't used,
# but we can verify it's not HTML/error text by checking length.
if [ "${#BODY}" -gt 100 ]; then
ok "Returns 200 and non-empty body for /photo/last"
else
err "Body too short for a JPEG"
fi
elif [ "$CODE" = "404" ]; then
ok "Returns 404 when no last capture exists"
else
err "Expected 200 or 404 for GET /photo/last, got HTTP $CODE"
fi
echo
# Test 13: GET /photo/<filename> for specific filename
# We attempt with the filename returned by the last capture if any.
echo "Test 13: GET /photo/<filename> (download specific photo)"
FILENAME=$(echo "$RESPONSE" | jq -r '.filename' 2>/dev/null || echo "")
if [ -z "$FILENAME" ] || [ "$CODE" = "404" ]; then
# No filename available from capture result; try a dummy file -> expect 404
RESPONSE_B=$(curl -s -w "\n%{http_code}" -X GET "${BASE}/photo/nonexistent.jpg")
CODE_B=$(echo "$RESPONSE_B" | tail -n1)
if [ "$CODE_B" = "404" ]; then
ok "Returns 404 for nonexistent filename"
else
err "Expected 404 for nonexistent photo, got HTTP $CODE_B"
fi
else
RESPONSE_B=$(curl -s -w "\n%{http_code}" -X GET "${BASE}/photo/${FILENAME}")
CODE_B=$(echo "$RESPONSE_B" | tail -n1)
if [ "$CODE_B" = "200" ]; then
ok "Returns 200 for known filename"
else
err "Expected 200 for known filename, got HTTP $CODE_B"
fi
fi
echo
# Test 14: GET /events (SSE endpoint)
echo "Test 14: GET /events (SSE endpoint)"
# Start background SSE listener and redirect to file
curl -s -N -o /tmp/sse_test.txt "${BASE}/events" &
EVENT_PID=$!
sleep 1
# Trigger capture to produce an event
curl -s -X POST --max-time 15 "${BASE}/capture" > /dev/null
sleep 2
kill $EVENT_PID 2>/dev/null || true
if grep -q "data:" /tmp/sse_test.txt; then
ok "SSE received event data"
else
err "SSE did not receive event data"
fi
echo
# Test 15: POST /photo should return 404 (wrong method)
echo "Test 15: POST /photo/last (wrong method)"
RESPONSE=$(req POST "/photo/last")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "404" ] || [ "$CODE" = "405" ]; then
ok "Returns 404/405 for POST as expected"
else
err "Expected 404/405 for POST /photo/last, got HTTP $CODE"
fi
echo
# Test 15: POST /settings toggle debug overlay
echo "Test 12: POST /settings (toggle debug overlay)"
RESPONSE=$(req POST "/settings" "-H Content-Type:application/json -d {\"debug\":true}")
BODY=$(echo "$RESPONSE" | sed '$d')
CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$CODE" = "200" ] && echo "$BODY" | grep -q '"debug":true'; then
ok "Returns 200 and debug is true"
else
err "Expected 200 + debug=true, got HTTP $CODE / $BODY"
fi
# Reset debug to false for clean state
req POST "/settings" "-H Content-Type:application/json -d {\"debug\":false}" >/dev/null
ok "Reset debug to false after test"
echo
echo "========================================"
echo "Results: $PASS passed, $FAIL failed"
echo "========================================"
if [ "$FAIL" -gt 0 ]; then
exit 1
fi