forked from GithubBackups/healthchecks
Less verbose output in the senddeletionnotices
command
This commit is contained in:
parent
8ea510cda6
commit
c7af52637a
@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Django 3.1
|
- Django 3.1
|
||||||
- Handle status callbacks from Twilio, show delivery failures in Integrations
|
- Handle status callbacks from Twilio, show delivery failures in Integrations
|
||||||
- Removing unused /api/v1/notifications/{uuid}/bounce endpoint
|
- Removing unused /api/v1/notifications/{uuid}/bounce endpoint
|
||||||
|
- Less verbose output in the `senddeletionnotices` command
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
- Handle excessively long email addresses in the signup form.
|
- Handle excessively long email addresses in the signup form.
|
||||||
|
@ -16,6 +16,8 @@ class Command(BaseCommand):
|
|||||||
- deletion notice has not been sent recently
|
- deletion notice has not been sent recently
|
||||||
- last login more than a year ago
|
- last login more than a year ago
|
||||||
- none of the owned projects has invited team members
|
- none of the owned projects has invited team members
|
||||||
|
- none of the owned projects has pings in the last year
|
||||||
|
- is on a free plan
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -38,17 +40,21 @@ class Command(BaseCommand):
|
|||||||
q = q.exclude(sms_limit__gt=5)
|
q = q.exclude(sms_limit__gt=5)
|
||||||
|
|
||||||
sent = 0
|
sent = 0
|
||||||
|
skipped_has_team = 0
|
||||||
|
skipped_has_pings = 0
|
||||||
|
|
||||||
for profile in q:
|
for profile in q:
|
||||||
members = Member.objects.filter(project__owner_id=profile.user_id)
|
members = Member.objects.filter(project__owner_id=profile.user_id)
|
||||||
if members.exists():
|
if members.exists():
|
||||||
self.stdout.write("Skipping %s, has team members" % profile)
|
# Don't send deletion notice: this account has team members
|
||||||
|
skipped_has_team += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
pings = Ping.objects
|
pings = Ping.objects.filter(owner__project__owner_id=profile.user_id)
|
||||||
pings = pings.filter(owner__project__owner_id=profile.user_id)
|
|
||||||
pings = pings.filter(created__gt=year_ago)
|
pings = pings.filter(created__gt=year_ago)
|
||||||
if pings.exists():
|
if pings.exists():
|
||||||
self.stdout.write("Skipping %s, has pings in last year" % profile)
|
# Don't send deletion notice: this account has pings in the last year
|
||||||
|
skipped_has_pings += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.stdout.write("Sending notice to %s" % profile.user.email)
|
self.stdout.write("Sending notice to %s" % profile.user.email)
|
||||||
@ -58,10 +64,14 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
ctx = {"email": profile.user.email, "support_email": settings.SUPPORT_EMAIL}
|
ctx = {"email": profile.user.email, "support_email": settings.SUPPORT_EMAIL}
|
||||||
emails.deletion_notice(profile.user.email, ctx)
|
emails.deletion_notice(profile.user.email, ctx)
|
||||||
|
sent += 1
|
||||||
|
|
||||||
# Throttle so we don't send too many emails at once:
|
# Throttle so we don't send too many emails at once:
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
sent += 1
|
return (
|
||||||
|
f"Done!\n"
|
||||||
return "Done! Sent %d notices" % sent
|
f"* Notices sent: {sent}\n"
|
||||||
|
f"* Skipped (has team members): {skipped_has_team}\n"
|
||||||
|
f"* Skipped (has pings in the last year): {skipped_has_pings}\n"
|
||||||
|
)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from datetime import timedelta as td
|
from datetime import timedelta as td
|
||||||
|
import re
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
@ -9,6 +10,11 @@ from hc.api.models import Check, Ping
|
|||||||
from hc.test import BaseTestCase
|
from hc.test import BaseTestCase
|
||||||
|
|
||||||
|
|
||||||
|
def counts(result):
|
||||||
|
""" Extract integer values from command's return value. """
|
||||||
|
return [int(s) for s in re.findall(r"\d+", result)]
|
||||||
|
|
||||||
|
|
||||||
class SendDeletionNoticesTestCase(BaseTestCase):
|
class SendDeletionNoticesTestCase(BaseTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(SendDeletionNoticesTestCase, self).setUp()
|
super(SendDeletionNoticesTestCase, self).setUp()
|
||||||
@ -28,7 +34,7 @@ class SendDeletionNoticesTestCase(BaseTestCase):
|
|||||||
cmd.pause = Mock() # don't pause for 1s
|
cmd.pause = Mock() # don't pause for 1s
|
||||||
|
|
||||||
result = cmd.handle()
|
result = cmd.handle()
|
||||||
self.assertEqual(result, "Done! Sent 1 notices")
|
self.assertEqual(counts(result), [1, 0, 0])
|
||||||
|
|
||||||
self.profile.refresh_from_db()
|
self.profile.refresh_from_db()
|
||||||
self.assertTrue(self.profile.deletion_notice_date)
|
self.assertTrue(self.profile.deletion_notice_date)
|
||||||
@ -42,7 +48,7 @@ class SendDeletionNoticesTestCase(BaseTestCase):
|
|||||||
self.alice.save()
|
self.alice.save()
|
||||||
|
|
||||||
result = Command(stdout=Mock()).handle()
|
result = Command(stdout=Mock()).handle()
|
||||||
self.assertEqual(result, "Done! Sent 0 notices")
|
self.assertEqual(counts(result), [0, 0, 0])
|
||||||
|
|
||||||
self.profile.refresh_from_db()
|
self.profile.refresh_from_db()
|
||||||
self.assertIsNone(self.profile.deletion_notice_date)
|
self.assertIsNone(self.profile.deletion_notice_date)
|
||||||
@ -53,7 +59,7 @@ class SendDeletionNoticesTestCase(BaseTestCase):
|
|||||||
self.alice.save()
|
self.alice.save()
|
||||||
|
|
||||||
result = Command(stdout=Mock()).handle()
|
result = Command(stdout=Mock()).handle()
|
||||||
self.assertEqual(result, "Done! Sent 0 notices")
|
self.assertEqual(counts(result), [0, 0, 0])
|
||||||
|
|
||||||
self.profile.refresh_from_db()
|
self.profile.refresh_from_db()
|
||||||
self.assertIsNone(self.profile.deletion_notice_date)
|
self.assertIsNone(self.profile.deletion_notice_date)
|
||||||
@ -64,7 +70,7 @@ class SendDeletionNoticesTestCase(BaseTestCase):
|
|||||||
self.profile.save()
|
self.profile.save()
|
||||||
|
|
||||||
result = Command(stdout=Mock()).handle()
|
result = Command(stdout=Mock()).handle()
|
||||||
self.assertEqual(result, "Done! Sent 0 notices")
|
self.assertEqual(counts(result), [0, 0, 0])
|
||||||
|
|
||||||
def test_it_checks_sms_limit(self):
|
def test_it_checks_sms_limit(self):
|
||||||
# alice has a paid account
|
# alice has a paid account
|
||||||
@ -72,7 +78,7 @@ class SendDeletionNoticesTestCase(BaseTestCase):
|
|||||||
self.profile.save()
|
self.profile.save()
|
||||||
|
|
||||||
result = Command(stdout=Mock()).handle()
|
result = Command(stdout=Mock()).handle()
|
||||||
self.assertEqual(result, "Done! Sent 0 notices")
|
self.assertEqual(counts(result), [0, 0, 0])
|
||||||
|
|
||||||
self.profile.refresh_from_db()
|
self.profile.refresh_from_db()
|
||||||
self.assertIsNone(self.profile.deletion_notice_date)
|
self.assertIsNone(self.profile.deletion_notice_date)
|
||||||
@ -82,7 +88,7 @@ class SendDeletionNoticesTestCase(BaseTestCase):
|
|||||||
Member.objects.create(user=self.bob, project=self.project)
|
Member.objects.create(user=self.bob, project=self.project)
|
||||||
|
|
||||||
result = Command(stdout=Mock()).handle()
|
result = Command(stdout=Mock()).handle()
|
||||||
self.assertEqual(result, "Done! Sent 0 notices")
|
self.assertEqual(counts(result), [0, 1, 0])
|
||||||
|
|
||||||
self.profile.refresh_from_db()
|
self.profile.refresh_from_db()
|
||||||
self.assertIsNone(self.profile.deletion_notice_date)
|
self.assertIsNone(self.profile.deletion_notice_date)
|
||||||
@ -92,7 +98,7 @@ class SendDeletionNoticesTestCase(BaseTestCase):
|
|||||||
Ping.objects.create(owner=check)
|
Ping.objects.create(owner=check)
|
||||||
|
|
||||||
result = Command(stdout=Mock()).handle()
|
result = Command(stdout=Mock()).handle()
|
||||||
self.assertEqual(result, "Done! Sent 0 notices")
|
self.assertEqual(counts(result), [0, 0, 1])
|
||||||
|
|
||||||
self.profile.refresh_from_db()
|
self.profile.refresh_from_db()
|
||||||
self.assertIsNone(self.profile.deletion_notice_date)
|
self.assertIsNone(self.profile.deletion_notice_date)
|
||||||
@ -103,4 +109,4 @@ class SendDeletionNoticesTestCase(BaseTestCase):
|
|||||||
self.profile.save()
|
self.profile.save()
|
||||||
|
|
||||||
result = Command(stdout=Mock()).handle()
|
result = Command(stdout=Mock()).handle()
|
||||||
self.assertEqual(result, "Done! Sent 0 notices")
|
self.assertEqual(counts(result), [0, 0, 0])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user