From 9aeb6a319fdc3c6724d5f6a0cf9e1f0cb69e7302 Mon Sep 17 00:00:00 2001 From: jedi Date: Wed, 10 Jan 2024 19:03:40 +0100 Subject: [PATCH] set state to 'open' when receiving reply on a ticket that is not in state 'new' --- core/mail/protocol.py | 6 ++++ core/mail/tests/v2/test_mails.py | 52 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/core/mail/protocol.py b/core/mail/protocol.py index 7d5c68f..9a515fb 100644 --- a/core/mail/protocol.py +++ b/core/mail/protocol.py @@ -180,12 +180,18 @@ def receive_email(envelope, log=None): reply = None if new: + # auto reply if new issue references = collect_references(active_issue_thread) reply_email = Email.objects.create( sender=recipient, recipient=sender, body="Thank you for your message.", subject="Message received", in_reply_to=header_message_id, event=target_event, issue_thread=active_issue_thread) reply = make_reply(reply_email, references) + else: + #change state if not new + if active_issue_thread.state != 'pending_new': + active_issue_thread.state = 'pending_open' + active_issue_thread.save() return email, new, reply diff --git a/core/mail/tests/v2/test_mails.py b/core/mail/tests/v2/test_mails.py index 84aa7ec..a66eb66 100644 --- a/core/mail/tests/v2/test_mails.py +++ b/core/mail/tests/v2/test_mails.py @@ -215,6 +215,58 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test self.assertEqual(IssueThread.objects.all()[0].state, 'pending_new') self.assertEqual(IssueThread.objects.all()[0].assigned_to, None) + def test_handle_client_reply_2(self): + issue_thread = IssueThread.objects.create( + name="test", + ) + mail1 = Email.objects.create( + subject='test subject', + body='test', + sender='test1@test', + recipient='test2@test', + issue_thread=issue_thread, + ) + mail1_reply = Email.objects.create( + subject='Message received', + body='Thank you for your message.', + sender='test2@test', + recipient='test1@test', + in_reply_to=mail1.reference, + issue_thread=issue_thread, + ) + StateChange.objects.create( + issue_thread=issue_thread, + state='waiting_details', + ) + self.assertEqual(IssueThread.objects.all()[0].state, 'waiting_details') + 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 = ['test2@test'] + envelope.content = (f'Subject: Re: test\nFrom: test3@test\nTo: test4@test\nMessage-ID: <3@test>\n' + f'In-Reply-To: {mail1_reply.reference}'.encode('utf-8') + b'\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()), 3) + self.assertEqual(len(IssueThread.objects.all()), 1) + aiosmtplib.send.assert_not_called() + self.assertEqual(Email.objects.all()[2].subject, 'Re: test') + self.assertEqual(Email.objects.all()[2].sender, 'test1@test') + self.assertEqual(Email.objects.all()[2].recipient, 'test2@test') + self.assertEqual(Email.objects.all()[2].body, 'test') + self.assertEqual(Email.objects.all()[2].issue_thread, issue_thread) + self.assertEqual(Email.objects.all()[2].reference, '<3@test>') + self.assertEqual(Email.objects.all()[2].in_reply_to, mail1_reply.reference) + self.assertEqual(IssueThread.objects.all()[0].name, 'test') + self.assertEqual(IssueThread.objects.all()[0].state, 'pending_open') + self.assertEqual(IssueThread.objects.all()[0].assigned_to, None) + def test_mail_reply(self): issue_thread = IssueThread.objects.create( name="test",