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.

151 lines
4.7 KiB

  1. # coding: utf-8
  2. from datetime import timedelta as td
  3. import json
  4. from django.core import mail
  5. from django.utils.timezone import now
  6. from hc.api.models import Channel, Check, Notification, Ping
  7. from hc.test import BaseTestCase
  8. class NotifyTestCase(BaseTestCase):
  9. def setUp(self):
  10. super().setUp()
  11. self.check = Check(project=self.project)
  12. self.check.name = "Daily Backup"
  13. self.check.desc = "Line 1\nLine2"
  14. self.check.tags = "foo bar"
  15. self.check.status = "down"
  16. self.check.last_ping = now() - td(minutes=61)
  17. self.check.n_pings = 112233
  18. self.check.save()
  19. self.ping = Ping(owner=self.check)
  20. self.ping.remote_addr = "1.2.3.4"
  21. self.ping.body = "Body Line 1\nBody Line 2"
  22. self.ping.save()
  23. self.channel = Channel(project=self.project)
  24. self.channel.kind = "email"
  25. self.channel.value = "[email protected]"
  26. self.channel.email_verified = True
  27. self.channel.save()
  28. self.channel.checks.add(self.check)
  29. def test_email(self):
  30. self.channel.notify(self.check)
  31. n = Notification.objects.get()
  32. self.assertEqual(n.error, "")
  33. # And email should have been sent
  34. self.assertEqual(len(mail.outbox), 1)
  35. email = mail.outbox[0]
  36. self.assertEqual(email.to[0], "[email protected]")
  37. self.assertTrue("X-Status-Url" in email.extra_headers)
  38. self.assertTrue("List-Unsubscribe" in email.extra_headers)
  39. self.assertTrue("List-Unsubscribe-Post" in email.extra_headers)
  40. html = email.alternatives[0][0]
  41. self.assertIn("Daily Backup", html)
  42. self.assertIn("Line 1<br>Line2", html)
  43. self.assertIn("Alices Project", html)
  44. self.assertIn("foo</code>", html)
  45. self.assertIn("bar</code>", html)
  46. self.assertIn("1 day", html)
  47. self.assertIn("from 1.2.3.4", html)
  48. self.assertIn("112233", html)
  49. self.assertIn("Body Line 1<br>Body Line 2", html)
  50. def test_it_shows_cron_schedule(self):
  51. self.check.kind = "cron"
  52. self.check.schedule = "0 18-23,0-8 * * *"
  53. self.check.save()
  54. self.channel.notify(self.check)
  55. email = mail.outbox[0]
  56. html = email.alternatives[0][0]
  57. self.assertIn("<code>0 18-23,0-8 * * *</code>", html)
  58. def test_it_truncates_long_body(self):
  59. self.ping.body = "X" * 10000 + ", and the rest gets cut off"
  60. self.ping.save()
  61. self.channel.notify(self.check)
  62. email = mail.outbox[0]
  63. html = email.alternatives[0][0]
  64. self.assertIn("[truncated]", html)
  65. self.assertNotIn("the rest gets cut off", html)
  66. def test_it_handles_missing_ping_object(self):
  67. self.ping.delete()
  68. self.channel.notify(self.check)
  69. email = mail.outbox[0]
  70. html = email.alternatives[0][0]
  71. self.assertIn("Daily Backup", html)
  72. def test_it_handles_missing_profile(self):
  73. self.channel.value = "[email protected]"
  74. self.channel.save()
  75. self.channel.notify(self.check)
  76. email = mail.outbox[0]
  77. self.assertEqual(email.to[0], "[email protected]")
  78. html = email.alternatives[0][0]
  79. self.assertIn("Daily Backup", html)
  80. self.assertNotIn("Projects Overview", html)
  81. def test_email_transport_handles_json_value(self):
  82. payload = {"value": "[email protected]", "up": True, "down": True}
  83. self.channel.value = json.dumps(payload)
  84. self.channel.save()
  85. self.channel.notify(self.check)
  86. # And email should have been sent
  87. self.assertEqual(len(mail.outbox), 1)
  88. email = mail.outbox[0]
  89. self.assertEqual(email.to[0], "[email protected]")
  90. def test_it_reports_unverified_email(self):
  91. self.channel.email_verified = False
  92. self.channel.save()
  93. self.channel.notify(self.check)
  94. # If an email is not verified, it should say so in the notification:
  95. n = Notification.objects.get()
  96. self.assertEqual(n.error, "Email not verified")
  97. def test_email_checks_up_down_flags(self):
  98. payload = {"value": "[email protected]", "up": True, "down": False}
  99. self.channel.value = json.dumps(payload)
  100. self.channel.save()
  101. self.channel.notify(self.check)
  102. # This channel should not notify on "down" events:
  103. self.assertEqual(Notification.objects.count(), 0)
  104. self.assertEqual(len(mail.outbox), 0)
  105. def test_email_handles_amperstand(self):
  106. self.check.name = "Foo & Bar"
  107. self.check.save()
  108. self.channel.notify(self.check)
  109. email = mail.outbox[0]
  110. self.assertEqual(email.subject, "DOWN | Foo & Bar")