diff --git a/hc/api/tests/test_notify_signal.py b/hc/api/tests/test_notify_signal.py index 9c44b798..6b50b063 100644 --- a/hc/api/tests/test_notify_signal.py +++ b/hc/api/tests/test_notify_signal.py @@ -102,6 +102,7 @@ class NotifySignalTestCase(BaseTestCase): self.flip.created = now() self.flip.old_status = "new" self.flip.new_status = "down" + self.flip.reason = "timeout" def get_html(self, email: EmailMessage) -> str: assert isinstance(email, EmailMultiAlternatives) @@ -125,6 +126,7 @@ class NotifySignalTestCase(BaseTestCase): params = socketobj.req["params"] self.assertIn("Daily Backup is DOWN", params["message"]) self.assertEqual(params["textStyle"][0], "10:12:BOLD") + self.assertIn("grace time passed", params["message"]) self.assertIn("Project: Alices Project", params["message"]) self.assertIn("Tags: foo, bar", params["message"]) @@ -137,6 +139,17 @@ class NotifySignalTestCase(BaseTestCase): # other checks: self.assertNotIn("All the other checks are up.", params["message"]) + @patch("hc.api.transports.socket.socket") + def test_it_handles_reason_fail(self, socket: Mock) -> None: + socketobj = setup_mock(socket, {}) + + self.flip.reason = "fail" + self.channel.notify(self.flip) + + assert socketobj.req + params = socketobj.req["params"] + self.assertIn("received a failure signal", params["message"]) + @patch("hc.api.transports.socket.socket") def test_it_shows_exitstatus(self, socket: Mock) -> None: socketobj = setup_mock(socket, {}) @@ -504,15 +517,16 @@ class NotifySignalTestCase(BaseTestCase): email = emails["alice@example.org"] self.assertEqual( email.subject, - "Signal notification failed: The check Foo & Co is DOWN.", + "Signal notification failed: The check Foo & Co is DOWN" + " (success signal did not arrive on time, grace time passed).", ) # The plaintext version should have no HTML markup, and should # have no &, < > stuff: - self.assertIn("The check Foo & Co is DOWN.", email.body) + self.assertIn("The check Foo & Co is DOWN", email.body) # The HTML version should retain styling, and escape special characters # in project name, check name, etc.: html = self.get_html(email) - self.assertIn("The check <b>Foo & Co</b> is <b>DOWN</b>.", html) + self.assertIn("The check <b>Foo & Co</b> is <b>DOWN</b>", html) @patch("hc.api.transports.socket.socket") def test_it_handles_null_data(self, socket: Mock) -> None: diff --git a/hc/api/transports.py b/hc/api/transports.py index f477f23c..c354c881 100644 --- a/hc/api/transports.py +++ b/hc/api/transports.py @@ -1507,7 +1507,7 @@ class Signal(Transport): raise TransportError("signal-cli call timed out") except OSError as e: - msg = "signal-cli call failed (%s)" % e + msg = f"signal-cli call failed ({e})" # Log the exception, so any configured logging handlers can pick it up logger.exception(msg) @@ -1524,6 +1524,7 @@ class Signal(Transport): raise TransportError("Rate limit exceeded") ctx = { + "flip": flip, "check": flip.owner, "status": flip.new_status, "ping": self.last_ping(flip), diff --git a/templates/integrations/signal_message.html b/templates/integrations/signal_message.html index 4d37f2c5..484dd08d 100644 --- a/templates/integrations/signal_message.html +++ b/templates/integrations/signal_message.html @@ -1,6 +1,6 @@ {% load hc_extras humanize linemode %}{% linemode %} {% if status == "down" %} - {% line %}The check <b>{{ check.name_then_code }}</b> is <b>DOWN</b>.{% endline %} + {% line %}The check <b>{{ check.name_then_code }}</b> is <b>DOWN</b>{% if flip.reason %} ({{ flip.reason_long }}){% endif %}.{% endline %} {% else %} {% line %}The check <b>{{ check.name_then_code }}</b> is now <b>UP</b>.{% endline %} {% endif %}