Files
ProxMenux/AppImage/scripts/tests/test_pushover_channel.py
T
MacRimi fcfe8da765 refine post-install and hardware GPU docs, Monitor UX and CLI styling
- rewrite the 15 post-install pages and the 3 hardware GPU pages so they reflect the current scripts (reversibility, tracked-tool counts, kernel parameters, per-tool commands, Alpine LXC propagation flow)
- migrate the legacy step-badge helper on post-install/optional and create-vm/synology to the canonical pill component, with the stepLabel key added in each locale
- fix rich-text i18n calls missing helpers across network, automated, optional, security, customization and the post-install landing pages, and escape the `<iface>` placeholder in automated so intl no longer parses it as a tag
- remove the mouse-follow blue overlay from the docs landing layout
- reposition the App-tab Edit button and stack the Search and Register controls vertically on mobile
- move the Bulk update Configure/Edit control into the section header so it behaves the same on desktop and mobile
- show a spinner during the final autoremove/autoclean pass of update-pve-safe so the cleanup step reads as active instead of silent
- restyle the shell spinner and msg_info in a distinctive purple and drop the unused msg_lang duplicate
- add a web-docs i18n build script and its CI workflow, plus tests for the pushover notification channel
2026-08-26 17:23:09 +02:00

107 lines
3.6 KiB
Python

import sys
import unittest
import urllib.parse
from pathlib import Path
SCRIPTS_DIR = Path(__file__).resolve().parents[1]
if str(SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(SCRIPTS_DIR))
from notification_channels import PushoverChannel, create_channel
class PushoverChannelTests(unittest.TestCase):
USER_KEY = "u" * 30
API_TOKEN = "a" * 30
def make_channel(self, **kwargs):
channel = PushoverChannel(
user_key=kwargs.pop("user_key", self.USER_KEY),
api_token=kwargs.pop("api_token", self.API_TOKEN),
**kwargs,
)
channel.MAX_RETRIES = 1
return channel
def test_requires_valid_user_key_and_api_token(self):
channel = self.make_channel(user_key="")
self.assertEqual(channel.validate_config(), (
False, "Pushover user or group key is required"
))
channel = self.make_channel(api_token="short")
self.assertEqual(channel.validate_config(), (
False, "Invalid Pushover application API token format"
))
def test_optional_device_sound_and_factory(self):
channel = create_channel("pushover", {
"user_key": self.USER_KEY,
"api_token": self.API_TOKEN,
"device": "iphone_15",
"sound": "magic",
"critical_priority": "false",
})
self.assertIsInstance(channel, PushoverChannel)
self.assertEqual(channel.validate_config(), (True, ""))
self.assertFalse(channel.critical_priority)
def test_critical_alert_uses_high_priority_and_api_limits(self):
channel = self.make_channel(
device="iphone_15",
sound="magic",
critical_priority="true",
)
request = {}
def fake_http(url, data, headers):
request["url"] = url
request["payload"] = urllib.parse.parse_qs(data.decode("utf-8"))
request["headers"] = headers
return 200, '{"status":1,"request":"test"}'
channel._http_request = fake_http
result = channel.send("T" * 300, "M" * 1200, "critical")
self.assertTrue(result["success"])
self.assertEqual(request["url"], PushoverChannel.API_URL)
self.assertEqual(request["payload"]["priority"], ["1"])
self.assertEqual(request["payload"]["device"], ["iphone_15"])
self.assertEqual(request["payload"]["sound"], ["magic"])
self.assertEqual(len(request["payload"]["title"][0]), 250)
self.assertEqual(len(request["payload"]["message"][0]), 1024)
self.assertTrue(request["payload"]["message"][0].endswith("…"))
def test_noncritical_alert_uses_normal_priority(self):
channel = self.make_channel(critical_priority="true")
request = {}
def fake_http(url, data, headers):
request["payload"] = urllib.parse.parse_qs(data.decode("utf-8"))
return 200, '{"status":1}'
channel._http_request = fake_http
result = channel.send("Warning", "Message", "WARNING")
self.assertTrue(result["success"])
self.assertEqual(request["payload"]["priority"], ["0"])
def test_api_error_does_not_expose_credentials(self):
channel = self.make_channel()
channel._http_request = lambda *args: (
400, '{"status":0,"errors":["user identifier is invalid"]}'
)
result = channel.send("Title", "Message")
self.assertFalse(result["success"])
self.assertIn("user identifier is invalid", result["error"])
self.assertNotIn(self.USER_KEY, result["error"])
self.assertNotIn(self.API_TOKEN, result["error"])
if __name__ == "__main__":
unittest.main()