Files
turmlibar-calendar/test_server.py
2025-10-30 13:33:08 +01:00

189 lines
7.4 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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)