/ 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