#!/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)