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
- Removing Pager Team integration, project appears to be discontinued
- Sending a test notification updates Channel.last_error (#391)
## 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:
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):
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.error = "Sending"
n.save()
@ -735,7 +742,7 @@ class Notification(models.Model):
get_latest_by = "created"
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)
channel = models.ForeignKey(Channel, models.CASCADE)
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]
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.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):
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)
def is_noop(self, check):
if not self.channel.email_verified:
return True
if check.status == "down":
return not self.channel.email_notify_down
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.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):
channel = Channel(project=self.project, kind="email")
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 django.core import mail
from hc.api.models import Channel
from hc.api.models import Channel, Notification
from hc.test import BaseTestCase
@ -31,6 +31,34 @@ class SendTestNotificationTestCase(BaseTestCase):
self.assertTrue("X-Bounce-Url" 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")
def test_it_handles_webhooks_with_no_down_url(self, mock_get):
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:
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:
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>
{% 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" %}
Retired
{% else %}


Loading…
Cancel
Save