- Completed Action 1.3.1.1: Created test-endpoint-formats.sh - Script reads endpoints from Swagger spec and tests each one - Identifies wrapped vs direct response formats - Outputs JSON report with format categorization - Handles auth-required endpoints gracefully - Can be run against any base URL
213 lines
7.5 KiB
Bash
Executable file
213 lines
7.5 KiB
Bash
Executable file
#!/bin/bash
|
|
# Test endpoint response formats to identify inconsistencies
|
|
# Usage: ./scripts/test-endpoint-formats.sh [base_url]
|
|
# Example: ./scripts/test-endpoint-formats.sh http://localhost:8080/api/v1
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
RED='\033[0;31m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
BASE_URL="${1:-http://localhost:8080/api/v1}"
|
|
OUTPUT_FILE="${2:-endpoint-formats-report.json}"
|
|
SWAGGER_SPEC="${3:-veza-backend-api/docs/swagger.json}"
|
|
|
|
echo -e "${BLUE}🔍 Testing endpoint response formats...${NC}"
|
|
echo -e "${BLUE}Base URL: ${BASE_URL}${NC}"
|
|
echo -e "${BLUE}Output: ${OUTPUT_FILE}${NC}"
|
|
echo ""
|
|
|
|
# Check if jq is available
|
|
if ! command -v jq &> /dev/null; then
|
|
echo -e "${RED}❌ Error: jq is required but not installed${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if swagger spec exists
|
|
if [ ! -f "$SWAGGER_SPEC" ]; then
|
|
echo -e "${YELLOW}⚠️ Warning: Swagger spec not found at $SWAGGER_SPEC${NC}"
|
|
echo -e "${YELLOW} Will test endpoints manually${NC}"
|
|
SWAGGER_SPEC=""
|
|
fi
|
|
|
|
# Initialize results array
|
|
RESULTS="[]"
|
|
|
|
# Function to test an endpoint
|
|
test_endpoint() {
|
|
local method=$1
|
|
local path=$2
|
|
local full_url="${BASE_URL}${path}"
|
|
local description=$3
|
|
|
|
echo -e "${BLUE}Testing: ${method} ${path}${NC}"
|
|
|
|
# Build curl command based on method
|
|
local curl_cmd="curl -s -w '\n%{http_code}' -X ${method}"
|
|
|
|
# Add headers
|
|
curl_cmd="${curl_cmd} -H 'Content-Type: application/json'"
|
|
curl_cmd="${curl_cmd} -H 'X-API-Version: v1'"
|
|
|
|
# Add body for POST/PUT/PATCH
|
|
if [[ "$method" == "POST" || "$method" == "PUT" || "$method" == "PATCH" ]]; then
|
|
# Try to determine if auth is needed (skip auth endpoints)
|
|
if [[ "$path" == *"/auth/login"* ]] || [[ "$path" == *"/auth/register"* ]]; then
|
|
curl_cmd="${curl_cmd} -d '{}'"
|
|
else
|
|
# For other endpoints, skip if they require auth (will get 401)
|
|
curl_cmd="${curl_cmd} -d '{}'"
|
|
fi
|
|
fi
|
|
|
|
# Execute request
|
|
local response=$(eval "$curl_cmd '${full_url}'" 2>/dev/null || echo "")
|
|
|
|
if [ -z "$response" ]; then
|
|
echo -e "${YELLOW} ⚠️ No response (endpoint may be down or require auth)${NC}"
|
|
RESULTS=$(echo "$RESULTS" | jq --arg method "$method" \
|
|
--arg path "$path" \
|
|
--arg desc "$description" \
|
|
--arg status "no_response" \
|
|
--arg format "unknown" \
|
|
'. += [{
|
|
method: $method,
|
|
path: $path,
|
|
description: $desc,
|
|
status: $status,
|
|
format: $format,
|
|
error: "No response received"
|
|
}]')
|
|
return
|
|
fi
|
|
|
|
# Extract HTTP status code (last line)
|
|
local http_code=$(echo "$response" | tail -n1)
|
|
local body=$(echo "$response" | sed '$d')
|
|
|
|
# Determine response format
|
|
local format="unknown"
|
|
local has_success=$(echo "$body" | jq -r '.success // empty' 2>/dev/null || echo "")
|
|
local has_data=$(echo "$body" | jq -r '.data // empty' 2>/dev/null || echo "")
|
|
local has_error=$(echo "$body" | jq -r '.error // empty' 2>/dev/null || echo "")
|
|
|
|
if [ "$http_code" == "200" ] || [ "$http_code" == "201" ]; then
|
|
if [ -n "$has_success" ] && [ -n "$has_data" ]; then
|
|
format="wrapped"
|
|
echo -e "${GREEN} ✅ Wrapped format: { success, data }${NC}"
|
|
elif [ -n "$has_data" ] && [ -z "$has_success" ]; then
|
|
format="direct_data"
|
|
echo -e "${YELLOW} ⚠️ Direct format: { data } (no success field)${NC}"
|
|
else
|
|
format="direct"
|
|
echo -e "${YELLOW} ⚠️ Direct format: no wrapper${NC}"
|
|
fi
|
|
elif [ "$http_code" == "401" ] || [ "$http_code" == "403" ]; then
|
|
format="auth_required"
|
|
echo -e "${YELLOW} 🔒 Auth required (${http_code})${NC}"
|
|
elif [ "$http_code" == "404" ]; then
|
|
format="not_found"
|
|
echo -e "${YELLOW} ❌ Not found (${http_code})${NC}"
|
|
else
|
|
format="error"
|
|
echo -e "${YELLOW} ⚠️ Error (${http_code})${NC}"
|
|
fi
|
|
|
|
# Add to results
|
|
RESULTS=$(echo "$RESULTS" | jq --arg method "$method" \
|
|
--arg path "$path" \
|
|
--arg desc "$description" \
|
|
--arg status "$http_code" \
|
|
--arg format "$format" \
|
|
--argjson body "$(echo "$body" | jq -c . 2>/dev/null || echo 'null')" \
|
|
'. += [{
|
|
method: $method,
|
|
path: $path,
|
|
description: $desc,
|
|
status: $status,
|
|
format: $format,
|
|
response_sample: $body
|
|
}]')
|
|
}
|
|
|
|
# Extract endpoints from Swagger spec if available
|
|
if [ -n "$SWAGGER_SPEC" ] && [ -f "$SWAGGER_SPEC" ]; then
|
|
echo -e "${GREEN}📋 Reading endpoints from Swagger spec...${NC}"
|
|
|
|
# Get all paths
|
|
jq -r '.paths | to_entries[] | .key as $path | .value | to_entries[] | "\(.key | ascii_upcase) \($path)"' "$SWAGGER_SPEC" | while read -r method path; do
|
|
# Get description if available
|
|
desc=$(jq -r ".paths[\"$path\"][\"${method,,}\"].summary // .paths[\"$path\"][\"${method,,}\"].description // \"\"" "$SWAGGER_SPEC" 2>/dev/null || echo "")
|
|
|
|
# Skip if path requires path parameters (we can't test those easily)
|
|
if [[ "$path" == *"{"* ]]; then
|
|
echo -e "${YELLOW}Skipping ${method} ${path} (has path parameters)${NC}"
|
|
continue
|
|
fi
|
|
|
|
test_endpoint "$method" "$path" "$desc"
|
|
sleep 0.1 # Small delay to avoid overwhelming the server
|
|
done
|
|
else
|
|
echo -e "${YELLOW}⚠️ No Swagger spec, testing common endpoints manually...${NC}"
|
|
|
|
# Test common endpoints manually
|
|
test_endpoint "GET" "/health" "Health check"
|
|
test_endpoint "GET" "/auth/me" "Get current user"
|
|
test_endpoint "GET" "/tracks" "List tracks"
|
|
test_endpoint "GET" "/playlists" "List playlists"
|
|
test_endpoint "GET" "/users" "List users"
|
|
fi
|
|
|
|
# Generate summary
|
|
echo ""
|
|
echo -e "${BLUE}📊 Generating summary...${NC}"
|
|
|
|
# Count formats
|
|
wrapped_count=$(echo "$RESULTS" | jq '[.[] | select(.format == "wrapped")] | length')
|
|
direct_count=$(echo "$RESULTS" | jq '[.[] | select(.format == "direct" or .format == "direct_data")] | length')
|
|
auth_required=$(echo "$RESULTS" | jq '[.[] | select(.format == "auth_required")] | length')
|
|
error_count=$(echo "$RESULTS" | jq '[.[] | select(.format == "error" or .format == "not_found")] | length')
|
|
|
|
# Create summary
|
|
SUMMARY=$(jq -n \
|
|
--argjson results "$RESULTS" \
|
|
--arg wrapped "$wrapped_count" \
|
|
--arg direct "$direct_count" \
|
|
--arg auth "$auth_required" \
|
|
--arg errors "$error_count" \
|
|
'{
|
|
summary: {
|
|
total_tested: ($results | length),
|
|
wrapped_format: ($wrapped | tonumber),
|
|
direct_format: ($direct | tonumber),
|
|
auth_required: ($auth | tonumber),
|
|
errors: ($errors | tonumber)
|
|
},
|
|
endpoints: $results
|
|
}')
|
|
|
|
# Save to file
|
|
echo "$SUMMARY" | jq '.' > "$OUTPUT_FILE"
|
|
|
|
echo ""
|
|
echo -e "${GREEN}✅ Testing complete!${NC}"
|
|
echo -e "${GREEN}Results saved to: ${OUTPUT_FILE}${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}Summary:${NC}"
|
|
echo -e " Wrapped format (✅): ${wrapped_count}"
|
|
echo -e " Direct format (⚠️): ${direct_count}"
|
|
echo -e " Auth required (🔒): ${auth_required}"
|
|
echo -e " Errors (❌): ${error_count}"
|
|
|
|
# List inconsistent endpoints
|
|
if [ "$direct_count" -gt 0 ]; then
|
|
echo ""
|
|
echo -e "${YELLOW}⚠️ Endpoints with direct format (inconsistent):${NC}"
|
|
echo "$RESULTS" | jq -r '.[] | select(.format == "direct" or .format == "direct_data") | " \(.method) \(.path)"'
|
|
fi
|