#!/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 '{ "name": "Test Static Token for Deletion", "description": "A test static token for deletion test", "permissions": ["read"], "expires_at": "2025-12-31T23:59:59Z" }' 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 '{ "name": "Test Static Token", "description": "A test static token", "permissions": ["read"], "expires_at": "2025-12-31T23:59:59Z" }' # 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 "$@"