189 lines
7.4 KiB
Python
Executable File
189 lines
7.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
"""
|
||
Test script to verify the calendar server functionality.
|
||
Run with: python test_server.py
|
||
"""
|
||
|
||
import asyncio
|
||
import sys
|
||
from datetime import datetime
|
||
import httpx
|
||
import json
|
||
from pathlib import Path
|
||
|
||
# ANSI color codes for terminal output
|
||
GREEN = '\033[92m'
|
||
RED = '\033[91m'
|
||
YELLOW = '\033[93m'
|
||
BLUE = '\033[94m'
|
||
RESET = '\033[0m'
|
||
BOLD = '\033[1m'
|
||
|
||
|
||
def print_status(status: str, message: str):
|
||
"""Print colored status messages."""
|
||
if status == "success":
|
||
print(f"{GREEN}✓{RESET} {message}")
|
||
elif status == "error":
|
||
print(f"{RED}✗{RESET} {message}")
|
||
elif status == "warning":
|
||
print(f"{YELLOW}⚠{RESET} {message}")
|
||
elif status == "info":
|
||
print(f"{BLUE}ℹ{RESET} {message}")
|
||
|
||
|
||
async def test_server():
|
||
"""Run tests against the calendar server."""
|
||
base_url = "http://localhost:8000"
|
||
|
||
print(f"\n{BOLD}Calendar Server Test Suite{RESET}")
|
||
print("=" * 50)
|
||
|
||
# Test 1: Check if server is running
|
||
print(f"\n{BOLD}1. Server Connectivity Test{RESET}")
|
||
try:
|
||
async with httpx.AsyncClient(timeout=5.0) as client:
|
||
response = await client.get(f"{base_url}/")
|
||
if response.status_code == 200:
|
||
print_status("success", f"Server is running at {base_url}")
|
||
else:
|
||
print_status("error", f"Server returned status code: {response.status_code}")
|
||
return False
|
||
except httpx.ConnectError:
|
||
print_status("error", "Cannot connect to server. Please ensure it's running with: ./run.sh")
|
||
return False
|
||
except Exception as e:
|
||
print_status("error", f"Connection error: {e}")
|
||
return False
|
||
|
||
# Test 2: Check HTML interface
|
||
print(f"\n{BOLD}2. HTML Interface Test{RESET}")
|
||
try:
|
||
async with httpx.AsyncClient(timeout=5.0) as client:
|
||
response = await client.get(f"{base_url}/")
|
||
content = response.text
|
||
|
||
if "Turmli Bar Calendar" in content:
|
||
print_status("success", "HTML interface is rendering correctly")
|
||
else:
|
||
print_status("warning", "HTML interface might not be rendering correctly")
|
||
|
||
if "Last updated:" in content:
|
||
print_status("success", "Calendar update timestamp is displayed")
|
||
else:
|
||
print_status("warning", "Update timestamp not found")
|
||
except Exception as e:
|
||
print_status("error", f"HTML interface test failed: {e}")
|
||
|
||
# Test 3: Check API endpoints
|
||
print(f"\n{BOLD}3. API Endpoints Test{RESET}")
|
||
|
||
# Test GET /api/events
|
||
try:
|
||
async with httpx.AsyncClient(timeout=5.0) as client:
|
||
response = await client.get(f"{base_url}/api/events")
|
||
if response.status_code == 200:
|
||
data = response.json()
|
||
print_status("success", "GET /api/events endpoint is working")
|
||
|
||
if "events" in data:
|
||
event_count = len(data["events"])
|
||
print_status("info", f"Found {event_count} event(s) in calendar")
|
||
|
||
if event_count > 0:
|
||
# Display first event
|
||
first_event = data["events"][0]
|
||
print_status("info", f"Next event: {first_event.get('title', 'N/A')}")
|
||
if first_event.get('start'):
|
||
start_time = datetime.fromisoformat(first_event['start'].replace('Z', '+00:00'))
|
||
print_status("info", f"Date: {start_time.strftime('%Y-%m-%d %H:%M')}")
|
||
else:
|
||
print_status("warning", "Events data structure not found")
|
||
|
||
if "last_updated" in data and data["last_updated"]:
|
||
print_status("success", f"Last updated: {data['last_updated']}")
|
||
else:
|
||
print_status("error", f"API returned status code: {response.status_code}")
|
||
except Exception as e:
|
||
print_status("error", f"API events test failed: {e}")
|
||
|
||
# Test POST /api/refresh
|
||
print(f"\n{BOLD}4. Manual Refresh Test{RESET}")
|
||
try:
|
||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||
print_status("info", "Triggering manual calendar refresh...")
|
||
response = await client.post(f"{base_url}/api/refresh")
|
||
if response.status_code == 200:
|
||
data = response.json()
|
||
if data.get("status") == "success":
|
||
print_status("success", f"Calendar refreshed successfully")
|
||
print_status("info", f"Total events: {data.get('events_count', 0)}")
|
||
else:
|
||
print_status("warning", "Refresh completed with unexpected status")
|
||
else:
|
||
print_status("error", f"Refresh returned status code: {response.status_code}")
|
||
except Exception as e:
|
||
print_status("error", f"Manual refresh test failed: {e}")
|
||
|
||
# Test 5: Check cache file
|
||
print(f"\n{BOLD}5. Cache File Test{RESET}")
|
||
cache_file = Path("calendar_cache.json")
|
||
if cache_file.exists():
|
||
print_status("success", "Cache file exists")
|
||
try:
|
||
with open(cache_file, 'r') as f:
|
||
cache_data = json.load(f)
|
||
if "events" in cache_data:
|
||
print_status("success", f"Cache contains {len(cache_data['events'])} event(s)")
|
||
if "last_fetch" in cache_data:
|
||
last_fetch = datetime.fromisoformat(cache_data['last_fetch'])
|
||
print_status("info", f"Cache last updated: {last_fetch.strftime('%Y-%m-%d %H:%M:%S')}")
|
||
except Exception as e:
|
||
print_status("warning", f"Could not read cache file: {e}")
|
||
else:
|
||
print_status("warning", "Cache file not found (will be created on first fetch)")
|
||
|
||
# Test 6: Mobile responsiveness check
|
||
print(f"\n{BOLD}6. Mobile Responsiveness Test{RESET}")
|
||
try:
|
||
async with httpx.AsyncClient(timeout=5.0) as client:
|
||
# Simulate mobile user agent
|
||
headers = {
|
||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15"
|
||
}
|
||
response = await client.get(f"{base_url}/", headers=headers)
|
||
content = response.text
|
||
|
||
if 'viewport' in content and 'width=device-width' in content:
|
||
print_status("success", "Mobile viewport meta tag found")
|
||
else:
|
||
print_status("warning", "Mobile viewport configuration might be missing")
|
||
|
||
if 'background: #f5f5f5' in content:
|
||
print_status("success", "Simplified design detected")
|
||
else:
|
||
print_status("warning", "Design might not be using simplified styles")
|
||
except Exception as e:
|
||
print_status("error", f"Mobile responsiveness test failed: {e}")
|
||
|
||
print(f"\n{BOLD}Test Summary{RESET}")
|
||
print("=" * 50)
|
||
print_status("info", "All basic tests completed")
|
||
print_status("info", f"Server URL: {base_url}")
|
||
print_status("info", "You can now access the calendar in your browser")
|
||
|
||
return True
|
||
|
||
|
||
async def main():
|
||
"""Main function to run tests."""
|
||
success = await test_server()
|
||
sys.exit(0 if success else 1)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
asyncio.run(main())
|
||
except KeyboardInterrupt:
|
||
print("\n\nTests interrupted by user")
|
||
sys.exit(0) |