442 lines
13 KiB
Bash
Executable File
442 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 '{
|
|
"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 "$@"
|