0
0
Fork 0
mirror of https://github.com/healthchecks/healthchecks.git synced 2025-04-08 14:40:05 +00:00

Fix type warnings

This commit is contained in:
Pēteris Caune 2023-09-03 09:04:38 +03:00
parent 4a819a8018
commit 2901f03146
No known key found for this signature in database
GPG key ID: E28D7679E9A9EDE2
9 changed files with 77 additions and 65 deletions

View file

@ -2,12 +2,19 @@ from __future__ import annotations
from django.conf import settings
from django.core import mail
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.test.utils import override_settings
from hc.test import BaseTestCase
class ChangeEmailTestCase(BaseTestCase):
def get_html(self, email: EmailMessage) -> str:
assert isinstance(email, EmailMultiAlternatives)
html, _ = email.alternatives[0]
assert isinstance(html, str)
return html
def test_it_requires_sudo_mode(self) -> None:
self.client.login(username="alice@example.org", password="password")
@ -45,7 +52,7 @@ class ChangeEmailTestCase(BaseTestCase):
self.assertEqual(len(mail.outbox), 1)
message = mail.outbox[0]
self.assertEqual(message.subject, f"Log in to {settings.SITE_NAME}")
html = message.alternatives[0][0]
html = self.get_html(message)
self.assertIn("http://testserver/accounts/change_email/", html)
@override_settings(SESSION_COOKIE_SECURE=True)

View file

@ -2,6 +2,7 @@ from __future__ import annotations
from django.conf import settings
from django.core import mail
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.test.utils import override_settings
from hc.accounts.models import Credential
@ -14,6 +15,12 @@ class LoginTestCase(BaseTestCase):
super().setUp()
self.checks_url = f"/projects/{self.project.code}/checks/"
def get_html(self, email: EmailMessage) -> str:
assert isinstance(email, EmailMultiAlternatives)
html, _ = email.alternatives[0]
assert isinstance(html, str)
return html
def test_it_shows_form(self) -> None:
r = self.client.get("/accounts/login/")
self.assertContains(r, "Email Me a Link")
@ -42,7 +49,7 @@ class LoginTestCase(BaseTestCase):
self.assertEqual(len(mail.outbox), 1)
message = mail.outbox[0]
self.assertEqual(message.subject, f"Log in to {settings.SITE_NAME}")
html = message.alternatives[0][0]
html = self.get_html(message)
self.assertIn("http://testserver/static/img/logo.png", html)
self.assertIn("http://testserver/docs/", html)
@ -55,7 +62,7 @@ class LoginTestCase(BaseTestCase):
@override_settings(SITE_LOGO_URL="https://example.org/logo.svg")
def test_it_uses_custom_logo(self) -> None:
self.client.post("/accounts/login/", {"identity": "alice@example.org"})
html = mail.outbox[0].alternatives[0][0]
html = self.get_html(mail.outbox[0])
self.assertIn("https://example.org/logo.svg", html)
def test_it_sends_link_with_next(self) -> None:

View file

@ -6,6 +6,7 @@ from datetime import timezone
from unittest.mock import Mock, patch
from django.core import mail
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.utils.timezone import now
from hc.api.models import Check
@ -16,6 +17,12 @@ MOCK_NOW = Mock(return_value=CURRENT_TIME)
class ProfileModelTestCase(BaseTestCase):
def get_html(self, email: EmailMessage) -> str:
assert isinstance(email, EmailMultiAlternatives)
html, _ = email.alternatives[0]
assert isinstance(html, str)
return html
@patch("hc.lib.date.now", MOCK_NOW)
def test_it_sends_report(self) -> None:
check = Check(project=self.project, name="Test Check")
@ -32,7 +39,7 @@ class ProfileModelTestCase(BaseTestCase):
self.assertEqual(message.subject, "Monthly Report")
self.assertIn("Test Check", message.body)
html, _ = message.alternatives[0]
html = self.get_html(message)
self.assertNotIn("Jan. 2020", html)
self.assertIn("Dec. 2019", html)
self.assertIn("Nov. 2019", html)

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import re
from datetime import timedelta as td
from unittest.mock import Mock
from unittest.mock import Mock, patch
from django.core import mail
from django.test.utils import override_settings
@ -13,6 +13,8 @@ from hc.accounts.models import Member, Project
from hc.api.models import Channel, Check
from hc.test import BaseTestCase
MOCK_SLEEP = Mock()
def counts(result: str) -> list[int]:
"""Extract integer values from command's return value."""
@ -20,6 +22,7 @@ def counts(result: str) -> list[int]:
@override_settings(SITE_NAME="Mychecks")
@patch("hc.api.management.commands.sendreports.time.sleep", MOCK_SLEEP)
class SendDeletionScheduledTestCase(BaseTestCase):
def setUp(self) -> None:
super().setUp()
@ -37,8 +40,6 @@ class SendDeletionScheduledTestCase(BaseTestCase):
Check.objects.create(project=self.project)
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
result = cmd.handle()
self.assertEqual(counts(result), [1])
@ -56,8 +57,6 @@ class SendDeletionScheduledTestCase(BaseTestCase):
self.bob.save()
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
result = cmd.handle()
self.assertEqual(counts(result), [1])
@ -65,8 +64,6 @@ class SendDeletionScheduledTestCase(BaseTestCase):
def test_it_skips_profiles_with_deletion_scheduled_date_not_set(self) -> None:
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
result = cmd.handle()
self.assertEqual(counts(result), [0])
self.assertEqual(len(mail.outbox), 0)
@ -76,8 +73,6 @@ class SendDeletionScheduledTestCase(BaseTestCase):
self.profile.save()
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
result = cmd.handle()
self.assertEqual(counts(result), [0])
self.assertEqual(len(mail.outbox), 0)
@ -95,8 +90,6 @@ class SendDeletionScheduledTestCase(BaseTestCase):
)
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
cmd.handle()
# Bob should be listed as a recipient a single time, despite two memberships:
self.assertEqual(mail.outbox[0].to, ["alice@example.org", "bob@example.org"])
@ -106,7 +99,6 @@ class SendDeletionScheduledTestCase(BaseTestCase):
self.profile.save()
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
cmd.handle()
self.assertEqual(mail.outbox[0].subject, "Account Deletion Warning")
@ -118,7 +110,6 @@ class SendDeletionScheduledTestCase(BaseTestCase):
self.profile.save()
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
cmd.handle()
self.assertEqual(len(mail.outbox), 1)
@ -131,7 +122,6 @@ class SendDeletionScheduledTestCase(BaseTestCase):
self.channel.save()
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
cmd.handle()
self.assertEqual(len(mail.outbox), 1)

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import re
from datetime import timedelta as td
from unittest.mock import Mock
from unittest.mock import Mock, patch
from django.core import mail
from django.utils.timezone import now
@ -13,13 +13,16 @@ from hc.api.models import Check, Ping
from hc.payments.models import Subscription
from hc.test import BaseTestCase
MOCK_SLEEP = Mock()
def counts(result: str) -> list[int]:
"""Extract integer values from command's return value."""
return [int(s) for s in re.findall(r"\d+", result)]
class SendDeletionNoticesTestCase(BaseTestCase):
@patch("hc.accounts.management.commands.sendinactivitynotices.time.sleep", MOCK_SLEEP)
class SendInactivityNoticesTestCase(BaseTestCase):
def setUp(self) -> None:
super().setUp()
@ -35,8 +38,6 @@ class SendDeletionNoticesTestCase(BaseTestCase):
def test_it_sends_notice(self) -> None:
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
result = cmd.handle()
self.assertEqual(counts(result), [1, 0, 0])
@ -121,14 +122,12 @@ class SendDeletionNoticesTestCase(BaseTestCase):
self.assertIsNone(self.profile.deletion_notice_date)
def test_it_ignores_inactive_team_members(self) -> None:
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
# bob has access to alice's project, but is inactive
Member.objects.create(user=self.bob, project=self.project)
self.bob.date_joined = now() - td(days=366)
self.bob.save()
cmd = Command(stdout=Mock())
result = cmd.handle()
# both alice and bob are eligible for deletion
self.assertEqual(counts(result), [2, 0, 0])

View file

@ -8,6 +8,7 @@ from unittest.mock import Mock, patch
from django.conf import settings
from django.core import mail
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.test.utils import override_settings
from django.utils.timezone import now
@ -41,6 +42,12 @@ class NotifyEmailTestCase(BaseTestCase):
self.channel.save()
self.channel.checks.add(self.check)
def get_html(self, email: EmailMessage) -> str:
assert isinstance(email, EmailMultiAlternatives)
html, _ = email.alternatives[0]
assert isinstance(html, str)
return html
@override_settings(DEFAULT_FROM_EMAIL="alerts@example.org")
def test_it_works(self) -> None:
self.channel.notify(self.check)
@ -58,7 +65,7 @@ class NotifyEmailTestCase(BaseTestCase):
self.assertTrue("List-Unsubscribe-Post" in email.extra_headers)
self.assertTrue(email.extra_headers["Message-ID"].endswith("@example.org>"))
html = email.alternatives[0][0]
html = self.get_html(email)
# Name
self.assertIn("Daily Backup", email.body)
self.assertIn("Daily Backup", html)
@ -116,8 +123,7 @@ class NotifyEmailTestCase(BaseTestCase):
self.channel.notify(self.check)
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(mail.outbox[0])
self.assertIn("Line 1<br>Line2", html)
code, n = get_object.call_args.args
@ -133,8 +139,7 @@ class NotifyEmailTestCase(BaseTestCase):
self.channel.notify(self.check)
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("0 18-23,0-8 * * *", email.body)
self.assertIn("Europe/Riga", email.body)
self.assertIn("<code>0 18-23,0-8 * * *</code>", html)
@ -147,8 +152,7 @@ class NotifyEmailTestCase(BaseTestCase):
self.channel.notify(self.check)
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("[truncated]", email.body)
self.assertIn("[truncated]", html)
self.assertNotIn("the rest gets cut off", html)
@ -158,9 +162,7 @@ class NotifyEmailTestCase(BaseTestCase):
self.channel.notify(self.check)
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(mail.outbox[0])
self.assertIn("Daily Backup", html)
def test_it_handles_missing_profile(self) -> None:
@ -172,7 +174,7 @@ class NotifyEmailTestCase(BaseTestCase):
email = mail.outbox[0]
self.assertEqual(email.to[0], "alice+notifications@example.org")
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("Daily Backup", html)
self.assertNotIn("Projects Overview", email.body)
@ -234,8 +236,7 @@ class NotifyEmailTestCase(BaseTestCase):
self.channel.notify(self.check)
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("The request body data is being processed", email.body)
self.assertIn("The request body data is being processed", html)
@ -247,7 +248,7 @@ class NotifyEmailTestCase(BaseTestCase):
self.channel.notify(self.check)
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("Ignored", email.body)
self.assertIn("Ignored", html)
@ -258,7 +259,7 @@ class NotifyEmailTestCase(BaseTestCase):
self.channel.notify(self.check)
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("Log", email.body)
self.assertIn("Log", html)

View file

@ -8,6 +8,7 @@ from datetime import timedelta as td
from unittest.mock import Mock, patch
from django.core import mail
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.test.utils import override_settings
from django.utils.timezone import now
@ -85,6 +86,12 @@ class NotifySignalTestCase(BaseTestCase):
self.channel.save()
self.channel.checks.add(self.check)
def get_html(self, email: EmailMessage) -> str:
assert isinstance(email, EmailMultiAlternatives)
html, _ = email.alternatives[0]
assert isinstance(html, str)
return html
@patch("hc.api.transports.socket.socket")
def test_it_works(self, socket) -> None:
socketobj = setup_mock(socket, {})
@ -391,7 +398,7 @@ class NotifySignalTestCase(BaseTestCase):
self.assertIn("The check Foo & Co is DOWN.", email.body)
# The HTML version should retain styling, and escape special characters
# in project name, check name, etc.:
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("The check <b>Foo &amp; Co</b> is <b>DOWN</b>.", html)
@patch("hc.api.transports.socket.socket")

View file

@ -7,6 +7,7 @@ from unittest.mock import Mock, patch
from django.conf import settings
from django.core import mail
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.test.utils import override_settings
from django.utils.timezone import now
@ -16,6 +17,7 @@ from hc.test import BaseTestCase
CURRENT_TIME = datetime(2020, 1, 13, 2, tzinfo=timezone.utc)
MOCK_NOW = Mock(return_value=CURRENT_TIME)
MOCK_SLEEP = Mock()
NAG_TEXT = """Hello,
@ -42,6 +44,7 @@ Mychecks
@patch("hc.lib.date.now", MOCK_NOW)
@patch("hc.accounts.models.now", MOCK_NOW)
@patch("hc.api.management.commands.sendreports.now", MOCK_NOW)
@patch("hc.api.management.commands.sendreports.time.sleep", MOCK_SLEEP)
class SendReportsTestCase(BaseTestCase):
def setUp(self) -> None:
super().setUp()
@ -66,10 +69,14 @@ class SendReportsTestCase(BaseTestCase):
self.check.status = "down"
self.check.save()
def get_html(self, email: EmailMessage) -> str:
assert isinstance(email, EmailMultiAlternatives)
html, _ = email.alternatives[0]
assert isinstance(html, str)
return html
def test_it_sends_monthly_report(self) -> None:
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
found = cmd.handle_one_report()
self.assertTrue(found)
@ -86,7 +93,7 @@ class SendReportsTestCase(BaseTestCase):
self.assertEqual(email.subject, "Monthly Report")
self.assertIn("This is a monthly report", email.body)
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("This is a monthly report", html)
self.assertIn("Nov. 2019", html)
self.assertIn("Dec. 2019", html)
@ -96,15 +103,13 @@ class SendReportsTestCase(BaseTestCase):
self.profile.save()
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
cmd.handle_one_report()
email = mail.outbox[0]
self.assertEqual(email.subject, "Weekly Report")
self.assertIn("This is a weekly report", email.body)
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("This is a weekly report", html)
self.assertIn("Dec 30 - Jan 5", html)
self.assertIn("Jan 6 - Jan 12", html)
@ -115,11 +120,10 @@ class SendReportsTestCase(BaseTestCase):
self.profile.save()
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
cmd.handle_one_report()
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(email)
# UTC: Monday, Jan 13, 2AM.
# New York: Sunday, Jan 12, 9PM.
# The report should not contain the Jan 6 - Jan 12 week, because
@ -134,11 +138,10 @@ class SendReportsTestCase(BaseTestCase):
self.profile.save()
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
cmd.handle_one_report()
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(email)
# UTC: Monday, Jan 13, 2AM.
# Tokyo: Monday, Jan 13, 11AM
self.assertNotIn("Dec 23 - Dec 29", html)
@ -173,6 +176,7 @@ class SendReportsTestCase(BaseTestCase):
self.assertTrue(found)
self.profile.refresh_from_db()
assert self.profile.next_report_date
self.assertEqual(self.profile.next_report_date.date(), date(2020, 1, 20))
self.assertEqual(len(mail.outbox), 0)
@ -194,8 +198,6 @@ class SendReportsTestCase(BaseTestCase):
def test_it_sends_nag(self) -> None:
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
found = cmd.handle_one_nag()
self.assertTrue(found)
@ -205,7 +207,7 @@ class SendReportsTestCase(BaseTestCase):
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertNotIn(str(self.check.code), email.body)
self.assertNotIn(str(self.check.code), html)
@ -248,7 +250,6 @@ class SendReportsTestCase(BaseTestCase):
check2.save()
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
found = cmd.handle_one_nag()
self.assertTrue(found)
@ -256,15 +257,13 @@ class SendReportsTestCase(BaseTestCase):
self.assertIn("Foo", email.body)
self.assertNotIn("Foobar", email.body)
html = email.alternatives[0][0]
html = self.get_html(email)
self.assertIn("Foo", html)
self.assertNotIn("Foobar", html)
@override_settings(EMAIL_MAIL_FROM_TMPL="%s@bounces.example.org")
def test_it_sets_custom_mail_from(self) -> None:
cmd = Command(stdout=Mock())
cmd.pause = Mock() # don't pause for 1s
cmd.handle_one_report()
email = mail.outbox[0]

View file

@ -54,13 +54,8 @@ def make_message(name, to, ctx, headers={}):
else:
from_email = settings.DEFAULT_FROM_EMAIL
msg = EmailMultiAlternatives(
subject,
body,
from_email=from_email,
to=[to] if isinstance(to, str) else to,
headers=headers,
)
to_list = [to] if isinstance(to, str) else to
msg = EmailMultiAlternatives(subject, body, from_email, to_list, headers=headers)
msg.attach_alternative(html, "text/html")
return msg