From fd7847993b1cf170b3b7e9d83150fec45e553c3d Mon Sep 17 00:00:00 2001 From: jedi Date: Sat, 30 Dec 2023 18:33:45 +0100 Subject: [PATCH] fix async bug in mailadress target event lookup --- core/mail/protocol.py | 17 +++++---- core/mail/tests/v2/test_mails.py | 61 +++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 12 deletions(-) diff --git a/core/mail/protocol.py b/core/mail/protocol.py index 6f26926..a57d2ff 100644 --- a/core/mail/protocol.py +++ b/core/mail/protocol.py @@ -90,6 +90,15 @@ def find_active_issue_thread(in_reply_to, subject=None): return issue, True +def find_target_event(address): + try: + address_map = EventAddress.objects.get(address=address) + if address_map.event: + return address_map.event + except EventAddress.DoesNotExist: + pass + return None + class LMTPHandler: async def handle_RCPT(self, server, session, envelope, address, rcpt_options): from core.settings import MAIL_DOMAIN @@ -142,13 +151,7 @@ class LMTPHandler: subject = parsed.get('Subject') subject = unescape_and_decode_quoted_printable(subject) subject = unescape_and_decode_base64(subject) - target_event = None - try: - address_map = await sync_to_async(EventAddress.objects.get)(address=recipient) - if address_map.event: - target_event = address_map.event - except EventAddress.DoesNotExist: - pass + target_event = await sync_to_async(find_target_event)(recipient) active_issue_thread, new = await sync_to_async(find_active_issue_thread)(header_in_reply_to, subject) body_decoded = body.decode('utf-8') diff --git a/core/mail/tests/v2/test_mails.py b/core/mail/tests/v2/test_mails.py index 80ba42b..b47ebc0 100644 --- a/core/mail/tests/v2/test_mails.py +++ b/core/mail/tests/v2/test_mails.py @@ -8,9 +8,9 @@ from knox.models import AuthToken from authentication.models import ExtendedUser from core.settings import MAIL_DOMAIN from inventory.models import Event -from mail.models import Email +from mail.models import Email, EventAddress from mail.protocol import LMTPHandler -from tickets.models import IssueThread +from tickets.models import IssueThread, StateChange def make_mocked_coro(return_value=mock.sentinel, raise_exception=mock.sentinel): @@ -102,9 +102,11 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test self.assertTrue(Email.objects.all()[1].reference.endswith("@localhost>")) self.assertEqual("<1@test>", Email.objects.all()[1].in_reply_to) self.assertEqual('test', IssueThread.objects.all()[0].name) - self.assertEqual('pending_new', IssueThread.objects.all()[0].state) + #self.assertEqual('pending_new', IssueThread.objects.all()[0].state) self.assertEqual(None, IssueThread.objects.all()[0].assigned_to) - + states = StateChange.objects.filter(issue_thread=IssueThread.objects.all()[0]) + self.assertEqual(1, len(states)) + self.assertEqual('pending_new', states[0].state) def test_handle_quoted_printable(self): from aiosmtpd.smtp import Envelope from asgiref.sync import async_to_sync @@ -126,7 +128,6 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test self.assertEqual('Text mit Quoted-Printable-Kodierung: äöüß', Email.objects.all()[0].body) def test_handle_quoted_printable_2(self): - #=?UTF-8?Q?suche_M=C3=BCtze?= from aiosmtpd.smtp import Envelope from asgiref.sync import async_to_sync import aiosmtplib @@ -249,3 +250,53 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test self.assertTrue(Email.objects.all()[2].reference.startswith("<")) self.assertTrue(Email.objects.all()[2].reference.endswith("@localhost>")) self.assertEqual(Email.objects.all()[2].in_reply_to, mail1.reference) + + def test_match_event(self): + event = Event.objects.create( + name="Test event", + slug="test-event", + ) + event_address = EventAddress.objects.create( + event=event, + address="test_event@localhost", + ) + from aiosmtpd.smtp import Envelope + from asgiref.sync import async_to_sync + import aiosmtplib + aiosmtplib.send = make_mocked_coro() + handler = LMTPHandler() + server = mock.Mock() + session = mock.Mock() + envelope = Envelope() + envelope.mail_from = 'test1@test' + envelope.rcpt_tos = ['test_event@localhost'] + envelope.content = b'Subject: test\nFrom: test1@test\nTo: test_event@localhost\nMessage-ID: <1@test>\n\ntest' + result = async_to_sync(handler.handle_DATA)(server, session, envelope) + self.assertEqual(result, '250 Message accepted for delivery') + self.assertEqual(len(Email.objects.all()), 2) + self.assertEqual(len(IssueThread.objects.all()), 1) + aiosmtplib.send.assert_called_once() + self.assertEqual(event, Email.objects.all()[0].event) + self.assertEqual(event, Email.objects.all()[1].event) + self.assertEqual('test', Email.objects.all()[0].subject) + self.assertEqual('Message received', Email.objects.all()[1].subject) + self.assertEqual('test1@test', Email.objects.all()[0].sender) + self.assertEqual('test_event@localhost', Email.objects.all()[0].recipient) + self.assertEqual('test_event@localhost', Email.objects.all()[1].sender) + self.assertEqual('test1@test', Email.objects.all()[1].recipient) + self.assertEqual('test', Email.objects.all()[0].body) + self.assertEqual('Thank you for your message.', Email.objects.all()[1].body) + self.assertEqual(IssueThread.objects.all()[0], Email.objects.all()[0].issue_thread) + self.assertEqual(IssueThread.objects.all()[0], Email.objects.all()[1].issue_thread) + self.assertEqual('<1@test>', Email.objects.all()[0].reference) + self.assertEqual(None, Email.objects.all()[0].in_reply_to) + self.assertTrue(Email.objects.all()[1].reference.startswith("<")) + self.assertTrue(Email.objects.all()[1].reference.endswith("@localhost>")) + self.assertEqual("<1@test>", Email.objects.all()[1].in_reply_to) + self.assertEqual('test', IssueThread.objects.all()[0].name) + self.assertEqual(None, IssueThread.objects.all()[0].assigned_to) + states = StateChange.objects.filter(issue_thread=IssueThread.objects.all()[0]) + self.assertEqual(1, len(states)) + self.assertEqual('pending_new', states[0].state) + +