Browse Source

Sending a test notification updates Channel.last_error. Fixes #391

pull/394/head
Pēteris Caune 4 years ago
parent
commit
3a00c0d2aa
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
9 changed files with 69 additions and 37 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +19
    -0
      hc/api/migrations/0072_auto_20200701_1007.py
  3. +10
    -3
      hc/api/models.py
  4. +4
    -5
      hc/api/tests/test_notify.py
  5. +0
    -3
      hc/api/transports.py
  6. +0
    -16
      hc/front/tests/test_channels.py
  7. +29
    -1
      hc/front/tests/test_send_test_notification.py
  8. +5
    -4
      hc/front/views.py
  9. +1
    -5
      templates/front/channels.html

+ 1
- 0
CHANGELOG.md View File

@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
### Bug Fixes ### Bug Fixes
- Removing Pager Team integration, project appears to be discontinued - Removing Pager Team integration, project appears to be discontinued
- Sending a test notification updates Channel.last_error (#391)
## v1.15.0 - 2020-06-04 ## v1.15.0 - 2020-06-04


+ 19
- 0
hc/api/migrations/0072_auto_20200701_1007.py View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.7 on 2020-07-01 10:07
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('api', '0071_check_manual_resume'),
]
operations = [
migrations.AlterField(
model_name='notification',
name='owner',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='api.Check'),
),
]

+ 10
- 3
hc/api/models.py View File

@ -459,11 +459,18 @@ class Channel(models.Model):
else: else:
raise NotImplementedError("Unknown channel kind: %s" % self.kind) raise NotImplementedError("Unknown channel kind: %s" % self.kind)
def notify(self, check):
def notify(self, check, is_test=False):
if self.transport.is_noop(check): if self.transport.is_noop(check):
return "no-op" return "no-op"
n = Notification(owner=check, channel=self)
n = Notification(channel=self)
if is_test:
# When sending a test notification we leave the owner field null.
# (the passed check is a dummy, unsaved Check instance)
pass
else:
n.owner = check
n.check_status = check.status n.check_status = check.status
n.error = "Sending" n.error = "Sending"
n.save() n.save()
@ -735,7 +742,7 @@ class Notification(models.Model):
get_latest_by = "created" get_latest_by = "created"
code = models.UUIDField(default=uuid.uuid4, null=True, editable=False) code = models.UUIDField(default=uuid.uuid4, null=True, editable=False)
owner = models.ForeignKey(Check, models.CASCADE)
owner = models.ForeignKey(Check, models.CASCADE, null=True)
check_status = models.CharField(max_length=6) check_status = models.CharField(max_length=6)
channel = models.ForeignKey(Channel, models.CASCADE) channel = models.ForeignKey(Channel, models.CASCADE)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)


+ 4
- 5
hc/api/tests/test_notify.py View File

@ -327,14 +327,13 @@ class NotifyTestCase(BaseTestCase):
email = mail.outbox[0] email = mail.outbox[0]
self.assertEqual(email.to[0], "[email protected]") self.assertEqual(email.to[0], "[email protected]")
def test_it_skips_unverified_email(self):
def test_it_reports_unverified_email(self):
self._setup_data("email", "[email protected]", email_verified=False) self._setup_data("email", "[email protected]", email_verified=False)
self.channel.notify(self.check) self.channel.notify(self.check)
# If an email is not verified, it should be skipped over
# without logging a notification:
self.assertEqual(Notification.objects.count(), 0)
self.assertEqual(len(mail.outbox), 0)
# If an email is not verified, it should say so in the notification:
n = Notification.objects.get()
self.assertEqual(n.error, "Email not verified")
def test_email_checks_up_down_flags(self): def test_email_checks_up_down_flags(self):
payload = {"value": "[email protected]", "up": True, "down": False} payload = {"value": "[email protected]", "up": True, "down": False}


+ 0
- 3
hc/api/transports.py View File

@ -88,9 +88,6 @@ class Email(Transport):
emails.alert(self.channel.email_value, ctx, headers) emails.alert(self.channel.email_value, ctx, headers)
def is_noop(self, check): def is_noop(self, check):
if not self.channel.email_verified:
return True
if check.status == "down": if check.status == "down":
return not self.channel.email_notify_down return not self.channel.email_notify_down
else: else:


+ 0
- 16
hc/front/tests/test_channels.py View File

@ -57,22 +57,6 @@ class ChannelsTestCase(BaseTestCase):
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
self.assertContains(r, "(normal priority)") self.assertContains(r, "(normal priority)")
def test_it_shows_disabled_email(self):
check = Check(project=self.project, status="up")
check.save()
channel = Channel(project=self.project, kind="email")
channel.value = "[email protected]"
channel.save()
n = Notification(owner=check, channel=channel, error="Invalid address")
n.save()
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.channels_url)
self.assertEqual(r.status_code, 200)
self.assertContains(r, "Disabled")
def test_it_shows_unconfirmed_email(self): def test_it_shows_unconfirmed_email(self):
channel = Channel(project=self.project, kind="email") channel = Channel(project=self.project, kind="email")
channel.value = "[email protected]" channel.value = "[email protected]"


+ 29
- 1
hc/front/tests/test_send_test_notification.py View File

@ -2,7 +2,7 @@ import json
from unittest.mock import patch from unittest.mock import patch
from django.core import mail from django.core import mail
from hc.api.models import Channel
from hc.api.models import Channel, Notification
from hc.test import BaseTestCase from hc.test import BaseTestCase
@ -31,6 +31,34 @@ class SendTestNotificationTestCase(BaseTestCase):
self.assertTrue("X-Bounce-Url" in email.extra_headers) self.assertTrue("X-Bounce-Url" in email.extra_headers)
self.assertTrue("List-Unsubscribe" in email.extra_headers) self.assertTrue("List-Unsubscribe" in email.extra_headers)
# It should create a notification
n = Notification.objects.get()
self.assertEqual(n.channel, self.channel)
self.assertEqual(n.error, "")
def test_it_clears_channel_last_error(self):
self.channel.last_error = "Something went wrong"
self.channel.save()
self.client.login(username="[email protected]", password="password")
self.client.post(self.url, {})
self.channel.refresh_from_db()
self.assertEqual(self.channel.last_error, "")
def test_it_sets_channel_last_error(self):
self.channel.email_verified = False
self.channel.save()
self.client.login(username="[email protected]", password="password")
r = self.client.post(self.url, {}, follow=True)
self.assertContains(r, "Could not send a test notification")
self.assertContains(r, "Email not verified")
self.channel.refresh_from_db()
self.assertEqual(self.channel.last_error, "Email not verified")
@patch("hc.api.transports.requests.request") @patch("hc.api.transports.requests.request")
def test_it_handles_webhooks_with_no_down_url(self, mock_get): def test_it_handles_webhooks_with_no_down_url(self, mock_get):
mock_get.return_value.status_code = 200 mock_get.return_value.status_code = 200


+ 5
- 4
hc/front/views.py View File

@ -795,10 +795,11 @@ def send_test_notification(request, code):
# send "TEST is UP" notification instead: # send "TEST is UP" notification instead:
dummy.status = "up" dummy.status = "up"
if channel.kind == "email":
error = channel.transport.notify(dummy, channel.get_unsub_link())
else:
error = channel.transport.notify(dummy)
# Delete all older test notifications for this channel
Notification.objects.filter(channel=channel, owner=None).delete()
# Send the test notification
error = channel.notify(dummy, is_test=True)
if error: if error:
messages.warning(request, "Could not send a test notification. %s" % error) messages.warning(request, "Could not send a test notification. %s" % error)


+ 1
- 5
templates/front/channels.html View File

@ -103,11 +103,7 @@
</td> </td>
<td> <td>
{% if ch.kind == "email" and not ch.email_verified %} {% if ch.kind == "email" and not ch.email_verified %}
{% if n and n.error %}
<span class="label label-danger">Disabled</span>
{% else %}
<span class="label label-default">Unconfirmed</span>
{% endif %}
<span class="label label-default">Unconfirmed</span>
{% elif ch.kind == "hipchat" or ch.kind == "pagerteam" %} {% elif ch.kind == "hipchat" or ch.kind == "pagerteam" %}
Retired Retired
{% else %} {% else %}


Loading…
Cancel
Save