diff options
-rw-r--r-- | service/pixelated/adapter/mailstore/leap_mailstore.py | 40 | ||||
-rw-r--r-- | service/pixelated/adapter/model/mail.py | 6 | ||||
-rw-r--r-- | service/pixelated/adapter/services/mail_service.py | 2 | ||||
-rw-r--r-- | service/pixelated/config/services.py | 2 | ||||
-rw-r--r-- | service/pixelated/resources/mail_resource.py | 13 | ||||
-rw-r--r-- | service/pixelated/resources/mails_resource.py | 2 | ||||
-rw-r--r-- | service/pixelated/support/replier.py | 32 | ||||
-rw-r--r-- | service/test/integration/test_leap_mailstore.py | 78 | ||||
-rw-r--r-- | service/test/support/integration/model.py | 3 | ||||
-rw-r--r-- | service/test/unit/adapter/mailstore/test_leap_mail.py | 102 | ||||
-rw-r--r-- | service/test/unit/adapter/services/test_mail_sender.py | 6 | ||||
-rw-r--r-- | service/test/unit/adapter/test_draft_service.py | 2 | ||||
-rw-r--r-- | service/test/unit/adapter/test_mail.py | 16 | ||||
-rw-r--r-- | service/test/unit/adapter/test_mail_service.py | 8 | ||||
-rw-r--r-- | service/test/unit/support/test_replier.py | 42 |
15 files changed, 111 insertions, 243 deletions
diff --git a/service/pixelated/adapter/mailstore/leap_mailstore.py b/service/pixelated/adapter/mailstore/leap_mailstore.py index c2912bbe..cf8c8ed1 100644 --- a/service/pixelated/adapter/mailstore/leap_mailstore.py +++ b/service/pixelated/adapter/mailstore/leap_mailstore.py @@ -121,6 +121,9 @@ class LeapMail(Mail): return result + def remove_duplicates(self, values): + return list(set(values)) + def _decoded_header_utf_8(self, header_value): if isinstance(header_value, list): return self.remove_duplicates([self._decoded_header_utf_8(v) for v in header_value]) @@ -143,47 +146,12 @@ class LeapMail(Mail): 'body': self._body, 'security_casing': self.security_casing, 'textPlainBody': self._body, - 'replying': self._replying_dict(), 'mailbox': self._mailbox_name.lower(), 'attachments': [attachment.as_dict() for attachment in self._attachments] } - def _replying_dict(self): - result = {'single': None, 'all': {'to-field': [], 'cc-field': []}} - - sender_mail = self._decoded_header_utf_8(self.headers.get('Reply-To', self.headers.get('From'))) - # Issue #215: Fix for existing mails without any from address. - if sender_mail is None: - sender_mail = InputMail.FROM_EMAIL_ADDRESS - - recipients = self._reply_recipient('To') - recipients = self._decoded_header_utf_8(recipients) - recipients.append(sender_mail) - recipients = self.remove_duplicates(recipients) - ccs = self._decoded_header_utf_8(self._reply_recipient('Cc')) - - result['single'] = sender_mail - result['all']['to-field'] = self._remove_me(recipients) if len(recipients) > 1 else recipients - result['all']['cc-field'] = self._remove_me(ccs) if len(ccs) > 1 else ccs - return result - - def _remove_me(self, recipients): - return [recipient for recipient in recipients if not self._parsed_mail_matches(recipient, InputMail.FROM_EMAIL_ADDRESS)] - - def remove_duplicates(self, recipients): - return list(set(recipients)) - def _reply_recipient(self, kind): - recipients = self.headers.get(kind, []) - if not recipients: - recipients = [] - - return recipients - - def _parsed_mail_matches(self, to_parse, expected): - if InputMail.FROM_EMAIL_ADDRESS is None: - return False - return parseaddr(to_parse)[1] == expected + return self.headers.get(kind, []) @staticmethod def from_dict(mail_dict): diff --git a/service/pixelated/adapter/model/mail.py b/service/pixelated/adapter/model/mail.py index dd2f4c0d..76df076e 100644 --- a/service/pixelated/adapter/model/mail.py +++ b/service/pixelated/adapter/model/mail.py @@ -141,8 +141,6 @@ class Mail(object): class InputMail(Mail): - FROM_EMAIL_ADDRESS = None - def __init__(self): self._raw_message = None self._fd = None @@ -193,12 +191,12 @@ class InputMail(Mail): }) @staticmethod - def from_dict(mail_dict): + def from_dict(mail_dict, from_address): input_mail = InputMail() input_mail.headers = {key.capitalize(): value for key, value in mail_dict.get('header', {}).items()} input_mail.headers['Date'] = date.mail_date_now() - input_mail.headers['From'] = InputMail.FROM_EMAIL_ADDRESS + input_mail.headers['From'] = from_address input_mail.body = mail_dict.get('body', '') input_mail.tags = set(mail_dict.get('tags', [])) diff --git a/service/pixelated/adapter/services/mail_service.py b/service/pixelated/adapter/services/mail_service.py index 75c0808e..cf47bfa6 100644 --- a/service/pixelated/adapter/services/mail_service.py +++ b/service/pixelated/adapter/services/mail_service.py @@ -96,7 +96,7 @@ class MailService(object): @defer.inlineCallbacks def send_mail(self, content_dict): - mail = InputMail.from_dict(content_dict) + mail = InputMail.from_dict(content_dict, self.account_email) draft_id = content_dict.get('ident') yield self.mail_sender.sendmail(mail) diff --git a/service/pixelated/config/services.py b/service/pixelated/config/services.py index 114609e0..048d04a4 100644 --- a/service/pixelated/config/services.py +++ b/service/pixelated/config/services.py @@ -22,8 +22,6 @@ class Services(object): @defer.inlineCallbacks def setup(self, leap_home, leap_session): - InputMail.FROM_EMAIL_ADDRESS = leap_session.account_email() - search_index_storage_key = self.setup_search_index_storage_key(leap_session.soledad) yield self.setup_search_engine( leap_home, diff --git a/service/pixelated/resources/mail_resource.py b/service/pixelated/resources/mail_resource.py index 14cb047a..3d151777 100644 --- a/service/pixelated/resources/mail_resource.py +++ b/service/pixelated/resources/mail_resource.py @@ -1,5 +1,6 @@ import json from pixelated.resources import respond_json, respond_json_deferred +from pixelated.support import replier from twisted.web.resource import Resource from twisted.web.server import NOT_DONE_YET from twisted.python.log import err @@ -36,8 +37,18 @@ class Mail(Resource): self._mail_service = mail_service def render_GET(self, request): + def populate_reply(mail): + mail_dict = mail.as_dict() + current_user = self._mail_service.account_email + sender = mail.headers.get('Reply-to', mail.headers.get('From')) + to = mail.headers.get('To', []) + ccs = mail.headers.get('Cc', []) + mail_dict['replying'] = replier.generate_recipients(sender, to, ccs, current_user) + return mail_dict + d = self._mail_service.mail(self._mail_id) - d.addCallback(lambda mail: respond_json_deferred(mail.as_dict(), request)) + d.addCallback(lambda mail: populate_reply(mail)) + d.addCallback(lambda mail_dict: respond_json_deferred(mail_dict, request)) return NOT_DONE_YET def render_DELETE(self, request): diff --git a/service/pixelated/resources/mails_resource.py b/service/pixelated/resources/mails_resource.py index 3a5b6286..a2f07093 100644 --- a/service/pixelated/resources/mails_resource.py +++ b/service/pixelated/resources/mails_resource.py @@ -198,7 +198,7 @@ class MailsResource(Resource): content_dict = json.loads(request.content.read()) with_attachment_content = yield self._fetch_attachment_contents(content_dict) - _mail = InputMail.from_dict(with_attachment_content) + _mail = InputMail.from_dict(with_attachment_content, from_address=self._mail_service.account_email) draft_id = content_dict.get('ident') pixelated_mail = yield self._draft_service.process_draft(draft_id, _mail) diff --git a/service/pixelated/support/replier.py b/service/pixelated/support/replier.py new file mode 100644 index 00000000..0bcb1a27 --- /dev/null +++ b/service/pixelated/support/replier.py @@ -0,0 +1,32 @@ +from email.utils import parseaddr + + +def generate_recipients(sender, to, ccs, current_user): + result = {'single': None, 'all': {'to-field': [], 'cc-field': []}} + + to.append(sender) + to = remove_duplicates(to) + ccs = remove_duplicates(ccs) + + result['single'] = swap_recipient_if_needed(sender, remove_address(to, current_user), current_user) + result['all']['to-field'] = remove_address(to, current_user) if len(to) > 1 else to + result['all']['cc-field'] = remove_address(ccs, current_user) if len(ccs) > 1 else ccs + return result + + +def remove_duplicates(recipients): + return list(set(recipients)) + + +def remove_address(recipients, current_user): + return [recipient for recipient in recipients if not parsed_mail_matches(recipient, current_user)] + + +def parsed_mail_matches(to_parse, expected): + return parseaddr(to_parse)[1] == expected + + +def swap_recipient_if_needed(sender, recipients, current_user): + if len(recipients) == 1 and parsed_mail_matches(sender, current_user): + return recipients[0] + return sender diff --git a/service/test/integration/test_leap_mailstore.py b/service/test/integration/test_leap_mailstore.py index e28fbe5d..885aa62b 100644 --- a/service/test/integration/test_leap_mailstore.py +++ b/service/test/integration/test_leap_mailstore.py @@ -32,7 +32,7 @@ class LeapMailStoreTest(SoledadTestBase): self.maxDiff = None mail = load_mail_from_file('mbox00000000') mail_id = yield self._create_mail_in_soledad(mail) - expected_mail_dict = {'body': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'header': {u'date': u'Tue, 21 Apr 2015 08:43:27 +0000 (UTC)', u'to': [u'carmel@murazikortiz.name'], u'x-tw-pixelated-tags': u'nite, macro, trash', u'from': u'darby.senger@zemlak.biz', u'subject': u'Itaque consequatur repellendus provident sunt quia.'}, 'ident': mail_id, 'status': [], 'tags': set([]), 'replying': {'all': {'cc-field': [], 'to-field': [u'carmel@murazikortiz.name', u'darby.senger@zemlak.biz']}, 'single': u'darby.senger@zemlak.biz'}, 'textPlainBody': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'mailbox': u'inbox', 'attachments': [], 'security_casing': {'imprints': [{'state': 'no_signature_information'}], 'locks': []}} + expected_mail_dict = {'body': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'header': {u'date': u'Tue, 21 Apr 2015 08:43:27 +0000 (UTC)', u'to': [u'carmel@murazikortiz.name'], u'x-tw-pixelated-tags': u'nite, macro, trash', u'from': u'darby.senger@zemlak.biz', u'subject': u'Itaque consequatur repellendus provident sunt quia.'}, 'ident': mail_id, 'status': [], 'tags': set([]), 'textPlainBody': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'mailbox': u'inbox', 'attachments': [], 'security_casing': {'imprints': [{'state': 'no_signature_information'}], 'locks': []}} result = yield self.mail_store.get_mail(mail_id, include_body=True) self.assertIsNotNone(result) @@ -109,83 +109,7 @@ class LeapMailStoreTest(SoledadTestBase): self.assertEqual(mail.mail_id, mails[0]) @defer.inlineCallbacks - def test_get_replying_when_sender_is_not_me(self): - InputMail.FROM_EMAIL_ADDRESS = 'me@pixelated.org' - mail = load_mail_from_file('mbox00000000') - del mail['From'] - del mail['To'] - del mail['Cc'] - mail['From'] = 'not-me@pixelated.org' - mail['To'] = 'addr1@pixelated.org, addr2@pixelated.org' - - yield self.mail_store.add_mailbox('INBOX') - mail = yield self.mail_store.add_mail('INBOX', mail.as_string()) - - replying = mail.as_dict()['replying'] - - self.assertEqual(replying['single'], 'not-me@pixelated.org') - self.assertEqual(replying['all']['to-field'], [u'addr1@pixelated.org', u'addr2@pixelated.org', u'not-me@pixelated.org']) - self.assertListEqual(replying['all']['cc-field'], []) - - @defer.inlineCallbacks - def test_get_replying_when_sender_is_me(self): - InputMail.FROM_EMAIL_ADDRESS = 'me@pixelated.org' - mail = load_mail_from_file('mbox00000000') - del mail['From'] - del mail['To'] - del mail['Cc'] - mail['From'] = 'me@pixelated.org' - mail['To'] = 'addr1@pixelated.org, addr2@pixelated.org' - - yield self.mail_store.add_mailbox('INBOX') - mail = yield self.mail_store.add_mail('INBOX', mail.as_string()) - - replying = mail.as_dict()['replying'] - - self.assertEqual(replying['single'], 'me@pixelated.org') - self.assertEqual(replying['all']['to-field'], [u'addr1@pixelated.org', u'addr2@pixelated.org']) - self.assertEqual(replying['all']['cc-field'], []) - - @defer.inlineCallbacks - def test_get_replying_when_sender_is_me_to_me(self): - InputMail.FROM_EMAIL_ADDRESS = 'me@pixelated.org' - mail = load_mail_from_file('mbox00000000') - del mail['From'] - del mail['To'] - del mail['Cc'] - mail['From'] = 'me@pixelated.org' - mail['To'] = 'me@pixelated.org' - - yield self.mail_store.add_mailbox('INBOX') - mail = yield self.mail_store.add_mail('INBOX', mail.as_string()) - - replying = mail.as_dict()['replying'] - - self.assertEqual(replying['single'], 'me@pixelated.org') - self.assertEqual(replying['all']['to-field'], [u'me@pixelated.org']) - self.assertEqual(replying['all']['cc-field'], []) - - @defer.inlineCallbacks - def test_get_replying_when_sender_is_me_to_recipients_including_me(self): - InputMail.FROM_EMAIL_ADDRESS = 'me@pixelated.org' - mail = load_mail_from_file('mbox00000000') - del mail['From'] - del mail['To'] - del mail['Cc'] - mail['From'] = 'me@pixelated.org' - mail['To'] = 'addr1@pixelated.org, me@pixelated.org' - - yield self.mail_store.add_mailbox('INBOX') - mail = yield self.mail_store.add_mail('INBOX', mail.as_string()) - replying = mail.as_dict()['replying'] - - self.assertEqual(replying['single'], 'me@pixelated.org') - self.assertEqual(replying['all']['to-field'], [u'addr1@pixelated.org']) - self.assertEqual(replying['all']['cc-field'], []) - - @defer.inlineCallbacks def test_deleting_a_deleted_mail_doesnt_raise_errors(self): - InputMail.FROM_EMAIL_ADDRESS = 'me@pixelated.org' mail = load_mail_from_file('mbox00000000') yield self.mail_store.add_mailbox('INBOX') mail = yield self.mail_store.add_mail('INBOX', mail.as_string()) diff --git a/service/test/support/integration/model.py b/service/test/support/integration/model.py index c6f6a754..87a18af6 100644 --- a/service/test/support/integration/model.py +++ b/service/test/support/integration/model.py @@ -33,7 +33,6 @@ class MailBuilder: 'body': "Hello,\nThis is the body of this message\n\nRegards,\n\n--\nPixelated.\n", 'status': [] } - InputMail.FROM_EMAIL_ADDRESS = 'Formatted Sender <sender@from.com>' def with_body(self, body): self.mail['body'] = body @@ -80,7 +79,7 @@ class MailBuilder: return json.dumps(self.mail) def build_input_mail(self): - return InputMail.from_dict(self.mail) + return InputMail.from_dict(self.mail, from_address='Formatted Sender <sender@from.com>') def build_leap_mail(self): return LeapMail.from_dict(self.mail) diff --git a/service/test/unit/adapter/mailstore/test_leap_mail.py b/service/test/unit/adapter/mailstore/test_leap_mail.py index 91e960e1..cd8852ad 100644 --- a/service/test/unit/adapter/mailstore/test_leap_mail.py +++ b/service/test/unit/adapter/mailstore/test_leap_mail.py @@ -68,11 +68,6 @@ class TestLeapMail(TestCase): 'imprints': [{'state': 'no_signature_information'}], 'locks': [] }, - 'replying': {'all': {'cc-field': [], - 'to-field': ['receiver@example.test', - 'test@example.test', - 'receiver2@other.test']}, - 'single': 'test@example.test'}, 'attachments': [] } @@ -105,103 +100,6 @@ class TestLeapMail(TestCase): self.assertEqual([expected_address], mail.as_dict()['header']['cc']) self.assertEqual(expected_subject, mail.as_dict()['header']['subject']) - def test_as_dict_replying_with_special_chars(self): - expected_address = u'"\xc4lbert \xdcbr\xf6" <\xe4\xfc\xf6@example.mail>' - mail = LeapMail('', 'INBOX', - {'From': '=?iso-8859-1?q?=22=C4lbert_=DCbr=F6=22_=3C=E4=FC=F6=40example=2Email=3E?=', - 'To': '=?iso-8859-1?q?=22=C4lbert_=DCbr=F6=22_=3C=E4=FC=F6=40example=2Email=3E?=', - 'Cc': '=?iso-8859-1?q?=22=C4lbert_=DCbr=F6=22_=3C=E4=FC=F6=40example=2Email=3E?=', - 'Subject': '=?iso-8859-1?q?H=E4ll=F6_W=F6rld?='}) - self.assertEqual([expected_address], mail.as_dict()['replying']['all']['to-field']) - self.assertEqual([expected_address], mail.as_dict()['replying']['all']['cc-field']) - self.assertEqual(expected_address, mail.as_dict()['replying']['single']) - - def test_reply_all_result_does_not_contain_own_address_in_to_with_spaces(self): - my_address = 'myaddress@example.test' - - with patch('pixelated.adapter.mailstore.leap_mailstore.InputMail.FROM_EMAIL_ADDRESS', my_address): - mail = LeapMail('', 'INBOX', - {'From': 'test@example.test', - 'To': 'receiver@example.test, %s ' % my_address}) - expected_recipients = ['receiver@example.test', 'test@example.test'] - actual_recipients = mail.as_dict()['replying']['all']['to-field'] - expected_recipients.sort() - actual_recipients.sort() - - self.assertEqual(expected_recipients, actual_recipients) - - def test_reply_all_result_does_not_contain_own_address_in_to_with_name(self): - my_address = 'myaddress@example.test' - - with patch('pixelated.adapter.mailstore.leap_mailstore.InputMail.FROM_EMAIL_ADDRESS', my_address): - mail = LeapMail('', 'INBOX', - {'From': 'test@example.test', - 'To': 'receiver@example.test, Folker Bernitt <%s>' % my_address}) - - expected_recipients = ['receiver@example.test', 'test@example.test'] - actual_recipients = mail.as_dict()['replying']['all']['to-field'] - expected_recipients.sort() - actual_recipients.sort() - - self.assertEqual(expected_recipients, actual_recipients) - - # TODO: fix this test - def test_reply_all_does_not_contain_own_address_in_to_field_with_different_encodings(self): - my_address = 'myaddress@example.test' - - with patch('pixelated.adapter.mailstore.leap_mailstore.InputMail.FROM_EMAIL_ADDRESS', my_address): - mail = LeapMail('', 'INBOX', - {'From': 'test@example.test', - 'To': 'receiver@example.test, =?iso-8859-1?q?=C4lbert_=3Cmyaddress=40example=2Etest=3E?='}) - - expected_recipients = [u'receiver@example.test', u'test@example.test'] - actual_recipients = mail.as_dict()['replying']['all']['to-field'] - expected_recipients.sort() - actual_recipients.sort() - - self.assertEqual(expected_recipients, actual_recipients) - - def test_reply_all_result_does_not_contain_own_address_in_cc(self): - my_address = 'myaddress@example.test' - - with patch('pixelated.adapter.mailstore.leap_mailstore.InputMail.FROM_EMAIL_ADDRESS', my_address): - mail = LeapMail('', 'INBOX', - {'From': 'test@example.test', - 'To': 'receiver@example.test', - 'Cc': my_address}) - - self.assertEqual([my_address], mail.as_dict()['replying']['all']['cc-field']) - - def test_reply_all_result_does_not_contain_own_address_if_sender(self): - my_address = 'myaddress@example.test' - - with patch('pixelated.adapter.mailstore.leap_mailstore.InputMail.FROM_EMAIL_ADDRESS', my_address): - mail = LeapMail('', 'INBOX', - {'From': 'myaddress@example.test', - 'To': 'receiver@example.test'}) - - self.assertEqual(['receiver@example.test'], mail.as_dict()['replying']['all']['to-field']) - - def test_reply_all_result_does_contain_own_address_if_only_recipient(self): - my_address = 'myaddress@example.test' - - with patch('pixelated.adapter.mailstore.leap_mailstore.InputMail.FROM_EMAIL_ADDRESS', my_address): - mail = LeapMail('', 'INBOX', - {'From': 'myaddress@example.test', - 'To': 'myaddress@example.test'}) - - self.assertEqual(['myaddress@example.test'], mail.as_dict()['replying']['all']['to-field']) - - def test_reply_result_swaps_sender_and_recipient_if_i_am_the_sender(self): - my_address = 'myaddress@example.test' - - with patch('pixelated.adapter.mailstore.leap_mailstore.InputMail.FROM_EMAIL_ADDRESS', my_address): - mail = LeapMail('', 'INBOX', - {'From': 'myaddress@example.test', - 'To': 'recipient@example.test'}) - - self.assertEqual('myaddress@example.test', mail.as_dict()['replying']['single']) - def test_as_dict_with_mixed_encodings(self): subject = 'Another test with =?iso-8859-1?B?3G1s5Px0?= =?iso-8859-1?Q?s?=' mail = LeapMail('', 'INBOX', diff --git a/service/test/unit/adapter/services/test_mail_sender.py b/service/test/unit/adapter/services/test_mail_sender.py index cd4a84c3..9a7e8fea 100644 --- a/service/test/unit/adapter/services/test_mail_sender.py +++ b/service/test/unit/adapter/services/test_mail_sender.py @@ -67,7 +67,7 @@ class MailSenderTest(unittest.TestCase): @defer.inlineCallbacks def test_iterates_over_recipients(self): - input_mail = InputMail.from_dict(mail_dict()) + input_mail = InputMail.from_dict(mail_dict(), from_address='pixelated@org') when(OutgoingMail).send_message(any(), any()).thenReturn(defer.succeed(None)) @@ -78,7 +78,7 @@ class MailSenderTest(unittest.TestCase): @defer.inlineCallbacks def test_problem_with_email_raises_exception(self): - input_mail = InputMail.from_dict(mail_dict()) + input_mail = InputMail.from_dict(mail_dict(), from_address='pixelated@org') when(OutgoingMail).send_message(any(), any()).thenReturn(defer.fail(Exception('pretend something went wrong'))) @@ -91,7 +91,7 @@ class MailSenderTest(unittest.TestCase): @defer.inlineCallbacks def test_iterates_over_recipients_and_send_whitout_bcc_field(self): - input_mail = InputMail.from_dict(mail_dict()) + input_mail = InputMail.from_dict(mail_dict(), from_address='pixelated@org') bccs = input_mail.bcc when(OutgoingMail).send_message(any(), any()).thenReturn(defer.succeed(None)) diff --git a/service/test/unit/adapter/test_draft_service.py b/service/test/unit/adapter/test_draft_service.py index bf5e18c5..c2516013 100644 --- a/service/test/unit/adapter/test_draft_service.py +++ b/service/test/unit/adapter/test_draft_service.py @@ -22,7 +22,7 @@ class DraftServiceTest(unittest.TestCase): verify(self.mail_store).add_mail('DRAFTS', mail.raw) def test_update_draft(self): - mail = InputMail.from_dict(test_helper.mail_dict()) + mail = InputMail.from_dict(test_helper.mail_dict(), from_address='pixelated@org') when(self.mail_store).delete_mail(mail.ident).thenReturn(defer.succeed(True)) when(self.mail_store).add_mail('DRAFTS', mail.raw).thenReturn(defer.succeed(LeapMail('id', 'DRAFTS'))) diff --git a/service/test/unit/adapter/test_mail.py b/service/test/unit/adapter/test_mail.py index 6e4943fa..d66eddd9 100644 --- a/service/test/unit/adapter/test_mail.py +++ b/service/test/unit/adapter/test_mail.py @@ -81,7 +81,7 @@ class InputMailTest(unittest.TestCase): mail_dict['header']['cc'] = '' mail_dict['header']['subject'] = '' - mime_multipart = InputMail.from_dict(mail_dict).to_mime_multipart() + mime_multipart = InputMail.from_dict(mail_dict, from_address='pixelated@org').to_mime_multipart() self.assertNotRegexpMatches(mime_multipart.as_string(), "\nTo: \n") self.assertNotRegexpMatches(mime_multipart.as_string(), "\nBcc: \n") @@ -99,14 +99,14 @@ class InputMailTest(unittest.TestCase): } } - result = InputMail.from_dict(mail_single_recipient).raw + result = InputMail.from_dict(mail_single_recipient, from_address='pixelated@org').raw self.assertRegexpMatches(result, 'To: to@pixelated.org') def test_to_mime_multipart(self): pixelated.support.date.mail_date_now = lambda: 'date now' - mime_multipart = InputMail.from_dict(simple_mail_dict()).to_mime_multipart() + mime_multipart = InputMail.from_dict(simple_mail_dict(), from_address='pixelated@org').to_mime_multipart() self.assertRegexpMatches(mime_multipart.as_string(), "\nTo: to@pixelated.org, anotherto@pixelated.org\n") self.assertRegexpMatches(mime_multipart.as_string(), "\nCc: cc@pixelated.org, anothercc@pixelated.org\n") @@ -120,20 +120,18 @@ class InputMailTest(unittest.TestCase): mail_dict['header']['to'] = u'"Älbert Übrö \xF0\x9F\x92\xA9" <äüö@example.mail>' pixelated.support.date.mail_date_now = lambda: 'date now' - mime_multipart = InputMail.from_dict(mail_dict).to_mime_multipart() + mime_multipart = InputMail.from_dict(mail_dict, from_address='pixelated@org').to_mime_multipart() expected_part_of_encoded_to = 'Iiwgw4QsIGwsIGIsIGUsIHIsIHQsICAsIMOcLCBiLCByLCDDtiwgICwgw7As' self.assertRegexpMatches(mime_multipart.as_string(), expected_part_of_encoded_to) def test_smtp_format(self): - InputMail.FROM_EMAIL_ADDRESS = 'pixelated@org' - - smtp_format = InputMail.from_dict(simple_mail_dict()).to_smtp_format() + smtp_format = InputMail.from_dict(simple_mail_dict(), from_address='pixelated@org').to_smtp_format() self.assertRegexpMatches(smtp_format, "\nFrom: pixelated@org") def test_to_mime_multipart_handles_alternative_bodies(self): - mime_multipart = InputMail.from_dict(multipart_mail_dict()).to_mime_multipart() + mime_multipart = InputMail.from_dict(multipart_mail_dict(), from_address='pixelated@org').to_mime_multipart() part_one = 'Content-Type: text/plain; charset="us-ascii"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\n\nHello world!' part_two = 'Content-Type: text/html; charset="us-ascii"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\n\n<p>Hello html world!</p>' @@ -142,7 +140,7 @@ class InputMailTest(unittest.TestCase): self.assertRegexpMatches(mime_multipart.as_string(), part_two) def test_raw_with_attachment_data(self): - input_mail = InputMail.from_dict(with_attachment_mail_dict()) + input_mail = InputMail.from_dict(with_attachment_mail_dict(), from_address='pixelated@org') attachment = MIMENonMultipart('text', 'plain', Content_Disposition='attachment; filename=ayoyo.txt') attachment.set_payload('Hello World') diff --git a/service/test/unit/adapter/test_mail_service.py b/service/test/unit/adapter/test_mail_service.py index 27c80fde..a8b6d597 100644 --- a/service/test/unit/adapter/test_mail_service.py +++ b/service/test/unit/adapter/test_mail_service.py @@ -45,7 +45,7 @@ class TestMailService(unittest.TestCase): def test_send_mail(self): input_mail = InputMail() - when(InputMail).from_dict(ANY()).thenReturn(input_mail) + when(InputMail).from_dict(ANY(), ANY()).thenReturn(input_mail) when(self.mail_sender).sendmail(ANY()).thenReturn(defer.Deferred()) sent_deferred = self.mail_service.send_mail(mail_dict()) @@ -60,7 +60,7 @@ class TestMailService(unittest.TestCase): def test_send_mail_removes_draft(self): mail = LeapMail('id', 'INBOX') when(mail).raw = 'raw mail' - when(InputMail).from_dict(ANY()).thenReturn(mail) + when(InputMail).from_dict(ANY(), ANY()).thenReturn(mail) when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None)) when(self.mail_store).add_mail('SENT', ANY()).thenReturn(mail) @@ -77,7 +77,7 @@ class TestMailService(unittest.TestCase): def test_send_mail_marks_as_read(self): mail = InputMail() when(mail).raw = 'raw mail' - when(InputMail).from_dict(ANY()).thenReturn(mail) + when(InputMail).from_dict(ANY(), ANY()).thenReturn(mail) when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None)) when(self.mail_sender).sendmail(mail).thenReturn(defer.succeed(None)) @@ -93,7 +93,7 @@ class TestMailService(unittest.TestCase): @defer.inlineCallbacks def test_send_mail_does_not_delete_draft_on_error(self): input_mail = InputMail() - when(InputMail).from_dict(ANY()).thenReturn(input_mail) + when(InputMail).from_dict(ANY(), ANY()).thenReturn(input_mail) deferred_failure = defer.fail(Exception("Assume sending mail failed")) when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_failure) diff --git a/service/test/unit/support/test_replier.py b/service/test/unit/support/test_replier.py new file mode 100644 index 00000000..5e1c234a --- /dev/null +++ b/service/test/unit/support/test_replier.py @@ -0,0 +1,42 @@ +import unittest +from pixelated.support import replier + + +class TestReplier(unittest.TestCase): + def test_reply_all_dont_exclude_own_address_if_only_recipient(self): + current_user = sender = 'me@pixelated.org' + to = [sender] + cc = [] + + reply_dict = replier.generate_recipients(sender, to, cc, current_user) + expected = {'single': sender, 'all': {'to-field': [current_user], 'cc-field': []}} + self.assertEquals(expected, reply_dict) + + def test_reply_all_does_not_contain_own_address_in_to(self): + current_user = 'me@pixelated.org' + sender = 'sender@pixelated.org' + to = ['test@pixelated.org', current_user] + cc = [] + + reply_dict = replier.generate_recipients(sender, to, cc, current_user) + expected = {'single': sender, 'all': {'to-field': ['test@pixelated.org', sender], 'cc-field': []}} + self.assertEquals(expected, reply_dict) + + def test_reply_all_does_not_contain_own_address_in_cc(self): + current_user = 'me@pixelated.org' + sender = 'sender@pixelated.org' + to = ['test@pixelated.org'] + cc = ['test2@pixelated.org', current_user] + + reply_dict = replier.generate_recipients(sender, to, cc, current_user) + expected = {'single': sender, 'all': {'to-field': ['test@pixelated.org', sender], 'cc-field': ['test2@pixelated.org']}} + self.assertEquals(expected, reply_dict) + + def test_reply_single_swaps_current_user_and_recipient_if_a_am_the_sender(self): + current_user = sender = 'me@pixelated.org' + to = ['test@pixelated.org'] + cc = [] + + reply_dict = replier.generate_recipients(sender, to, cc, current_user) + expected = {'single': 'test@pixelated.org', 'all': {'to-field': ['test@pixelated.org'], 'cc-field': []}} + self.assertEquals(expected, reply_dict) |