/ test-server.sh
test-server.sh
1 #!/bin/bash 2 # test-server.sh - Comprehensive test suite for Asteroid Radio server 3 # Tests all API endpoints and core functionality 4 5 set -e # Exit on error 6 7 # Colors for output 8 RED='\033[0;31m' 9 GREEN='\033[0;32m' 10 YELLOW='\033[1;33m' 11 BLUE='\033[0;34m' 12 NC='\033[0m' # No Color 13 14 # Configuration 15 BASE_URL="${ASTEROID_URL:-http://localhost:8080}" 16 API_BASE="${BASE_URL}/api/asteroid" 17 VERBOSE="${VERBOSE:-0}" 18 19 # Test counters 20 TESTS_RUN=0 21 TESTS_PASSED=0 22 TESTS_FAILED=0 23 24 # Helper functions 25 print_header() { 26 echo -e "\n${BLUE}========================================${NC}" 27 echo -e "${BLUE}$1${NC}" 28 echo -e "${BLUE}========================================${NC}\n" 29 } 30 31 print_test() { 32 echo -e "${YELLOW}TEST:${NC} $1" 33 } 34 35 print_pass() { 36 echo -e "${GREEN}✓ PASS:${NC} $1" 37 TESTS_PASSED=$((TESTS_PASSED + 1)) 38 } 39 40 print_fail() { 41 echo -e "${RED}✗ FAIL:${NC} $1" 42 TESTS_FAILED=$((TESTS_FAILED + 1)) 43 } 44 45 print_info() { 46 echo -e "${BLUE}INFO:${NC} $1" 47 } 48 49 # Test function wrapper 50 run_test() { 51 local test_name="$1" 52 TESTS_RUN=$((TESTS_RUN + 1)) 53 print_test "$test_name" 54 } 55 56 # Check if server is running 57 check_server() { 58 print_header "Checking Server Status" 59 run_test "Server is accessible" 60 61 if curl -s --max-time 5 "${BASE_URL}/asteroid/" > /dev/null 2>&1; then 62 print_pass "Server is running at ${BASE_URL}" 63 else 64 print_fail "Server is not accessible at ${BASE_URL}" 65 echo "Please start the server with: ./asteroid" 66 exit 1 67 fi 68 } 69 70 # Test API endpoint with JSON response 71 test_api_endpoint() { 72 local endpoint="$1" 73 local description="$2" 74 local expected_field="$3" 75 local method="${4:-GET}" 76 local data="${5:-}" 77 78 run_test "$description" 79 80 local url="${API_BASE}${endpoint}" 81 local response 82 83 if [ "$method" = "POST" ]; then 84 response=$(curl -s -X POST "$url" ${data:+-d "$data"}) 85 else 86 response=$(curl -s "$url") 87 fi 88 89 if [ $VERBOSE -eq 1 ]; then 90 echo "Response: $response" | head -c 200 91 echo "..." 92 fi 93 94 # Check if response contains expected field 95 if echo "$response" | grep -q "$expected_field"; then 96 print_pass "$description - Response contains '$expected_field'" 97 return 0 98 else 99 print_fail "$description - Expected field '$expected_field' not found" 100 if [ $VERBOSE -eq 1 ]; then 101 echo "Full response: $response" 102 fi 103 return 1 104 fi 105 } 106 107 # Test JSON structure 108 test_json_structure() { 109 local endpoint="$1" 110 local description="$2" 111 local jq_query="$3" 112 113 run_test "$description" 114 115 local url="${API_BASE}${endpoint}" 116 local response=$(curl -s "$url") 117 118 # Check if jq is available 119 if ! command -v jq &> /dev/null; then 120 print_info "jq not installed, skipping JSON validation" 121 return 0 122 fi 123 124 if echo "$response" | jq -e "$jq_query" > /dev/null 2>&1; then 125 print_pass "$description" 126 return 0 127 else 128 print_fail "$description" 129 if [ $VERBOSE -eq 1 ]; then 130 echo "Response: $response" 131 fi 132 return 1 133 fi 134 } 135 136 # Test Status Endpoints 137 test_status_endpoints() { 138 print_header "Testing Status Endpoints" 139 140 test_api_endpoint "/status" \ 141 "Server status endpoint" \ 142 "asteroid-radio" 143 144 test_api_endpoint "/auth-status" \ 145 "Authentication status endpoint" \ 146 "loggedIn" 147 148 test_api_endpoint "/icecast-status" \ 149 "Icecast status endpoint" \ 150 "icestats" 151 } 152 153 # Test Admin Endpoints (requires authentication) 154 test_admin_endpoints() { 155 print_header "Testing Admin Endpoints" 156 157 print_info "Note: Admin endpoints require authentication" 158 159 test_api_endpoint "/admin/tracks" \ 160 "Admin tracks listing" \ 161 "data" 162 163 # Note: scan-library is POST and modifies state, so we just check it exists 164 run_test "Admin scan-library endpoint exists" 165 local response=$(curl -s -X POST "${API_BASE}/admin/scan-library") 166 if echo "$response" | grep -q "status"; then 167 print_pass "Admin scan-library endpoint responds" 168 else 169 print_fail "Admin scan-library endpoint not responding" 170 fi 171 } 172 173 # Test Track Endpoints 174 test_track_endpoints() { 175 print_header "Testing Track Endpoints" 176 177 test_api_endpoint "/tracks" \ 178 "Tracks listing endpoint" \ 179 "data" 180 } 181 182 # Test Player Endpoints 183 test_player_endpoints() { 184 print_header "Testing Player Control Endpoints" 185 186 test_api_endpoint "/player/status" \ 187 "Player status endpoint" \ 188 "player" 189 190 test_api_endpoint "/player/pause" \ 191 "Player pause endpoint" \ 192 "status" 193 194 test_api_endpoint "/player/stop" \ 195 "Player stop endpoint" \ 196 "status" 197 198 test_api_endpoint "/player/resume" \ 199 "Player resume endpoint" \ 200 "status" 201 } 202 203 # Test Playlist Endpoints 204 test_playlist_endpoints() { 205 print_header "Testing Playlist Endpoints" 206 207 test_api_endpoint "/playlists" \ 208 "Playlists listing endpoint" \ 209 "data" 210 211 # Test playlist creation (requires auth) 212 print_info "Note: Playlist creation requires authentication" 213 } 214 215 # Test Page Endpoints (HTML pages) 216 test_page_endpoints() { 217 print_header "Testing HTML Page Endpoints" 218 219 run_test "Front page loads" 220 if curl -s "${BASE_URL}/asteroid/" | grep -q "ASTEROID RADIO"; then 221 print_pass "Front page loads successfully" 222 else 223 print_fail "Front page not loading" 224 fi 225 226 run_test "Admin page loads" 227 if curl -s "${BASE_URL}/asteroid/admin" | grep -q "ADMIN DASHBOARD"; then 228 print_pass "Admin page loads successfully" 229 else 230 print_fail "Admin page not loading" 231 fi 232 233 run_test "Player page loads" 234 if curl -s "${BASE_URL}/asteroid/player" | grep -q "Web Player"; then 235 print_pass "Player page loads successfully" 236 else 237 print_fail "Player page not loading" 238 fi 239 } 240 241 # Test Static File Serving 242 test_static_files() { 243 print_header "Testing Static File Serving" 244 245 run_test "CSS file loads" 246 if curl -s -I "${BASE_URL}/asteroid/static/asteroid.css" | grep -q "200 OK"; then 247 print_pass "CSS file accessible" 248 else 249 print_fail "CSS file not accessible" 250 fi 251 252 run_test "JavaScript files load" 253 if curl -s -I "${BASE_URL}/asteroid/static/js/player.js" | grep -q "200 OK"; then 254 print_pass "JavaScript files accessible" 255 else 256 print_fail "JavaScript files not accessible" 257 fi 258 } 259 260 # Test API Response Format 261 test_api_format() { 262 print_header "Testing API Response Format" 263 264 run_test "API returns JSON format" 265 local response=$(curl -s "${API_BASE}/status") 266 267 if echo "$response" | grep -q '"status"'; then 268 print_pass "API returns JSON (not S-expressions)" 269 else 270 print_fail "API not returning proper JSON format" 271 if [ $VERBOSE -eq 1 ]; then 272 echo "Response: $response" 273 fi 274 fi 275 } 276 277 # Print summary 278 print_summary() { 279 print_header "Test Summary" 280 281 echo "Tests Run: $TESTS_RUN" 282 echo -e "Tests Passed: ${GREEN}$TESTS_PASSED${NC}" 283 echo -e "Tests Failed: ${RED}$TESTS_FAILED${NC}" 284 285 if [ $TESTS_FAILED -eq 0 ]; then 286 echo -e "\n${GREEN}✓ All tests passed!${NC}\n" 287 exit 0 288 else 289 echo -e "\n${RED}✗ Some tests failed${NC}\n" 290 exit 1 291 fi 292 } 293 294 # Main test execution 295 main() { 296 echo -e "${BLUE}" 297 echo "╔═══════════════════════════════════════╗" 298 echo "║ Asteroid Radio Server Test Suite ║" 299 echo "╔═══════════════════════════════════════╗" 300 echo -e "${NC}" 301 302 print_info "Testing server at: ${BASE_URL}" 303 print_info "Verbose mode: ${VERBOSE}" 304 echo "" 305 306 # Run all test suites 307 check_server 308 test_api_format 309 test_status_endpoints 310 test_track_endpoints 311 test_player_endpoints 312 test_playlist_endpoints 313 test_admin_endpoints 314 test_page_endpoints 315 test_static_files 316 317 # Print summary 318 print_summary 319 } 320 321 # Parse command line arguments 322 while [[ $# -gt 0 ]]; do 323 case $1 in 324 -v|--verbose) 325 VERBOSE=1 326 shift 327 ;; 328 -u|--url) 329 BASE_URL="$2" 330 API_BASE="${BASE_URL}/api/asteroid" 331 shift 2 332 ;; 333 -h|--help) 334 echo "Usage: $0 [OPTIONS]" 335 echo "" 336 echo "Options:" 337 echo " -v, --verbose Enable verbose output" 338 echo " -u, --url URL Set base URL (default: http://localhost:8080)" 339 echo " -h, --help Show this help message" 340 echo "" 341 echo "Environment variables:" 342 echo " ASTEROID_URL Base URL for the server" 343 echo " VERBOSE Enable verbose output (0 or 1)" 344 echo "" 345 echo "Examples:" 346 echo " $0 # Test local server" 347 echo " $0 -v # Verbose mode" 348 echo " $0 -u http://example.com # Test remote server" 349 exit 0 350 ;; 351 *) 352 echo "Unknown option: $1" 353 echo "Use -h or --help for usage information" 354 exit 1 355 ;; 356 esac 357 done 358 359 # Run main 360 main