#!/bin/bash # ================================================ # Math Platform - End-to-End Testing Script # ================================================ set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration API_BASE_URL="http://localhost:3001" FRONTEND_URL="http://localhost:3000" TEST_USER_EMAIL="test_$(date +%s)@example.com" TEST_USER_PASSWORD="Test123456!" TEST_USER_NAME="Test User" # Test results TESTS_PASSED=0 TESTS_FAILED=0 TESTS_TOTAL=0 # Helper functions print_header() { echo -e "\n${BLUE}============================================${NC}" echo -e "${BLUE}$1${NC}" echo -e "${BLUE}============================================${NC}" } print_test() { echo -e "\n${YELLOW}TEST: $1${NC}" TESTS_TOTAL=$((TESTS_TOTAL + 1)) } print_success() { echo -e "${GREEN}✓ PASSED: $1${NC}" TESTS_PASSED=$((TESTS_PASSED + 1)) } print_error() { echo -e "${RED}✗ FAILED: $1${NC}" TESTS_FAILED=$((TESTS_FAILED + 1)) } print_info() { echo -e "${BLUE}ℹ $1${NC}" } # Function to wait for service wait_for_service() { local url=$1 local max_attempts=30 local attempt=1 print_info "Waiting for $url..." while [ $attempt -le $max_attempts ]; do if curl -s -f "$url" > /dev/null 2>&1; then print_success "Service is ready" return 0 fi sleep 2 attempt=$((attempt + 1)) done print_error "Service not ready after $max_attempts attempts" return 1 } # Function to make API request api_request() { local method=$1 local endpoint=$2 local data=$3 local token=$4 local url="${API_BASE_URL}${endpoint}" local headers="-H 'Content-Type: application/json'" if [ -n "$token" ]; then headers="$headers -H 'Authorization: Bearer $token'" fi if [ "$method" = "GET" ]; then curl -s -X GET "$url" $headers elif [ "$method" = "POST" ]; then curl -s -X POST "$url" $headers -d "$data" elif [ "$method" = "PUT" ]; then curl -s -X PUT "$url" $headers -d "$data" elif [ "$method" = "DELETE" ]; then curl -s -X DELETE "$url" $headers fi } # Function to test user registration test_registration() { print_test "User Registration" local response=$(api_request "POST" "/api/auth/register" "{\"email\":\"$TEST_USER_EMAIL\",\"password\":\"$TEST_USER_PASSWORD\",\"name\":\"$TEST_USER_NAME\"}") if echo "$response" | grep -q "token"; then USER_TOKEN=$(echo "$response" | grep -o '"token":"[^"]*' | cut -d'"' -f4) USER_ID=$(echo "$response" | grep -o '"id":"[^"]*' | cut -d'"' -f4) print_success "User registered successfully" print_info "User ID: $USER_ID" print_info "Email: $TEST_USER_EMAIL" return 0 else print_error "Registration failed" print_info "Response: $response" return 1 fi } # Function to test user login test_login() { print_test "User Login" local response=$(api_request "POST" "/api/auth/login" "{\"email\":\"$TEST_USER_EMAIL\",\"password\":\"$TEST_USER_PASSWORD\"}") if echo "$response" | grep -q "token"; then USER_TOKEN=$(echo "$response" | grep -o '"token":"[^"]*' | cut -d'"' -f4) print_success "User logged in successfully" return 0 else print_error "Login failed" print_info "Response: $response" return 1 fi } # Function to test getting modules test_get_modules() { print_test "Get Learning Modules" local response=$(api_request "GET" "/api/modules" "" "$USER_TOKEN") if echo "$response" | grep -q "modules"; then MODULE_COUNT=$(echo "$response" | grep -o '"id"' | wc -l) print_success "Retrieved $MODULE_COUNT modules" # Get first module ID if [ $MODULE_COUNT -gt 0 ]; then MODULE_ID=$(echo "$response" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4) print_info "First Module ID: $MODULE_ID" fi return 0 else print_error "Failed to retrieve modules" print_info "Response: $response" return 1 fi } # Function to test accessing a specific module test_access_module() { print_test "Access Module Content" if [ -z "$MODULE_ID" ]; then print_error "No module ID available" return 1 fi local response=$(api_request "GET" "/api/modules/$MODULE_ID" "" "$USER_TOKEN") if echo "$response" | grep -q "title"; then MODULE_TITLE=$(echo "$response" | grep -o '"title":"[^"]*' | cut -d'"' -f4) print_success "Accessed module: $MODULE_TITLE" return 0 else print_error "Failed to access module" print_info "Response: $response" return 1 fi } # Function to test getting exercises test_get_exercises() { print_test "Get Exercises for Module" if [ -z "$MODULE_ID" ]; then print_error "No module ID available" return 1 fi local response=$(api_request "GET" "/api/exercises?moduleId=$MODULE_ID" "" "$USER_TOKEN") if echo "$response" | grep -q "exercises"; then EXERCISE_COUNT=$(echo "$response" | grep -o '"id"' | wc -l) print_success "Retrieved $EXERCISE_COUNT exercises" # Get first exercise ID if [ $EXERCISE_COUNT -gt 0 ]; then EXERCISE_ID=$(echo "$response" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4) print_info "First Exercise ID: $EXERCISE_ID" fi return 0 else print_error "Failed to retrieve exercises" print_info "Response: $response" return 1 fi } # Function to test submitting an exercise test_submit_exercise() { print_test "Submit Exercise Answer" if [ -z "$EXERCISE_ID" ]; then print_error "No exercise ID available" return 1 fi # Submit a test answer local response=$(api_request "POST" "/api/exercises/$EXERCISE_ID/submit" "{\"answer\":\"42\",\"timeSpent\":60}" "$USER_TOKEN") if echo "$response" | grep -q "correct"; then print_success "Exercise submitted successfully" return 0 else print_error "Failed to submit exercise" print_info "Response: $response" return 1 fi } # Function to test getting user progress test_get_progress() { print_test "Get User Progress" local response=$(api_request "GET" "/api/users/progress" "" "$USER_TOKEN") if echo "$response" | grep -q "progress"; then print_success "Retrieved user progress" return 0 else print_error "Failed to retrieve progress" print_info "Response: $response" return 1 fi } # Function to test getting ranking test_get_ranking() { print_test "Get User Ranking" local response=$(api_request "GET" "/api/users/ranking?limit=10" "" "$USER_TOKEN") if echo "$response" | grep -q "ranking"; then print_success "Retrieved user ranking" return 0 else print_error "Failed to retrieve ranking" print_info "Response: $response" return 1 fi } # Function to test getting achievements test_get_achievements() { print_test "Get User Achievements" local response=$(api_request "GET" "/api/users/achievements" "" "$USER_TOKEN") if echo "$response" | grep -q "achievements"; then ACHIEVEMENT_COUNT=$(echo "$response" | grep -o '"id"' | wc -l) print_success "Retrieved $ACHIEVEMENT_COUNT achievements" return 0 else print_error "Failed to retrieve achievements" print_info "Response: $response" return 1 fi } # Function to test updating user profile test_update_profile() { print_test "Update User Profile" local new_name="Updated Test User" local response=$(api_request "PUT" "/api/users/profile" "{\"name\":\"$new_name\"}" "$USER_TOKEN") if echo "$response" | grep -q "name"; then print_success "Profile updated successfully" return 0 else print_error "Failed to update profile" print_info "Response: $response" return 1 fi } # Function to test health endpoint test_health() { print_test "Health Check Endpoint" local response=$(curl -s "$API_BASE_URL/health") if echo "$response" | grep -q "status.*ok\|healthy"; then print_success "Health check passed" return 0 else print_error "Health check failed" print_info "Response: $response" return 1 fi } # Function to test frontend accessibility test_frontend() { print_test "Frontend Accessibility" local response=$(curl -s -o /dev/null -w "%{http_code}" "$FRONTEND_URL") if [ "$response" = "200" ]; then print_success "Frontend is accessible" return 0 else print_error "Frontend returned status code: $response" return 1 fi } # Function to run all tests run_all_tests() { print_header "Math Platform E2E Test Suite" # Check if services are running print_info "Checking service availability..." if ! wait_for_service "$API_BASE_URL/health"; then print_error "Backend service is not available. Please start the services first." print_info "Run: ./docker/start.sh" exit 1 fi if ! wait_for_service "$FRONTEND_URL"; then print_error "Frontend service is not available. Please start the services first." print_info "Run: ./docker/start.sh" exit 1 fi echo -e "\n${GREEN}All services are running! Starting tests...${NC}\n" # Run tests test_health test_frontend test_registration test_login test_get_modules test_access_module test_get_exercises test_submit_exercise test_get_progress test_get_ranking test_get_achievements test_update_profile # Print summary print_header "Test Summary" echo -e "Total Tests: $TESTS_TOTAL" echo -e "${GREEN}Passed: $TESTS_PASSED${NC}" echo -e "${RED}Failed: $TESTS_FAILED${NC}" if [ $TESTS_FAILED -eq 0 ]; then echo -e "\n${GREEN}All tests passed!${NC}\n" exit 0 else echo -e "\n${RED}Some tests failed!${NC}\n" exit 1 fi } # Function to run specific test run_specific_test() { local test_name=$1 case $test_name in "health") test_health ;; "frontend") test_frontend ;; "register") test_registration ;; "login") test_login ;; "modules") test_get_modules ;; "module") test_access_module ;; "exercises") test_get_exercises ;; "submit") test_submit_exercise ;; "progress") test_get_progress ;; "ranking") test_get_ranking ;; "achievements") test_get_achievements ;; "profile") test_update_profile ;; *) print_error "Unknown test: $test_name" echo "Available tests: health, frontend, register, login, modules, module, exercises, submit, progress, ranking, achievements, profile" exit 1 ;; esac } # Main execution main() { if [ $# -eq 0 ]; then run_all_tests else run_specific_test "$1" fi } # Run main function main "$@"