mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 15:01:14 +00:00
865dfdb3b9
AZ-794: rename inventory wire fields tileZoom/tileX/tileY -> z/x/y to match the slippy-map URL convention. Contract bumped to v2.0.0. AZ-795: shared validation infrastructure -- FluentValidation + ValidationEndpointFilter + GlobalValidatorConfig (camelCase paths). GlobalExceptionHandler now converts JsonException (UnmappedMember + JsonRequired) into RFC 7807 ValidationProblemDetails. JSON layer hardened with UnmappedMemberHandling.Disallow + camelCase naming policy. New error-shape.md contract. AZ-796: InventoryRequestValidator covers 9 rules (XOR tiles vs locationHashes, cap 1000, z 0..22, x/y in slippy bounds, hash length/charset). 16 unit tests + 16 integration tests + a manual curl probe script. Adjacent fixes uncovered by the new strict layer: - IdempotentPostTests RoutePoint payload corrected to lat/lon (the DTO has used JsonPropertyName for ages; previously silently ignored under PascalCase fallback). - TileInventoryTests slippy x/y reduced to fit z=18 bounds. - docker-compose.yml host port for Postgres moved 5432 -> 5433 to avoid sibling-project conflict; appsettings.Development + README + AGENTS + architecture + containerization docs aligned. New coderule (suite + repo): API consumer-facing OpenAPI descriptions must not contain task IDs, contract filenames, or version-bump history -- internal change tracking belongs in commits/contract docs/changelogs. Existing offending descriptions in Program.cs cleaned up. Co-authored-by: Cursor <cursoragent@cursor.com>
59 lines
2.7 KiB
Bash
Executable File
59 lines
2.7 KiB
Bash
Executable File
#!/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="<bearer-token>" ./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."
|