#!/usr/bin/env python3 """Test script to verify Pushover push notification connectivity. This script tests Pushover API connectivity and sends test notifications to help verify that the configuration is correct. """ import sys import time from datetime import datetime # Load configuration from config.yaml try: from alpine_bits_python.config_loader import load_config from pushover_complete import PushoverAPI print("Loading configuration from config.yaml...") config = load_config() pushover_config = config.get("pushover", {}) USER_KEY = pushover_config.get("user_key", "") API_TOKEN = pushover_config.get("api_token", "") # Get monitoring configuration monitoring_config = pushover_config.get("monitoring", {}) daily_report_config = monitoring_config.get("daily_report", {}) error_alerts_config = monitoring_config.get("error_alerts", {}) DAILY_REPORT_ENABLED = daily_report_config.get("enabled", False) DAILY_REPORT_PRIORITY = daily_report_config.get("priority", 0) ERROR_ALERTS_ENABLED = error_alerts_config.get("enabled", False) ERROR_ALERTS_PRIORITY = error_alerts_config.get("priority", 1) print(f"✓ Configuration loaded successfully") print(f" User Key: {USER_KEY[:10]}... (hidden)" if USER_KEY else " User Key: (not set)") print(f" API Token: {API_TOKEN[:10]}... (hidden)" if API_TOKEN else " API Token: (not set)") print(f" Daily Reports: {'Enabled' if DAILY_REPORT_ENABLED else 'Disabled'} (priority: {DAILY_REPORT_PRIORITY})") print(f" Error Alerts: {'Enabled' if ERROR_ALERTS_ENABLED else 'Disabled'} (priority: {ERROR_ALERTS_PRIORITY})") print() if not USER_KEY or not API_TOKEN: print("✗ Pushover credentials not configured!") print() print("Please add the following to your secrets.yaml:") print(" PUSHOVER_USER_KEY: your-user-key-here") print(" PUSHOVER_API_TOKEN: your-app-token-here") print() print("Get your credentials from https://pushover.net") sys.exit(1) except Exception as e: print(f"✗ Failed to load configuration: {e}") print() print("Make sure you have:") print("1. config.yaml with pushover section") print("2. secrets.yaml with PUSHOVER_USER_KEY and PUSHOVER_API_TOKEN") sys.exit(1) def test_simple_notification() -> bool: """Test sending a simple notification.""" print("Test 1: Sending simple test notification...") try: api = PushoverAPI(API_TOKEN) api.send_message( user=USER_KEY, title="Pushover Test", message=f"Test notification from AlpineBits server at {datetime.now().strftime('%H:%M:%S')}", ) print("✓ Simple notification sent successfully") print(" Check your Pushover device for the notification!") return True except Exception as e: print(f"✗ Failed to send notification: {e}") return False def test_priority_levels() -> bool: """Test different priority levels.""" print("\nTest 2: Testing priority levels...") priorities = [ (-2, "Lowest", "No alert, quiet notification"), (-1, "Low", "No alert"), (0, "Normal", "Standard notification"), (1, "High", "Bypasses quiet hours"), ] success_count = 0 for i, (priority, name, description) in enumerate(priorities): try: api = PushoverAPI(API_TOKEN) api.send_message( user=USER_KEY, title=f"Priority Test: {name}", message=f"Testing priority {priority} - {description}", priority=priority, ) print(f"✓ Sent notification with priority {priority} ({name})") success_count += 1 # Add delay between notifications to avoid rate limiting (except after last one) if i < len(priorities) - 1: time.sleep(1) except Exception as e: print(f"✗ Failed to send priority {priority} notification: {e}") print(f" {success_count}/{len(priorities)} priority notifications sent") return success_count == len(priorities) def test_daily_report_format() -> bool: """Test sending a message formatted like a daily report.""" print("\nTest 3: Testing daily report format...") # Sample stats similar to what the app would generate date_str = datetime.now().strftime("%Y-%m-%d") stats = { "reporting_period": { "start": "2025-10-15 08:00:00", "end": "2025-10-16 08:00:00", }, "total_reservations": 12, "hotels": [ {"hotel_name": "Bemelmans Post", "reservations": 5}, {"hotel_name": "Jagthof Kaltern", "reservations": 4}, {"hotel_name": "Residence Erika", "reservations": 3}, ], } # Build message similar to pushover_service.py lines = [f"Report for {date_str}", ""] period = stats.get("reporting_period", {}) if period: start = period.get("start", "").split(" ")[1] if " " in period.get("start", "") else "" end = period.get("end", "").split(" ")[1] if " " in period.get("end", "") else "" if start and end: lines.append(f"Period: {start} - {end}") total = stats.get("total_reservations", 0) lines.append(f"Total Reservations: {total}") hotels = stats.get("hotels", []) if hotels: lines.append("") lines.append("By Hotel:") for hotel in hotels[:5]: hotel_name = hotel.get("hotel_name", "Unknown") count = hotel.get("reservations", 0) if len(hotel_name) > 20: hotel_name = hotel_name[:17] + "..." lines.append(f" • {hotel_name}: {count}") message = "\n".join(lines) try: api = PushoverAPI(API_TOKEN) api.send_message( user=USER_KEY, title=f"AlpineBits Daily Report - {date_str}", message=message, priority=DAILY_REPORT_PRIORITY, ) print("✓ Daily report format notification sent successfully") print(f" Message preview:\n{message}") return True except Exception as e: print(f"✗ Failed to send daily report notification: {e}") return False def test_error_alert_format() -> bool: """Test sending a message formatted like an error alert.""" print("\nTest 4: Testing error alert format...") error_count = 3 title = f"🚨 AlpineBits Error Alert: {error_count} errors" message = f"""Error Alert - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} Alert Type: Test Alert Error Count: {error_count} Time Range: 14:30:00 to 14:45:00 Sample errors (see logs for details): 1. Database connection timeout 2. SMTP connection failed 3. API rate limit exceeded""" try: api = PushoverAPI(API_TOKEN) api.send_message( user=USER_KEY, title=title, message=message, priority=ERROR_ALERTS_PRIORITY, ) print("✓ Error alert format notification sent successfully") return True except Exception as e: print(f"✗ Failed to send error alert notification: {e}") return False def test_with_url() -> bool: """Test notification with supplementary URL.""" print("\nTest 5: Testing notification with URL...") try: api = PushoverAPI(API_TOKEN) api.send_message( user=USER_KEY, title="AlpineBits Server", message="This notification includes a supplementary URL. Tap to open.", url="https://github.com/anthropics/claude-code", url_title="View on GitHub", ) print("✓ Notification with URL sent successfully") return True except Exception as e: print(f"✗ Failed to send notification with URL: {e}") return False def validate_credentials() -> bool: """Validate Pushover credentials.""" print("Test 0: Validating Pushover credentials...") try: api = PushoverAPI(API_TOKEN) # Try to validate the user key response = api.send_message( user=USER_KEY, title="Credential Validation", message="If you receive this, your Pushover credentials are valid!", ) print("✓ Credentials validated successfully") return True except Exception as e: print(f"✗ Credential validation failed: {e}") print() print("Possible issues:") print("1. Invalid API token (check your application settings)") print("2. Invalid user key (check your user dashboard)") print("3. Network connectivity issues") print("4. Pushover service is down") return False def main(): """Run all Pushover tests.""" print("=" * 70) print("Pushover Push Notification Test Script") print("=" * 70) print() # First validate credentials if not validate_credentials(): print("\n" + "=" * 70) print("FAILED: Cannot proceed without valid credentials") print("=" * 70) return 1 print() # Run all tests tests = [ ("Simple Notification", test_simple_notification), ("Priority Levels", test_priority_levels), ("Daily Report Format", test_daily_report_format), ("Error Alert Format", test_error_alert_format), ("Notification with URL", test_with_url), ] results = [] for i, (test_name, test_func) in enumerate(tests): try: result = test_func() results.append((test_name, result)) # Add delay between tests to avoid rate limiting (except after last one) if i < len(tests) - 1: print(" (Waiting 1 second to avoid rate limiting...)") time.sleep(1) except Exception as e: print(f"✗ Test '{test_name}' crashed: {e}") results.append((test_name, False)) # Print summary print("\n" + "=" * 70) print("TEST SUMMARY") print("=" * 70) passed = sum(1 for _, result in results if result) total = len(results) for test_name, result in results: status = "✓ PASS" if result else "✗ FAIL" print(f" {status}: {test_name}") print() print(f"Results: {passed}/{total} tests passed") if passed == total: print("\n✓ ALL TESTS PASSED!") print("=" * 70) print("\nYour Pushover configuration is working correctly.") print("Check your Pushover device for all the test notifications.") return 0 else: print(f"\n⚠ {total - passed} TEST(S) FAILED") print("=" * 70) print("\nSome tests failed. Check the output above for details.") return 1 if __name__ == "__main__": try: sys.exit(main()) except KeyboardInterrupt: print("\n\nTest cancelled by user") sys.exit(1)