#!/usr/bin/env bash set -euo pipefail # Manual end-to-end probe for the inventory endpoint's strict validation gate. # Each call below should return HTTP 400 with an `application/problem+json` # body whose `errors` map names the offending field path. Exactly one call # (the happy path) should return HTTP 200. # # Usage: # API_URL=https://localhost:8080 JWT="" ./scripts/probe_inventory_validation.sh # (defaults to https://localhost:8080 with a JWT minted via PerfBootstrap --mint-only) API_URL="${API_URL:-https://localhost:8080}" JWT="${JWT:-}" PATH_INV="${API_URL%/}/api/satellite/tiles/inventory" if [[ -z "${JWT}" ]]; then echo "ERROR: set JWT env var to a bearer token. Mint one via:" echo " dotnet run --project SatelliteProvider.IntegrationTests -- --mint-only" exit 2 fi curl_args=(-sS -k -H "Authorization: Bearer ${JWT}" -H "Content-Type: application/json" -X POST "${PATH_INV}") probe() { local label="$1" local body="$2" local expected_status="$3" echo "----- ${label} (expecting HTTP ${expected_status}) -----" local response response=$(curl "${curl_args[@]}" -d "${body}" -w "\nHTTP_STATUS=%{http_code}\n") echo "${response}" local actual_status actual_status=$(echo "${response}" | tail -n 1 | sed 's/HTTP_STATUS=//') if [[ "${actual_status}" != "${expected_status}" ]]; then echo "FAIL: expected HTTP ${expected_status}, got ${actual_status}" return 1 fi echo "OK: HTTP ${expected_status}" echo } probe "happy-path" '{"tiles":[{"z":18,"x":1,"y":1}]}' 200 probe "missing-z" '{"tiles":[{"x":1,"y":1}]}' 400 probe "missing-x-and-y" '{"tiles":[{"z":18}]}' 400 probe "zoom-out-of-range" '{"tiles":[{"z":30,"x":0,"y":0}]}' 400 probe "x-beyond-zoom-bounds" '{"tiles":[{"z":2,"x":4,"y":0}]}' 400 probe "y-beyond-zoom-bounds" '{"tiles":[{"z":0,"x":0,"y":1}]}' 400 probe "negative-x" '{"tiles":[{"z":18,"x":-1,"y":0}]}' 400 probe "unknown-root-field" '{"unknownField":42,"tiles":[{"z":18,"x":1,"y":1}]}' 400 probe "unknown-nested-field" '{"tiles":[{"z":18,"x":1,"y":1,"foo":42}]}' 400 probe "legacy-v1-field-name" '{"tiles":[{"tileZoom":18,"tileX":1,"tileY":1}]}' 400 probe "type-mismatch-string" '{"tiles":[{"z":"eighteen","x":1,"y":1}]}' 400 probe "both-populated-xor" '{"tiles":[{"z":18,"x":1,"y":1}],"locationHashes":["00000000-0000-0000-0000-000000000000"]}' 400 probe "neither-populated-xor" '{}' 400 echo "All probes passed."