all the refactor
Build and Publish / BuildAndDeployAmd64 (push) Failing after 5s
Build and Publish / BuildAndDeployArm64 (push) Failing after 6s

This commit is contained in:
2026-06-28 17:51:52 +02:00
parent 7db0d236c7
commit aa8b2bdedc
84 changed files with 4328 additions and 2344 deletions
+138 -25
View File
@@ -1,7 +1,8 @@
#!/usr/bin/env bash
# ──────────────────────────────────────────────────────────────────────────────
# UCP API test suite
# Tests the Universal Commerce Protocol REST endpoints (cart, order) via curl.
# Tests the Universal Commerce Protocol REST endpoints (cart, checkout, order)
# via curl.
#
# Prerequisites:
# make up-infra (infra compose up — order :8092, cart :8090)
@@ -17,6 +18,7 @@
# # Single service:
# bash api-tests/test_ucp.sh --order
# bash api-tests/test_ucp.sh --cart
# bash api-tests/test_ucp.sh --checkout
#
# # Verify signatures (requires signing key mounted):
# bash api-tests/test_ucp.sh --verify-sig
@@ -36,16 +38,20 @@ elif [ "$MODE" = "--order" ]; then
ORDER_URL="http://localhost:8092"
elif [ "$MODE" = "--cart" ]; then
CART_URL="http://localhost:8090"
elif [ "$MODE" = "--checkout" ]; then
CART_URL="http://localhost:8090"
CHECKOUT_URL="http://localhost:8094"
elif [ "$MODE" = "--verify-sig" ]; then
# If signing is enabled (key mounted), you need the full stack or direct with
# env var — try both common ports.
ORDER_URL="${ORDER_URL:-http://localhost:8092}"
CART_URL="${CART_URL:-http://localhost:8090}"
CHECKOUT_URL="${CHECKOUT_URL:-http://localhost:8094}"
else
# Default: infra stack, direct to Docker ports
CART_URL="${CART_URL:-http://localhost:8090}"
ORDER_URL="${ORDER_URL:-http://localhost:8092}"
CHECKOUT_URL="${CHECKOUT_URL:-}"
CHECKOUT_URL="${CHECKOUT_URL:-http://localhost:8094}"
fi
echo "═══════════════════════════════════════════════════════════════"
@@ -210,20 +216,25 @@ if [ -n "${CART_URL:-}" ]; then
echo " response: $(echo "$cart_body" | head -c 400)"
fi
# ── Add item to cart ────────────────────────────────────────────────────────
echo "--- 2.3 POST /ucp/v1/carts/{id}/items ---"
add_resp=$(curl -s -w '\n%{http_code}' -X POST "$CART_URL/ucp/v1/carts/$CART_ID/items" \
# ── Replace cart contents via UCP ───────────────────────────────────────────
echo "--- 2.3 PUT /ucp/v1/carts/{id} ---"
add_resp=$(curl -s -w '\n%{http_code}' -X PUT "$CART_URL/ucp/v1/carts/$CART_ID" \
-H 'Content-Type: application/json' \
-d '{
"sku": "TEST-SKU-1",
"name": "Test Product",
"quantity": 1,
"unitPrice": 19900,
"taxRate": 2500
"country": "se",
"items": [
{
"sku": "TEST-SKU-1",
"name": "Test Product",
"quantity": 1,
"price": 19900,
"taxRate": 25
}
]
}')
add_code=$(echo "$add_resp" | tail -1)
add_body=$(echo "$add_resp" | sed '$d')
assert_status "Add item" 201 "$add_code" "$add_body"
assert_status "Update cart items" 200 "$add_code" "$add_body"
# ── Get cart ────────────────────────────────────────────────────────────────
echo "--- 2.4 GET /ucp/v1/carts/{id} ---"
@@ -231,41 +242,143 @@ if [ -n "${CART_URL:-}" ]; then
get_cart_code=$(echo "$get_cart_resp" | tail -1)
get_cart_body=$(echo "$get_cart_resp" | sed '$d')
assert_status "Get cart" 200 "$get_cart_code" "$get_cart_body"
echo " total: $(echo "$get_cart_body" | sed -n 's/.*"total"[[:space:]]*:[[:space:]]*\([0-9]*\).*/\1/p')"
echo " totalIncVat: $(echo "$get_cart_body" | sed -n 's/.*"totalIncVat"[[:space:]]*:[[:space:]]*\([0-9]*\).*/\1/p')"
echo ""
fi
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 3: Full flow — cart → checkout → order (via edge/nginx only)
# SECTION 3: Checkout service tests
# ══════════════════════════════════════════════════════════════════════════════
if [ "$MODE" = "--edge" ] && [ -n "${CHECKOUT_URL:-}" ]; then
header "3. Full Flow (via nginx)"
if [ -n "${CHECKOUT_URL:-}" ] && [ -n "${CART_ID:-}" ]; then
header "3. Checkout Service → $CHECKOUT_URL"
# ── This section needs the full compose stack with nginx on :8080,
# and checkout must be reachable. Skip for infra/direct modes.
echo "--- 3.1 Create checkout session ---"
checkout_resp=$(curl -s -w '\n%{http_code}' -X POST "$CHECKOUT_URL/ucp/v1/checkout-sessions" \
# ── Health ──────────────────────────────────────────────────────────────────
echo "--- 3.1 Health check ---"
resp=$(curl -sf "$CHECKOUT_URL/healthz" 2>&1) && pass "/healthz" || fail "/healthz: $resp"
# ── Create checkout session ────────────────────────────────────────────────
echo "--- 3.2 POST /ucp/v1/checkout-sessions/ ---"
checkout_resp=$(curl -s -w '\n%{http_code}' -X POST "$CHECKOUT_URL/ucp/v1/checkout-sessions/" \
-H 'Content-Type: application/json' \
-d '{
"cartId": "'"$CART_ID"'",
"currency": "SEK",
"country": "se"
"cartId": "'"$CART_ID"'",
"currency": "SEK",
"country": "se"
}')
checkout_code=$(echo "$checkout_resp" | tail -1)
checkout_body=$(echo "$checkout_resp" | sed '$d')
assert_status "Create checkout session" 201 "$checkout_code" "$checkout_body"
CHECKOUT_ID=$(echo "$checkout_body" | sed -n 's/.*"id"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
if [ -n "$CHECKOUT_ID" ]; then
pass "Checkout ID: $CHECKOUT_ID"
else
fail "Could not extract checkout ID"
echo " response: $(echo "$checkout_body" | head -c 400)"
fi
if [ -n "${CHECKOUT_ID:-}" ]; then
# ── Read checkout session ────────────────────────────────────────────────
echo "--- 3.3 GET /ucp/v1/checkout-sessions/{id} ---"
get_checkout_resp=$(curl -s -w '\n%{http_code}' "$CHECKOUT_URL/ucp/v1/checkout-sessions/$CHECKOUT_ID")
get_checkout_code=$(echo "$get_checkout_resp" | tail -1)
get_checkout_body=$(echo "$get_checkout_resp" | sed '$d')
assert_status "Get checkout session" 200 "$get_checkout_code" "$get_checkout_body"
echo " checkout: $(maybe_jq "$get_checkout_body" '.id + " status=" + .status')"
# ── Complete checkout session ────────────────────────────────────────────
echo "--- 3.4 POST /ucp/v1/checkout-sessions/{id}/complete ---"
complete_resp=$(curl -s -w '\n%{http_code}' -X POST "$CHECKOUT_URL/ucp/v1/checkout-sessions/$CHECKOUT_ID/complete" \
-H 'Content-Type: application/json' \
-d '{
"provider": "test",
"paymentToken": "ucp-test-payment-token",
"currency": "SEK",
"country": "se"
}')
complete_code=$(echo "$complete_resp" | tail -1)
complete_body=$(echo "$complete_resp" | sed '$d')
assert_status "Complete checkout session" 200 "$complete_code" "$complete_body"
COMPLETE_ORDER_ID=$(echo "$complete_body" | sed -n 's/.*"orderId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
if [ -n "$COMPLETE_ORDER_ID" ]; then
pass "Checkout produced order ID: $COMPLETE_ORDER_ID"
else
fail "Checkout completion did not return an orderId"
echo " response: $(echo "$complete_body" | head -c 400)"
fi
# ── Signature headers (if enabled) ──────────────────────────────────────
echo "--- 3.5 Check signature headers ---"
checkout_sig_resp=$(curl -s -i "$CHECKOUT_URL/ucp/v1/checkout-sessions/$CHECKOUT_ID" 2>/dev/null | head -30)
if echo "$checkout_sig_resp" | grep -qi "signature-input"; then
pass "Checkout Signature-Input header present"
echo " $(echo "$checkout_sig_resp" | grep -i "signature-input" | head -1)"
else
echo " ️ No Signature-Input header"
fi
if echo "$checkout_sig_resp" | grep -qi "^signature:"; then
pass "Checkout Signature header present"
else
echo " ️ No Signature header"
fi
fi
fi
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 4: Signature verification (standalone)
# SECTION 4: Edge-only discovery artifact tests
# ══════════════════════════════════════════════════════════════════════════════
if [ "$MODE" = "--edge" ]; then
header "4. Edge Discovery → $BASE"
echo "--- 4.1 GET /.well-known/ucp ---"
profile_resp=$(curl -s -w '\n%{http_code}' "$BASE/.well-known/ucp")
profile_code=$(echo "$profile_resp" | tail -1)
profile_body=$(echo "$profile_resp" | sed '$d')
assert_status "Get UCP profile" 200 "$profile_code" "$profile_body"
if echo "$profile_body" | grep -q '/.well-known/ucp/openapi/shopping-rest.openapi.json'; then
pass "Profile advertises self-hosted REST OpenAPI"
else
fail "Profile is missing self-hosted REST OpenAPI URL"
fi
echo "--- 4.2 GET /.well-known/ucp/openapi/shopping-rest.openapi.json ---"
openapi_resp=$(curl -s -w '\n%{http_code}' "$BASE/.well-known/ucp/openapi/shopping-rest.openapi.json")
openapi_code=$(echo "$openapi_resp" | tail -1)
openapi_body=$(echo "$openapi_resp" | sed '$d')
assert_status "Get UCP REST OpenAPI" 200 "$openapi_code" "$openapi_body"
if echo "$openapi_body" | grep -q '"openapi"'; then
pass "OpenAPI document returned"
else
fail "OpenAPI document body missing openapi field"
fi
echo "--- 4.3 GET self-hosted UCP schemas ---"
for schema_path in \
"/.well-known/ucp/schemas/shopping/customer.json" \
"/.well-known/ucp/schemas/shopping/authentication.json" \
"/.well-known/ucp/schemas/payments/processor_tokenizer.json"
do
schema_resp=$(curl -s -w '\n%{http_code}' "$BASE$schema_path")
schema_code=$(echo "$schema_resp" | tail -1)
schema_body=$(echo "$schema_resp" | sed '$d')
assert_status "Get $schema_path" 200 "$schema_code" "$schema_body"
if echo "$schema_body" | grep -q '"$schema"'; then
pass "$schema_path is valid schema JSON"
else
fail "$schema_path body missing \$schema"
fi
done
fi
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 5: Signature verification (standalone)
# ══════════════════════════════════════════════════════════════════════════════
if [ "$MODE" = "--verify-sig" ]; then
header "4. Signature Verification"
header "5. Signature Verification"
# Verify that the response includes RFC 9421 HTTP Message Signatures.
# Requires the service to have UCP_SIGNING_KEY_PATH set and the key mounted.
echo "--- 4.1 Check Signed Response ---"
echo "--- 5.1 Check Signed Response ---"
sig_output=$(curl -s -D - "$ORDER_URL/ucp/v1/orders/$ORDER_ID" 2>/dev/null | head -40)
echo "$sig_output" | while IFS= read -r line; do