diff options
-rw-r--r-- | service/pixelated/adapter/mailstore/leap_mailstore.py | 33 | ||||
-rw-r--r-- | service/pixelated/adapter/search/__init__.py | 10 | ||||
-rw-r--r-- | service/pixelated/adapter/services/mail_service.py | 3 | ||||
-rw-r--r-- | service/test/integration/test_leap_mailstore.py | 2 | ||||
-rw-r--r-- | service/test/unit/adapter/mailstore/test_leap_mailstore.py | 15 | ||||
-rw-r--r-- | service/test/unit/adapter/test_mail_service.py | 26 |
6 files changed, 68 insertions, 21 deletions
diff --git a/service/pixelated/adapter/mailstore/leap_mailstore.py b/service/pixelated/adapter/mailstore/leap_mailstore.py index 1bcab036..df9a9b44 100644 --- a/service/pixelated/adapter/mailstore/leap_mailstore.py +++ b/service/pixelated/adapter/mailstore/leap_mailstore.py @@ -21,7 +21,7 @@ from pixelated.adapter.mailstore.body_parser import BodyParser from pixelated.adapter.mailstore.mailstore import MailStore, underscore_uuid from leap.mail.mail import Message -from pixelated.adapter.model.mail import Mail +from pixelated.adapter.model.mail import Mail, InputMail class LeapMail(Mail): @@ -39,7 +39,7 @@ class LeapMail(Mail): cpy = dict(self._headers) for name in set(self._headers.keys()).intersection(['To', 'Cc', 'Bcc']): - cpy[name] = self._headers[name].split(',') if self._headers[name] else None + cpy[name] = self._headers[name].split(',') if self._headers[name] else [] return cpy @@ -85,9 +85,36 @@ class LeapMail(Mail): 'ident': self._mail_id, 'tags': self.tags, 'status': list(self.status), - 'body': self._body + 'body': self._body, + 'textPlainBody': self._body, + 'replying': self._replying_dict(), + 'mailbox': self._mailbox_name.lower() } + def _replying_dict(self): + result = {'single': None, 'all': {'to-field': [], 'cc-field': []}} + + sender_mail = 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.append(sender_mail) + ccs = self._reply_recipient('Cc') + + result['single'] = sender_mail + result['all']['to-field'] = recipients + result['all']['cc-field'] = ccs + return result + + def _reply_recipient(self, kind): + recipients = self.headers.get(kind, []) + if not recipients: + recipients = [] + + return [recipient for recipient in recipients if recipient != InputMail.FROM_EMAIL_ADDRESS] + class LeapMailStore(MailStore): __slots__ = ('soledad') diff --git a/service/pixelated/adapter/search/__init__.py b/service/pixelated/adapter/search/__init__.py index e1ce5e8c..46691926 100644 --- a/service/pixelated/adapter/search/__init__.py +++ b/service/pixelated/adapter/search/__init__.py @@ -129,9 +129,9 @@ class SearchEngine(object): 'sender': self._unicode_header_field(header.get('from', '')), 'subject': self._unicode_header_field(header.get('subject', '')), 'date': milliseconds(header.get('date', '')), - 'to': u','.join([h for h in header.get('to', [''])]), - 'cc': u','.join([h for h in header.get('cc', [''])]), - 'bcc': u','.join([h for h in header.get('bcc', [''])]), + 'to': self._format_recipient(header, 'to'), + 'cc': self._format_recipient(header, 'cc'), + 'bcc': self._format_recipient(header, 'bcc'), 'tag': u','.join(unique(tags)), 'bounced': u','.join(bounced), 'body': unicode(mdict['textPlainBody'] if 'textPlainBody' in mdict else mdict['body']), @@ -142,6 +142,10 @@ class SearchEngine(object): writer.update_document(**index_data) + def _format_recipient(self, headers, name): + list = headers.get(name, ['']) + return u','.join(list) if list else u'' + def _unicode_header_field(self, field_value): if not field_value: return None diff --git a/service/pixelated/adapter/services/mail_service.py b/service/pixelated/adapter/services/mail_service.py index 0c2884ed..b3f58448 100644 --- a/service/pixelated/adapter/services/mail_service.py +++ b/service/pixelated/adapter/services/mail_service.py @@ -71,7 +71,7 @@ class MailService(object): return [_use_current_casing(new_tag.lower()) if new_tag.lower() in current_tags_lower else new_tag for new_tag in new_tags] def mail(self, mail_id): - return self.mail_store.get_mail(mail_id) + return self.mail_store.get_mail(mail_id, include_body=True) def attachment(self, attachment_id, encoding): return self.querier.attachment(attachment_id, encoding) @@ -115,6 +115,7 @@ class MailService(object): @defer.inlineCallbacks def delete_mail(self, mail_id): mail = yield self.mail(mail_id) + print 'go mail %s' % mail if mail.mailbox_name.upper() == u'TRASH': yield self.mail_store.delete_mail(mail_id) else: diff --git a/service/test/integration/test_leap_mailstore.py b/service/test/integration/test_leap_mailstore.py index 48764194..5b6c2f16 100644 --- a/service/test/integration/test_leap_mailstore.py +++ b/service/test/integration/test_leap_mailstore.py @@ -28,7 +28,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([])} + 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'} result = yield self.mail_store.get_mail(mail_id, include_body=True) self.assertIsNotNone(result) diff --git a/service/test/unit/adapter/mailstore/test_leap_mailstore.py b/service/test/unit/adapter/mailstore/test_leap_mailstore.py index df9f8aeb..d8d724c6 100644 --- a/service/test/unit/adapter/mailstore/test_leap_mailstore.py +++ b/service/test/unit/adapter/mailstore/test_leap_mailstore.py @@ -75,7 +75,13 @@ class TestLeapMail(TestCase): 'ident': 'doc id', 'tags': {'foo', 'bar'}, 'status': [], - 'body': None + 'body': None, + 'textPlainBody': None, + 'replying': {'all': {'cc-field': [], + 'to-field': ['receiver@example.test', + 'receiver2@other.test', + 'test@example.test']}, + 'single': 'test@example.test'}, } self.assertEqual(expected, mail.as_dict()) @@ -95,6 +101,13 @@ class TestLeapMail(TestCase): expected_raw = 'To: receiver@example.test\nFrom: test@example.test\nSubject: A test Mail\n\nsome body content' self.assertEqual(expected_raw, result) + def test_headers_none_recipients_are_converted_to_empty_array(self): + mail = LeapMail('id', 'INBOX', {'To':None, 'Cc': None, 'Bcc': None}) + + self.assertEquals([], mail.headers['To']) + self.assertEquals([], mail.headers['Cc']) + self.assertEquals([], mail.headers['Bcc']) + class TestLeapMailStore(TestCase): def setUp(self): diff --git a/service/test/unit/adapter/test_mail_service.py b/service/test/unit/adapter/test_mail_service.py index ec386611..de140997 100644 --- a/service/test/unit/adapter/test_mail_service.py +++ b/service/test/unit/adapter/test_mail_service.py @@ -20,7 +20,7 @@ from pixelated.adapter.model.status import Status from pixelated.adapter.services.mail_service import MailService from test.support.test_helper import mail_dict, leap_mail -from mockito import mock, unstub, when, verify, verifyNoMoreInteractions, any, any as ANY +from mockito import mock, unstub, when, verify, verifyNoMoreInteractions, any as ANY from twisted.internet import defer @@ -44,8 +44,8 @@ class TestMailService(unittest.TestCase): unstub() def test_send_mail(self): - when(InputMail).from_dict(any()).thenReturn('inputmail') - when(self.mail_sender).sendmail(any()).thenReturn(defer.Deferred()) + when(InputMail).from_dict(ANY()).thenReturn('inputmail') + when(self.mail_sender).sendmail(ANY()).thenReturn(defer.Deferred()) sent_deferred = self.mail_service.send_mail(mail_dict()) @@ -59,12 +59,12 @@ class TestMailService(unittest.TestCase): def test_send_mail_removes_draft(self): mail = mock() when(mail).raw = 'raw mail' - when(InputMail).from_dict(any()).thenReturn(mail) + when(InputMail).from_dict(ANY()).thenReturn(mail) when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None)) when(self.mail_store).add_mail('SENT', ANY()).thenReturn(defer.succeed(None)) deferred_success = defer.succeed(None) - when(self.mail_sender).sendmail(any()).thenReturn(deferred_success) + when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_success) yield self.mail_service.send_mail({'ident': '12'}) @@ -74,10 +74,10 @@ class TestMailService(unittest.TestCase): @defer.inlineCallbacks def test_send_mail_does_not_delete_draft_on_error(self): - when(InputMail).from_dict(any()).thenReturn('inputmail') + when(InputMail).from_dict(ANY()).thenReturn('inputmail') deferred_failure = defer.fail(Exception("Assume sending mail failed")) - when(self.mail_sender).sendmail(any()).thenReturn(deferred_failure) + when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_failure) try: yield self.mail_service.send_mail({'ident': '12'}) @@ -86,19 +86,21 @@ class TestMailService(unittest.TestCase): verify(self.mail_sender).sendmail("inputmail") verifyNoMoreInteractions(self.drafts) + @defer.inlineCallbacks def test_mark_as_read(self): mail = LeapMail('id', 'INBOX') - when(self.mail_store).get_mail(any()).thenReturn(mail) - self.mail_service.mark_as_read(1) + when(self.mail_store).get_mail(ANY(), include_body=True).thenReturn(mail) + yield self.mail_service.mark_as_read(1) - verify(self.mail_store).update_mail(mail) self.assertIn(Status.SEEN, mail.flags) + verify(self.mail_store).update_mail(mail) + @defer.inlineCallbacks def test_delete_mail(self): mail_to_delete = LeapMail(1, 'INBOX') - when(self.mail_store).get_mail(1).thenReturn(defer.succeed(mail_to_delete)) + when(self.mail_store).get_mail(1, include_body=True).thenReturn(defer.succeed(mail_to_delete)) - self.mail_service.delete_mail(1) + yield self.mail_service.delete_mail(1) verify(self.mail_store).move_mail_to_mailbox(1, 'TRASH') |