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.

115 lines
3.8 KiB

  1. # coding: utf-8
  2. from datetime import timedelta as td
  3. import json
  4. from unittest.mock import patch
  5. from django.core import mail
  6. from django.utils.timezone import now
  7. from hc.api.models import Channel, Check, Notification
  8. from hc.test import BaseTestCase
  9. class NotifySmsTestCase(BaseTestCase):
  10. def setUp(self):
  11. super().setUp()
  12. self.check = Check(project=self.project)
  13. self.check.status = "down"
  14. self.check.last_ping = now() - td(minutes=61)
  15. self.check.save()
  16. spec = {"value": "+1234567890", "up": False, "down": True}
  17. self.channel = Channel(project=self.project, kind="sms")
  18. self.channel.value = json.dumps(spec)
  19. self.channel.save()
  20. self.channel.checks.add(self.check)
  21. @patch("hc.api.transports.requests.request")
  22. def test_it_works(self, mock_post):
  23. self.check.last_ping = now() - td(hours=2)
  24. mock_post.return_value.status_code = 200
  25. self.channel.notify(self.check)
  26. args, kwargs = mock_post.call_args
  27. payload = kwargs["data"]
  28. self.assertEqual(payload["To"], "+1234567890")
  29. self.assertNotIn("\xa0", payload["Body"])
  30. self.assertIn("is DOWN", payload["Body"])
  31. n = Notification.objects.get()
  32. callback_path = f"/api/v1/notifications/{n.code}/status"
  33. self.assertTrue(payload["StatusCallback"].endswith(callback_path))
  34. # sent SMS counter should go up
  35. self.profile.refresh_from_db()
  36. self.assertEqual(self.profile.sms_sent, 1)
  37. @patch("hc.api.transports.requests.request")
  38. def test_it_enforces_limit(self, mock_post):
  39. # At limit already:
  40. self.profile.last_sms_date = now()
  41. self.profile.sms_sent = 50
  42. self.profile.save()
  43. self.channel.notify(self.check)
  44. self.assertFalse(mock_post.called)
  45. n = Notification.objects.get()
  46. self.assertTrue("Monthly SMS limit exceeded" in n.error)
  47. # And email should have been sent
  48. self.assertEqual(len(mail.outbox), 1)
  49. email = mail.outbox[0]
  50. self.assertEqual(email.to[0], "[email protected]")
  51. self.assertEqual(email.subject, "Monthly SMS Limit Reached")
  52. @patch("hc.api.transports.requests.request")
  53. def test_it_resets_limit_next_month(self, mock_post):
  54. # At limit, but also into a new month
  55. self.profile.sms_sent = 50
  56. self.profile.last_sms_date = now() - td(days=100)
  57. self.profile.save()
  58. mock_post.return_value.status_code = 200
  59. self.channel.notify(self.check)
  60. self.assertTrue(mock_post.called)
  61. @patch("hc.api.transports.requests.request")
  62. def test_it_does_not_escape_special_characters(self, mock_post):
  63. self.check.name = "Foo > Bar & Co"
  64. self.check.last_ping = now() - td(hours=2)
  65. mock_post.return_value.status_code = 200
  66. self.channel.notify(self.check)
  67. args, kwargs = mock_post.call_args
  68. payload = kwargs["data"]
  69. self.assertIn("Foo > Bar & Co", payload["Body"])
  70. @patch("hc.api.transports.requests.request")
  71. def test_it_handles_disabled_down_notification(self, mock_post):
  72. payload = {"value": "+123123123", "up": True, "down": False}
  73. self.channel.value = json.dumps(payload)
  74. self.channel.notify(self.check)
  75. self.assertFalse(mock_post.called)
  76. @patch("hc.api.transports.requests.request")
  77. def test_it_sends_up_notification(self, mock_post):
  78. payload = {"value": "+123123123", "up": True, "down": False}
  79. self.channel.value = json.dumps(payload)
  80. self.check.last_ping = now()
  81. self.check.status = "up"
  82. mock_post.return_value.status_code = 200
  83. self.channel.notify(self.check)
  84. args, kwargs = mock_post.call_args
  85. payload = kwargs["data"]
  86. self.assertIn("is UP", payload["Body"])