test_plugin.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. from urllib.parse import parse_qs
  2. import responses
  3. from exam import fixture
  4. from sentry.models import Rule
  5. from sentry.plugins.base import Notification
  6. from sentry.testutils import PluginTestCase, TestCase
  7. from sentry_plugins.twilio.plugin import TwilioConfigurationForm, TwilioPlugin, split_sms_to
  8. class TwilioPluginSMSSplitTest(TestCase):
  9. def test_valid_split_sms_to(self):
  10. to = "330-509-3095, (330)-509-3095, +13305093095, 4045550144"
  11. expected = {"330-509-3095", "(330)-509-3095", "+13305093095", "4045550144"}
  12. actual = split_sms_to(to)
  13. assert expected == actual
  14. def test_valid_split_sms_to_with_extra_spaces(self):
  15. to = "330-509-3095 , (330)-509-3095, +13305093095, 4045550144"
  16. expected = {"330-509-3095", "(330)-509-3095", "+13305093095", "4045550144"}
  17. actual = split_sms_to(to)
  18. assert expected == actual
  19. def test_split_sms_to_with_single_number(self):
  20. to = "555-555-5555"
  21. expected = {"555-555-5555"}
  22. actual = split_sms_to(to)
  23. assert expected == actual
  24. class TwilioConfigurationFormTest(TestCase):
  25. def test_valid_form(self):
  26. form = TwilioConfigurationForm(
  27. data={
  28. "sms_from": "3305093095",
  29. "sms_to": "330-509-3095, (330)-509-3095, +13305093095, 4045550144",
  30. "auth_token": "foo",
  31. "account_sid": "bar",
  32. }
  33. )
  34. self.assertTrue(form.is_valid())
  35. self.assertDictEqual(
  36. form.clean(),
  37. {
  38. "auth_token": "foo",
  39. "sms_to": "+13305093095,+14045550144",
  40. "sms_from": "+13305093095",
  41. "account_sid": "bar",
  42. },
  43. )
  44. def test_invalid_form(self):
  45. form = TwilioConfigurationForm(data={"sms_from": "foobar", "sms_to": "911"})
  46. self.assertFalse(form.is_valid())
  47. errors = form.errors.as_data()
  48. # extracting the message from django.forms.ValidationError
  49. # is the easiest and simplest way I've found to assert as_data
  50. for e in errors:
  51. errors[e] = list(map(lambda x: x.message, errors[e]))
  52. self.assertDictEqual(
  53. errors,
  54. {
  55. "auth_token": ["This field is required."],
  56. "account_sid": ["This field is required."],
  57. "sms_from": ["foobar is not a valid phone number."],
  58. "sms_to": ["911 is not a valid phone number."],
  59. },
  60. )
  61. class TwilioPluginTest(PluginTestCase):
  62. @fixture
  63. def plugin(self):
  64. return TwilioPlugin()
  65. def test_conf_key(self):
  66. assert self.plugin.conf_key == "twilio"
  67. def test_entry_point(self):
  68. self.assertPluginInstalled("twilio", self.plugin)
  69. def test_is_configured(self):
  70. for o in ("account_sid", "auth_token", "sms_from", "sms_to"):
  71. assert self.plugin.is_configured(self.project) is False
  72. self.plugin.set_option(o, "foo", self.project)
  73. assert self.plugin.is_configured(self.project) is True
  74. @responses.activate
  75. def test_simple_notification(self):
  76. responses.add("POST", "https://api.twilio.com/2010-04-01/Accounts/abcdef/Messages.json")
  77. self.plugin.set_option("account_sid", "abcdef", self.project)
  78. self.plugin.set_option("auth_token", "abcd", self.project)
  79. self.plugin.set_option("sms_from", "4158675309", self.project)
  80. self.plugin.set_option("sms_to", "4154444444", self.project)
  81. event = self.store_event(
  82. data={
  83. "message": "Hello world",
  84. "level": "warning",
  85. "platform": "python",
  86. "culprit": "foo.bar",
  87. },
  88. project_id=self.project.id,
  89. )
  90. rule = Rule.objects.create(project=self.project, label="my rule")
  91. notification = Notification(event=event, rule=rule)
  92. with self.options({"system.url-prefix": "http://example.com"}):
  93. self.plugin.notify(notification)
  94. request = responses.calls[0].request
  95. payload = parse_qs(request.body)
  96. assert payload == {
  97. "To": ["+14154444444"],
  98. "From": ["+14158675309"],
  99. "Body": ["Sentry [%s] WARNING: Hello world" % self.project.slug.title()],
  100. }