From d8d8d280cae71e9377b135bcc3818ba0dde7714f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C4=93teris=20Caune?= <cuu508@gmail.com>
Date: Tue, 17 Dec 2024 10:09:55 +0200
Subject: [PATCH] Update OpsGenie notification template to include failure
 reason

cc: #1069
---
 hc/api/tests/test_notify_opsgenie.py         | 22 ++++++++++++++++++--
 hc/api/transports.py                         |  4 ++--
 templates/integrations/opsgenie_message.html |  2 +-
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/hc/api/tests/test_notify_opsgenie.py b/hc/api/tests/test_notify_opsgenie.py
index 02a1a6ae..1a43bf47 100644
--- a/hc/api/tests/test_notify_opsgenie.py
+++ b/hc/api/tests/test_notify_opsgenie.py
@@ -1,4 +1,3 @@
-
 from __future__ import annotations
 
 import json
@@ -40,6 +39,7 @@ class NotifyOpsgenieTestCase(BaseTestCase):
         self.flip.created = now()
         self.flip.old_status = "new"
         self.flip.new_status = status
+        self.flip.reason = "timeout"
 
     @patch("hc.api.transports.curl.request", autospec=True)
     def test_it_works(self, mock_post: Mock) -> None:
@@ -52,13 +52,31 @@ class NotifyOpsgenieTestCase(BaseTestCase):
 
         payload = mock_post.call_args.kwargs["json"]
         self.assertEqual(payload["alias"], self.check.unique_key)
-        self.assertIn("""The check "Foo" is DOWN.""", payload["message"])
+        self.assertIn(
+            """The check "Foo" is DOWN (success signal did not arrive """
+            """on time, grace time passed).""",
+            payload["message"],
+        )
 
         details = payload["details"]
         self.assertIn("cloaked", details["Full details"])
         self.assertEqual(details["Last ping"], "Success, 10 minutes ago")
         self.assertEqual(details["Total pings"], 112233)
 
+    @patch("hc.api.transports.curl.request", autospec=True)
+    def test_it_handles_reason_fail(self, mock_post: Mock) -> None:
+        self._setup_data(json.dumps({"key": "123", "region": "us"}))
+        mock_post.return_value.status_code = 202
+
+        self.flip.reason = "fail"
+        self.channel.notify(self.flip)
+
+        payload = mock_post.call_args.kwargs["json"]
+        self.assertIn(
+            """The check "Foo" is DOWN (received a failure signal).""",
+            payload["message"],
+        )
+
     @patch("hc.api.transports.curl.request", autospec=True)
     def test_it_handles_oncalendar_schedule(self, mock_post: Mock) -> None:
         self._setup_data(json.dumps({"key": "123", "region": "us"}))
diff --git a/hc/api/transports.py b/hc/api/transports.py
index 0dafa4a9..8bfb99e6 100644
--- a/hc/api/transports.py
+++ b/hc/api/transports.py
@@ -546,7 +546,7 @@ class Opsgenie(HttpTransport):
 
         headers = {
             "Content-Type": "application/json",
-            "Authorization": "GenieKey %s" % self.channel.opsgenie.key,
+            "Authorization": f"GenieKey {self.channel.opsgenie.key}",
         }
 
         check = flip.owner
@@ -556,7 +556,7 @@ class Opsgenie(HttpTransport):
         }
 
         if flip.new_status == "down":
-            ctx = {"check": check, "ping": self.last_ping(flip)}
+            ctx = {"flip": flip, "check": check, "ping": self.last_ping(flip)}
             payload["tags"] = cast(JSONValue, check.tags_list())
             payload["message"] = tmpl("opsgenie_message.html", **ctx)
             payload["description"] = check.desc
diff --git a/templates/integrations/opsgenie_message.html b/templates/integrations/opsgenie_message.html
index a3114643..edbb24ec 100644
--- a/templates/integrations/opsgenie_message.html
+++ b/templates/integrations/opsgenie_message.html
@@ -1 +1 @@
-The check "{{ check.name_then_code }}" is DOWN.
\ No newline at end of file
+The check "{{ check.name_then_code }}" is DOWN{% if flip.reason %} ({{ flip.reason_long }}){% endif %}.