asteroid/test-server.sh

361 lines
9.3 KiB
Bash
Executable File

#!/bin/bash
# test-server.sh - Comprehensive test suite for Asteroid Radio server
# Tests all API endpoints and core functionality
set -e # Exit on error
# 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
BASE_URL="${ASTEROID_URL:-http://localhost:8080}"
API_BASE="${BASE_URL}/api/asteroid"
VERBOSE="${VERBOSE:-0}"
# Test counters
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0
# Helper functions
print_header() {
echo -e "\n${BLUE}========================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}========================================${NC}\n"
}
print_test() {
echo -e "${YELLOW}TEST:${NC} $1"
}
print_pass() {
echo -e "${GREEN}✓ PASS:${NC} $1"
TESTS_PASSED=$((TESTS_PASSED + 1))
}
print_fail() {
echo -e "${RED}✗ FAIL:${NC} $1"
TESTS_FAILED=$((TESTS_FAILED + 1))
}
print_info() {
echo -e "${BLUE}INFO:${NC} $1"
}
# Test function wrapper
run_test() {
local test_name="$1"
TESTS_RUN=$((TESTS_RUN + 1))
print_test "$test_name"
}
# Check if server is running
check_server() {
print_header "Checking Server Status"
run_test "Server is accessible"
if curl -s --max-time 5 "${BASE_URL}/asteroid/" > /dev/null 2>&1; then
print_pass "Server is running at ${BASE_URL}"
else
print_fail "Server is not accessible at ${BASE_URL}"
echo "Please start the server with: ./asteroid"
exit 1
fi
}
# Test API endpoint with JSON response
test_api_endpoint() {
local endpoint="$1"
local description="$2"
local expected_field="$3"
local method="${4:-GET}"
local data="${5:-}"
run_test "$description"
local url="${API_BASE}${endpoint}"
local response
if [ "$method" = "POST" ]; then
response=$(curl -s -X POST "$url" ${data:+-d "$data"})
else
response=$(curl -s "$url")
fi
if [ $VERBOSE -eq 1 ]; then
echo "Response: $response" | head -c 200
echo "..."
fi
# Check if response contains expected field
if echo "$response" | grep -q "$expected_field"; then
print_pass "$description - Response contains '$expected_field'"
return 0
else
print_fail "$description - Expected field '$expected_field' not found"
if [ $VERBOSE -eq 1 ]; then
echo "Full response: $response"
fi
return 1
fi
}
# Test JSON structure
test_json_structure() {
local endpoint="$1"
local description="$2"
local jq_query="$3"
run_test "$description"
local url="${API_BASE}${endpoint}"
local response=$(curl -s "$url")
# Check if jq is available
if ! command -v jq &> /dev/null; then
print_info "jq not installed, skipping JSON validation"
return 0
fi
if echo "$response" | jq -e "$jq_query" > /dev/null 2>&1; then
print_pass "$description"
return 0
else
print_fail "$description"
if [ $VERBOSE -eq 1 ]; then
echo "Response: $response"
fi
return 1
fi
}
# Test Status Endpoints
test_status_endpoints() {
print_header "Testing Status Endpoints"
test_api_endpoint "/status" \
"Server status endpoint" \
"asteroid-radio"
test_api_endpoint "/auth-status" \
"Authentication status endpoint" \
"loggedIn"
test_api_endpoint "/icecast-status" \
"Icecast status endpoint" \
"icestats"
}
# Test Admin Endpoints (requires authentication)
test_admin_endpoints() {
print_header "Testing Admin Endpoints"
print_info "Note: Admin endpoints require authentication"
test_api_endpoint "/admin/tracks" \
"Admin tracks listing" \
"data"
# Note: scan-library is POST and modifies state, so we just check it exists
run_test "Admin scan-library endpoint exists"
local response=$(curl -s -X POST "${API_BASE}/admin/scan-library")
if echo "$response" | grep -q "status"; then
print_pass "Admin scan-library endpoint responds"
else
print_fail "Admin scan-library endpoint not responding"
fi
}
# Test Track Endpoints
test_track_endpoints() {
print_header "Testing Track Endpoints"
test_api_endpoint "/tracks" \
"Tracks listing endpoint" \
"data"
}
# Test Player Endpoints
test_player_endpoints() {
print_header "Testing Player Control Endpoints"
test_api_endpoint "/player/status" \
"Player status endpoint" \
"player"
test_api_endpoint "/player/pause" \
"Player pause endpoint" \
"status"
test_api_endpoint "/player/stop" \
"Player stop endpoint" \
"status"
test_api_endpoint "/player/resume" \
"Player resume endpoint" \
"status"
}
# Test Playlist Endpoints
test_playlist_endpoints() {
print_header "Testing Playlist Endpoints"
test_api_endpoint "/playlists" \
"Playlists listing endpoint" \
"data"
# Test playlist creation (requires auth)
print_info "Note: Playlist creation requires authentication"
}
# Test Page Endpoints (HTML pages)
test_page_endpoints() {
print_header "Testing HTML Page Endpoints"
run_test "Front page loads"
if curl -s "${BASE_URL}/asteroid/" | grep -q "ASTEROID RADIO"; then
print_pass "Front page loads successfully"
else
print_fail "Front page not loading"
fi
run_test "Admin page loads"
if curl -s "${BASE_URL}/asteroid/admin" | grep -q "ADMIN DASHBOARD"; then
print_pass "Admin page loads successfully"
else
print_fail "Admin page not loading"
fi
run_test "Player page loads"
if curl -s "${BASE_URL}/asteroid/player" | grep -q "Web Player"; then
print_pass "Player page loads successfully"
else
print_fail "Player page not loading"
fi
}
# Test Static File Serving
test_static_files() {
print_header "Testing Static File Serving"
run_test "CSS file loads"
if curl -s -I "${BASE_URL}/asteroid/static/asteroid.css" | grep -q "200 OK"; then
print_pass "CSS file accessible"
else
print_fail "CSS file not accessible"
fi
run_test "JavaScript files load"
if curl -s -I "${BASE_URL}/asteroid/static/js/player.js" | grep -q "200 OK"; then
print_pass "JavaScript files accessible"
else
print_fail "JavaScript files not accessible"
fi
}
# Test API Response Format
test_api_format() {
print_header "Testing API Response Format"
run_test "API returns JSON format"
local response=$(curl -s "${API_BASE}/status")
if echo "$response" | grep -q '"status"'; then
print_pass "API returns JSON (not S-expressions)"
else
print_fail "API not returning proper JSON format"
if [ $VERBOSE -eq 1 ]; then
echo "Response: $response"
fi
fi
}
# Print summary
print_summary() {
print_header "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 "\n${GREEN}✓ All tests passed!${NC}\n"
exit 0
else
echo -e "\n${RED}✗ Some tests failed${NC}\n"
exit 1
fi
}
# Main test execution
main() {
echo -e "${BLUE}"
echo "╔═══════════════════════════════════════╗"
echo "║ Asteroid Radio Server Test Suite ║"
echo "╔═══════════════════════════════════════╗"
echo -e "${NC}"
print_info "Testing server at: ${BASE_URL}"
print_info "Verbose mode: ${VERBOSE}"
echo ""
# Run all test suites
check_server
test_api_format
test_status_endpoints
test_track_endpoints
test_player_endpoints
test_playlist_endpoints
test_admin_endpoints
test_page_endpoints
test_static_files
# Print summary
print_summary
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-v|--verbose)
VERBOSE=1
shift
;;
-u|--url)
BASE_URL="$2"
API_BASE="${BASE_URL}/api/asteroid"
shift 2
;;
-h|--help)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -v, --verbose Enable verbose output"
echo " -u, --url URL Set base URL (default: http://localhost:8080)"
echo " -h, --help Show this help message"
echo ""
echo "Environment variables:"
echo " ASTEROID_URL Base URL for the server"
echo " VERBOSE Enable verbose output (0 or 1)"
echo ""
echo "Examples:"
echo " $0 # Test local server"
echo " $0 -v # Verbose mode"
echo " $0 -u http://example.com # Test remote server"
exit 0
;;
*)
echo "Unknown option: $1"
echo "Use -h or --help for usage information"
exit 1
;;
esac
done
# Run main
main