You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
7.1 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. from django.core import mail
  2. from mock import patch
  3. from requests.exceptions import ConnectionError, Timeout
  4. from hc.api.models import Channel, Check, Notification
  5. from hc.test import BaseTestCase
  6. class NotifyTestCase(BaseTestCase):
  7. def _setup_data(self, kind, value, status="down", email_verified=True):
  8. self.check = Check()
  9. self.check.status = status
  10. self.check.save()
  11. self.channel = Channel(user=self.alice)
  12. self.channel.kind = kind
  13. self.channel.value = value
  14. self.channel.email_verified = email_verified
  15. self.channel.save()
  16. self.channel.checks.add(self.check)
  17. @patch("hc.api.transports.requests.request")
  18. def test_webhook(self, mock_get):
  19. self._setup_data("webhook", "http://example")
  20. mock_get.return_value.status_code = 200
  21. self.channel.notify(self.check)
  22. mock_get.assert_called_with(
  23. "get", u"http://example",
  24. headers={"User-Agent": "healthchecks.io"}, timeout=5)
  25. @patch("hc.api.transports.requests.request", side_effect=Timeout)
  26. def test_webhooks_handle_timeouts(self, mock_get):
  27. self._setup_data("webhook", "http://example")
  28. self.channel.notify(self.check)
  29. n = Notification.objects.get()
  30. self.assertEqual(n.error, "Connection timed out")
  31. @patch("hc.api.transports.requests.request", side_effect=ConnectionError)
  32. def test_webhooks_handle_connection_errors(self, mock_get):
  33. self._setup_data("webhook", "http://example")
  34. self.channel.notify(self.check)
  35. n = Notification.objects.get()
  36. self.assertEqual(n.error, "Connection failed")
  37. @patch("hc.api.transports.requests.request")
  38. def test_webhooks_ignore_up_events(self, mock_get):
  39. self._setup_data("webhook", "http://example", status="up")
  40. self.channel.notify(self.check)
  41. self.assertFalse(mock_get.called)
  42. self.assertEqual(Notification.objects.count(), 0)
  43. @patch("hc.api.transports.requests.request")
  44. def test_webhooks_handle_500(self, mock_get):
  45. self._setup_data("webhook", "http://example")
  46. mock_get.return_value.status_code = 500
  47. self.channel.notify(self.check)
  48. n = Notification.objects.get()
  49. self.assertEqual(n.error, "Received status code 500")
  50. @patch("hc.api.transports.requests.request")
  51. def test_webhooks_support_variables(self, mock_get):
  52. template = "http://host/$CODE/$STATUS/$TAG1/$TAG2/?name=$NAME"
  53. self._setup_data("webhook", template)
  54. self.check.name = "Hello World"
  55. self.check.tags = "foo bar"
  56. self.check.save()
  57. self.channel.notify(self.check)
  58. url = u"http://host/%s/down/foo/bar/?name=Hello%%20World" \
  59. % self.check.code
  60. mock_get.assert_called_with(
  61. "get", url, headers={"User-Agent": "healthchecks.io"}, timeout=5)
  62. @patch("hc.api.transports.requests.request")
  63. def test_webhooks_dollarsign_escaping(self, mock_get):
  64. # If name or tag contains what looks like a variable reference,
  65. # that should be left alone:
  66. template = "http://host/$NAME"
  67. self._setup_data("webhook", template)
  68. self.check.name = "$TAG1"
  69. self.check.tags = "foo"
  70. self.check.save()
  71. self.channel.notify(self.check)
  72. url = u"http://host/%24TAG1"
  73. mock_get.assert_called_with(
  74. "get", url, headers={"User-Agent": "healthchecks.io"}, timeout=5)
  75. @patch("hc.api.transports.requests.request")
  76. def test_webhook_fires_on_up_event(self, mock_get):
  77. self._setup_data("webhook", "http://foo\nhttp://bar", status="up")
  78. self.channel.notify(self.check)
  79. mock_get.assert_called_with(
  80. "get", "http://bar", headers={"User-Agent": "healthchecks.io"},
  81. timeout=5)
  82. def test_email(self):
  83. self._setup_data("email", "[email protected]")
  84. self.channel.notify(self.check)
  85. n = Notification.objects.get()
  86. self.assertEqual(n.error, "")
  87. # And email should have been sent
  88. self.assertEqual(len(mail.outbox), 1)
  89. def test_it_skips_unverified_email(self):
  90. self._setup_data("email", "[email protected]", email_verified=False)
  91. self.channel.notify(self.check)
  92. assert Notification.objects.count() == 1
  93. n = Notification.objects.first()
  94. self.assertEqual(n.error, "Email not verified")
  95. self.assertEqual(len(mail.outbox), 0)
  96. @patch("hc.api.transports.requests.request")
  97. def test_pd(self, mock_post):
  98. self._setup_data("pd", "123")
  99. mock_post.return_value.status_code = 200
  100. self.channel.notify(self.check)
  101. assert Notification.objects.count() == 1
  102. args, kwargs = mock_post.call_args
  103. json = kwargs["json"]
  104. self.assertEqual(json["event_type"], "trigger")
  105. @patch("hc.api.transports.requests.request")
  106. def test_slack(self, mock_post):
  107. self._setup_data("slack", "123")
  108. mock_post.return_value.status_code = 200
  109. self.channel.notify(self.check)
  110. assert Notification.objects.count() == 1
  111. args, kwargs = mock_post.call_args
  112. json = kwargs["json"]
  113. attachment = json["attachments"][0]
  114. fields = {f["title"]: f["value"] for f in attachment["fields"]}
  115. self.assertEqual(fields["Last Ping"], "Never")
  116. @patch("hc.api.transports.requests.request")
  117. def test_slack_handles_500(self, mock_post):
  118. self._setup_data("slack", "123")
  119. mock_post.return_value.status_code = 500
  120. self.channel.notify(self.check)
  121. n = Notification.objects.get()
  122. self.assertEqual(n.error, "Received status code 500")
  123. @patch("hc.api.transports.requests.request", side_effect=Timeout)
  124. def test_slack_handles_timeout(self, mock_post):
  125. self._setup_data("slack", "123")
  126. self.channel.notify(self.check)
  127. n = Notification.objects.get()
  128. self.assertEqual(n.error, "Connection timed out")
  129. @patch("hc.api.transports.requests.request")
  130. def test_hipchat(self, mock_post):
  131. self._setup_data("hipchat", "123")
  132. mock_post.return_value.status_code = 204
  133. self.channel.notify(self.check)
  134. n = Notification.objects.first()
  135. self.assertEqual(n.error, "")
  136. args, kwargs = mock_post.call_args
  137. json = kwargs["json"]
  138. self.assertIn("DOWN", json["message"])
  139. @patch("hc.api.transports.requests.request")
  140. def test_pushover(self, mock_post):
  141. self._setup_data("po", "123|0")
  142. mock_post.return_value.status_code = 200
  143. self.channel.notify(self.check)
  144. assert Notification.objects.count() == 1
  145. args, kwargs = mock_post.call_args
  146. json = kwargs["data"]
  147. self.assertIn("DOWN", json["title"])
  148. @patch("hc.api.transports.requests.request")
  149. def test_victorops(self, mock_post):
  150. self._setup_data("victorops", "123")
  151. mock_post.return_value.status_code = 200
  152. self.channel.notify(self.check)
  153. assert Notification.objects.count() == 1
  154. args, kwargs = mock_post.call_args
  155. json = kwargs["json"]
  156. self.assertEqual(json["message_type"], "CRITICAL")