""" Integration tests for ntfy topics. """ import json import time import urllib.request class TestNtfyTopics: def test_cc_topic_exists_and_writable(self): """Verify C&C topic exists and accepts messages.""" from engine.config import NTFY_CC_TOPIC topic_url = NTFY_CC_TOPIC.replace("/json", "") test_message = f"test_{int(time.time())}" req = urllib.request.Request( topic_url, data=test_message.encode("utf-8"), headers={ "User-Agent": "mainline-test/0.1", "Content-Type": "text/plain", }, method="POST", ) try: with urllib.request.urlopen(req, timeout=10) as resp: assert resp.status == 200 except Exception as e: raise AssertionError(f"Failed to write to C&C topic: {e}") from e def test_message_topic_exists_and_writable(self): """Verify message topic exists and accepts messages.""" from engine.config import NTFY_TOPIC topic_url = NTFY_TOPIC.replace("/json", "") test_message = f"test_{int(time.time())}" req = urllib.request.Request( topic_url, data=test_message.encode("utf-8"), headers={ "User-Agent": "mainline-test/0.1", "Content-Type": "text/plain", }, method="POST", ) try: with urllib.request.urlopen(req, timeout=10) as resp: assert resp.status == 200 except Exception as e: raise AssertionError(f"Failed to write to message topic: {e}") from e def test_cc_topic_readable(self): """Verify we can read messages from C&C topic.""" from engine.config import NTFY_CC_TOPIC test_message = f"integration_test_{int(time.time())}" topic_url = NTFY_CC_TOPIC.replace("/json", "") req = urllib.request.Request( topic_url, data=test_message.encode("utf-8"), headers={ "User-Agent": "mainline-test/0.1", "Content-Type": "text/plain", }, method="POST", ) try: urllib.request.urlopen(req, timeout=10) except Exception as e: raise AssertionError(f"Failed to write to C&C topic: {e}") from e time.sleep(1) poll_url = f"{NTFY_CC_TOPIC}?poll=1&limit=1" req = urllib.request.Request( poll_url, headers={"User-Agent": "mainline-test/0.1"}, ) try: with urllib.request.urlopen(req, timeout=10) as resp: body = resp.read().decode("utf-8") if body.strip(): data = json.loads(body.split("\n")[0]) assert isinstance(data, dict) except Exception as e: raise AssertionError(f"Failed to read from C&C topic: {e}") from e def test_topics_are_different(self): """Verify C&C and message topics are different.""" from engine.config import NTFY_CC_TOPIC, NTFY_TOPIC assert NTFY_CC_TOPIC != NTFY_TOPIC assert "_cc" in NTFY_CC_TOPIC