Files
skybridge/test/e2e_test.sh
2025-08-22 14:40:59 -04:00

446 lines
13 KiB
Bash
Executable File

#!/bin/bash
# End-to-End Test Script for KMS API
# This script tests the Key Management Service API using curl commands
# set -e # Exit on any error - commented out for debugging
# Configuration
BASE_URL="${BASE_URL:-http://localhost:8080}"
API_BASE="${BASE_URL}/api"
USER_EMAIL="${USER_EMAIL:-test@example.com}"
USER_ID="${USER_ID:-test-user-123}"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test counters
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0
# Helper functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[PASS]${NC} $1"
((TESTS_PASSED++))
}
log_error() {
echo -e "${RED}[FAIL]${NC} $1"
((TESTS_FAILED++))
}
log_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
run_test() {
local test_name="$1"
local expected_status="$2"
shift 2
local curl_args=("$@")
((TESTS_RUN++))
log_info "Running test: $test_name"
# Run curl command and capture response
local response
local status_code
response=$(curl -s -w "\n%{http_code}" "${curl_args[@]}" 2>/dev/null || echo -e "\n000")
status_code=$(echo "$response" | tail -n1)
local body=$(echo "$response" | head -n -1)
if [[ "$status_code" == "$expected_status" ]]; then
log_success "$test_name (Status: $status_code)"
if [[ -n "$body" && "$body" != "null" && "$body" != "" ]]; then
echo " Response: $body" | head -c 300
if [[ ${#body} -gt 300 ]]; then
echo "..."
fi
echo
else
echo " Response: (empty or null)"
fi
return 0
else
log_error "$test_name (Expected: $expected_status, Got: $status_code)"
if [[ -n "$body" ]]; then
echo "Response: $body"
fi
return 1
fi
}
# Wait for server to be ready
wait_for_server() {
log_info "Waiting for server to be ready..."
local max_attempts=30
local attempt=1
while [[ $attempt -le $max_attempts ]]; do
if curl -s "$BASE_URL/health" > /dev/null 2>&1; then
log_success "Server is ready!"
return 0
fi
log_info "Attempt $attempt/$max_attempts - Server not ready, waiting..."
sleep 2
((attempt++))
done
log_error "Server failed to start within timeout"
exit 1
}
# Test functions
test_health_endpoints() {
log_info "=== Testing Health Endpoints ==="
run_test "Health Check" "200" \
-X GET "$BASE_URL/health"
run_test "Readiness Check" "200" \
-X GET "$BASE_URL/ready"
}
test_authentication_endpoints() {
log_info "=== Testing Authentication Endpoints ==="
# Test login without auth headers (should fail)
run_test "Login without auth headers" "401" \
-X POST "$API_BASE/login" \
-H "Content-Type: application/json" \
-d '{
"app_id": "test-app-123",
"permissions": ["read", "write"],
"redirect_uri": "https://example.com/callback"
}'
# Test login with auth headers
run_test "Login with auth headers" "200" \
-X POST "$API_BASE/login" \
-H "Content-Type: application/json" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" \
-d '{
"app_id": "test-app-123",
"permissions": ["read", "write"]
}'
# Test verify endpoint
run_test "Verify token" "200" \
-X POST "$API_BASE/verify" \
-H "Content-Type: application/json" \
-d '{
"app_id": "test-app-123",
"token": "test-token-123",
"type": "static"
}'
# Test renew endpoint
run_test "Renew token" "200" \
-X POST "$API_BASE/renew" \
-H "Content-Type: application/json" \
-d '{
"app_id": "test-app-123",
"user_id": "test-user-123",
"token": "test-token-123"
}'
}
test_application_endpoints() {
log_info "=== Testing Application Endpoints ==="
# Test list applications without auth (should fail)
run_test "List applications without auth" "401" \
-X GET "$API_BASE/applications"
# Test list applications with auth
run_test "List applications with auth" "200" \
-X GET "$API_BASE/applications" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID"
# Test list applications with pagination
run_test "List applications with pagination" "200" \
-X GET "$API_BASE/applications?limit=10&offset=0" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID"
# Generate unique application ID
local unique_app_id="test-app-e2e-$(date +%s%N | cut -b1-13)-$RANDOM"
# Test create application
run_test "Create application" "201" \
-X POST "$API_BASE/applications" \
-H "Content-Type: application/json" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" \
-d '{
"app_id": "'$unique_app_id'",
"app_link": "https://example.com/test-app",
"type": ["static"],
"callback_url": "https://example.com/callback",
"token_renewal_duration": 604800000000000,
"max_token_duration": 2592000000000000,
"owner": {
"type": "individual",
"name": "Test User",
"owner": "test@example.com"
}
}'
# Use the unique_app_id directly since we know it was created successfully
local app_id="$unique_app_id"
if [[ -n "$app_id" && "$app_id" != "test-app-123" ]]; then
log_info "Using created app_id: $app_id"
# Test get application by ID
run_test "Get application by ID" "200" \
-X GET "$API_BASE/applications/$app_id" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID"
# Test update application
run_test "Update application" "200" \
-X PUT "$API_BASE/applications/$app_id" \
-H "Content-Type: application/json" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" \
-d '{
"name": "Updated Test Application",
"description": "An updated test application"
}'
# Store app_id for token tests
export TEST_APP_ID="$app_id"
else
log_warning "Could not extract app_id from create response, using default"
export TEST_APP_ID="test-app-123"
fi
# Test get non-existent application
run_test "Get non-existent application" "404" \
-X GET "$API_BASE/applications/non-existent-id" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID"
# Test create application with invalid JSON
run_test "Create application with invalid JSON" "400" \
-X POST "$API_BASE/applications" \
-H "Content-Type: application/json" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" \
-d '{"invalid": json}'
}
test_token_endpoints() {
log_info "=== Testing Token Endpoints ==="
local app_id="${TEST_APP_ID:-test-app-123}"
# Test list tokens for application
run_test "List tokens for application" "200" \
-X GET "$API_BASE/applications/$app_id/tokens" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID"
# Test list tokens with pagination
run_test "List tokens with pagination" "200" \
-X GET "$API_BASE/applications/$app_id/tokens?limit=5&offset=0" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID"
# Test create static token and capture response for token_id extraction
local token_response
token_response=$(curl -s -w "\n%{http_code}" -X POST "$API_BASE/applications/$app_id/tokens" \
-H "Content-Type: application/json" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" \
-d '{
"owner": {
"type": "individual",
"name": "Test Token Owner",
"owner": "test-token@example.com"
},
"permissions": ["repo.read", "repo.write"]
}' 2>/dev/null || echo -e "\n000")
local token_status_code=$(echo "$token_response" | tail -n1)
local token_body=$(echo "$token_response" | head -n -1)
run_test "Create static token" "201" \
-X POST "$API_BASE/applications/$app_id/tokens" \
-H "Content-Type: application/json" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" \
-d '{
"owner": {
"type": "individual",
"name": "Test Token Owner",
"owner": "test-token@example.com"
},
"permissions": ["repo.read", "repo.write"]
}'
# Extract token_id from the first response for deletion test
local token_id
token_id=$(echo "$token_body" | grep -o '"id":"[^"]*"' | cut -d'"' -f4 || echo "")
if [[ -n "$token_id" ]]; then
log_info "Using created token_id: $token_id"
# Test delete token
run_test "Delete token" "204" \
-X DELETE "$API_BASE/tokens/$token_id" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID"
else
log_warning "Could not extract token_id from create response"
fi
# Test create token with invalid JSON
run_test "Create token with invalid JSON" "400" \
-X POST "$API_BASE/applications/$app_id/tokens" \
-H "Content-Type: application/json" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" \
-d '{"invalid": json}'
# Test delete non-existent token
run_test "Delete non-existent token" "500" \
-X DELETE "$API_BASE/tokens/00000000-0000-0000-0000-000000000000" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID"
}
test_error_handling() {
log_info "=== Testing Error Handling ==="
# Test invalid endpoints
run_test "Invalid endpoint" "404" \
-X GET "$API_BASE/invalid-endpoint"
# Test missing content-type for POST requests
local unique_missing_ct_id="test-missing-ct-$(date +%s%N | cut -b1-13)-$RANDOM"
run_test "Missing content-type" "400" \
-X POST "$API_BASE/applications" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" \
-d '{
"app_id": "'$unique_missing_ct_id'",
"app_link": "https://example.com/test-app",
"type": ["static"],
"callback_url": "https://example.com/callback",
"token_renewal_duration": 604800000000000,
"max_token_duration": 2592000000000000,
"owner": {
"type": "individual",
"name": "Test User",
"owner": "test@example.com"
}
}'
# Test malformed JSON
run_test "Malformed JSON" "400" \
-X POST "$API_BASE/applications" \
-H "Content-Type: application/json" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" \
-d '{"name": "test"'
}
test_documentation_endpoint() {
log_info "=== Testing Documentation Endpoint ==="
run_test "Get API documentation" "200" \
-X GET "$API_BASE/docs" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID"
}
cleanup_test_data() {
log_info "=== Cleaning up test data ==="
if [[ -n "${TEST_APP_ID:-}" && "$TEST_APP_ID" != "test-app-123" ]]; then
log_info "Deleting test application: $TEST_APP_ID"
curl -s -X DELETE "$API_BASE/applications/$TEST_APP_ID" \
-H "X-User-Email: $USER_EMAIL" \
-H "X-User-ID: $USER_ID" > /dev/null 2>&1 || true
fi
}
print_summary() {
echo
log_info "=== Test Summary ==="
echo "Tests Run: $TESTS_RUN"
echo -e "Tests Passed: ${GREEN}$TESTS_PASSED${NC}"
echo -e "Tests Failed: ${RED}$TESTS_FAILED${NC}"
if [[ $TESTS_FAILED -eq 0 ]]; then
echo -e "${GREEN}All tests passed!${NC}"
exit 0
else
echo -e "${RED}Some tests failed!${NC}"
exit 1
fi
}
# Main execution
main() {
log_info "Starting End-to-End Tests for KMS API"
log_info "Base URL: $BASE_URL"
log_info "User Email: $USER_EMAIL"
log_info "User ID: $USER_ID"
echo
# Wait for server to be ready
wait_for_server
# Run all test suites
test_health_endpoints
echo
test_authentication_endpoints
echo
test_application_endpoints
echo
test_token_endpoints
echo
test_error_handling
echo
test_documentation_endpoint
echo
# Cleanup
cleanup_test_data
# Print summary
print_summary
}
# Handle script interruption
trap cleanup_test_data EXIT
# Check if curl is available
if ! command -v curl &> /dev/null; then
log_error "curl is required but not installed"
exit 1
fi
# Run main function
main "$@"