From 38d810d338ce671b6389cd47d665b87798bcd65c Mon Sep 17 00:00:00 2001 From: Folker Bernitt Date: Fri, 31 Jul 2015 17:04:25 +0200 Subject: First steps migrating mail service to new data model. --- .../pixelated/adapter/mailstore/leap_mailstore.py | 23 ++++++++++++--- service/pixelated/adapter/mailstore/mailstore.py | 3 ++ service/pixelated/adapter/services/mail_service.py | 6 ++-- service/pixelated/adapter/services/mailboxes.py | 3 +- service/pixelated/config/services.py | 1 + service/pixelated/resources/mails_resource.py | 2 ++ service/test/integration/test_drafts.py | 3 ++ .../test/support/integration/app_test_client.py | 2 +- .../unit/adapter/mailstore/test_leap_mailstore.py | 33 ++++++++++++++++------ service/test/unit/adapter/test_mailboxes.py | 9 +++--- 10 files changed, 64 insertions(+), 21 deletions(-) diff --git a/service/pixelated/adapter/mailstore/leap_mailstore.py b/service/pixelated/adapter/mailstore/leap_mailstore.py index cbb9a28a..c1e9f0d8 100644 --- a/service/pixelated/adapter/mailstore/leap_mailstore.py +++ b/service/pixelated/adapter/mailstore/leap_mailstore.py @@ -76,8 +76,7 @@ class LeapMailStore(MailStore): def update_mail(self, mail): message = yield self._fetch_msg_from_soledad(mail.mail_id) message.get_wrapper().set_tags(tuple(mail.tags)) - message.get_wrapper().update(self.soledad) - pass + self._update_mail(message) @defer.inlineCallbacks def all_mails(self): @@ -123,6 +122,22 @@ class LeapMailStore(MailStore): mbx_wrapper = yield self._get_or_create_mailbox(mailbox_name) yield SoledadMailAdaptor().delete_mbox(self.soledad, mbx_wrapper) + @defer.inlineCallbacks + def copy_mail_to_mailbox(self, mail_id, mailbox_name): + message = yield self._fetch_msg_from_soledad(mail_id, load_body=True) + mailbox = yield self._get_or_create_mailbox(mailbox_name) + + copy_wrapper = yield message.get_wrapper().copy(self.soledad, mailbox.uuid) + + leap_message = Message(copy_wrapper) + + mail = yield self._leap_message_to_leap_mail(copy_wrapper.mdoc.doc_id, leap_message, include_body=False) + + defer.returnValue(mail) + + def _update_mail(self, message): + return message.get_wrapper().update(self.soledad) + @defer.inlineCallbacks def _leap_message_to_leap_mail(self, mail_id, message, include_body): if include_body: @@ -136,8 +151,8 @@ class LeapMailStore(MailStore): def _get_or_create_mailbox(self, mailbox_name): return SoledadMailAdaptor().get_or_create_mbox(self.soledad, mailbox_name) - def _fetch_msg_from_soledad(self, mail_id): - return SoledadMailAdaptor().get_msg_from_mdoc_id(Message, self.soledad, mail_id) + def _fetch_msg_from_soledad(self, mail_id, load_body=False): + return SoledadMailAdaptor().get_msg_from_mdoc_id(Message, self.soledad, mail_id, get_cdocs=load_body) def _is_empty_message(message): diff --git a/service/pixelated/adapter/mailstore/mailstore.py b/service/pixelated/adapter/mailstore/mailstore.py index ab7bfb94..29d4fe67 100644 --- a/service/pixelated/adapter/mailstore/mailstore.py +++ b/service/pixelated/adapter/mailstore/mailstore.py @@ -46,6 +46,9 @@ class MailStore(object): def get_mailbox_mail_ids(self, mailbox_name): pass + def copy_mail_to_mailbox(self, mail_id, mailbox_name): + pass + def underscore_uuid(uuid): return uuid.replace('-', '_') diff --git a/service/pixelated/adapter/services/mail_service.py b/service/pixelated/adapter/services/mail_service.py index 23cbc5f7..708297b9 100644 --- a/service/pixelated/adapter/services/mail_service.py +++ b/service/pixelated/adapter/services/mail_service.py @@ -29,13 +29,13 @@ class MailService(object): @defer.inlineCallbacks def all_mails(self): - defer.returnValue((yield self.querier.all_mails())) + defer.returnValue((yield self.mail_store.all_mails())) @defer.inlineCallbacks def mails(self, query, window_size, page): mail_ids, total = self.search_engine.search(query, window_size, page) - mails = yield self.querier.mails(mail_ids) + mails = yield self.mail_store.get_mails(mail_ids) defer.returnValue((mails, total)) @@ -72,7 +72,7 @@ class MailService(object): @defer.inlineCallbacks def mail_exists(self, mail_id): - defer.returnValue(not(not((yield self.querier.get_header_by_chash(mail_id))))) + defer.returnValue(not (yield self.mail_store.get_mail(mail_id))) @defer.inlineCallbacks def send_mail(self, content_dict): diff --git a/service/pixelated/adapter/services/mailboxes.py b/service/pixelated/adapter/services/mailboxes.py index 80cc74fe..52c9c212 100644 --- a/service/pixelated/adapter/services/mailboxes.py +++ b/service/pixelated/adapter/services/mailboxes.py @@ -22,10 +22,11 @@ from twisted.mail.imap4 import MailboxCollision class Mailboxes(object): - def __init__(self, account, soledad_querier, search_engine): + def __init__(self, account, mail_store, soledad_querier, search_engine): self.account = account self.querier = soledad_querier self.search_engine = search_engine + self.mail_store = mail_store # for mailbox_name in account.mailboxes: # MailboxIndexerListener.listen(self.account, mailbox_name, soledad_querier) diff --git a/service/pixelated/config/services.py b/service/pixelated/config/services.py index a45f9a99..73678ccc 100644 --- a/service/pixelated/config/services.py +++ b/service/pixelated/config/services.py @@ -25,6 +25,7 @@ class Services(object): pixelated_mailboxes = Mailboxes( leap_session.account, + leap_session.soledad_session.soledad, soledad_querier, self.search_engine) yield pixelated_mailboxes.index_mailboxes() diff --git a/service/pixelated/resources/mails_resource.py b/service/pixelated/resources/mails_resource.py index 1056dcdb..d4e8372e 100644 --- a/service/pixelated/resources/mails_resource.py +++ b/service/pixelated/resources/mails_resource.py @@ -146,6 +146,7 @@ class MailsResource(Resource): return server.NOT_DONE_YET def render_PUT(self, request): + print '\nrender_PUT\n' content_dict = json.loads(request.content.read()) _mail = InputMail.from_dict(content_dict) draft_id = content_dict.get('ident') @@ -163,6 +164,7 @@ class MailsResource(Resource): defer_response(self._draft_service.update_draft(draft_id, _mail)) deferred_check.addCallback(return422otherwise) else: + print '\nCreating draft\n' defer_response(self._draft_service.create_draft(_mail)) return server.NOT_DONE_YET diff --git a/service/test/integration/test_drafts.py b/service/test/integration/test_drafts.py index d0505d75..bc314c04 100644 --- a/service/test/integration/test_drafts.py +++ b/service/test/integration/test_drafts.py @@ -77,8 +77,11 @@ class DraftsTest(SoledadTestBase): @defer.inlineCallbacks def test_put_creates_a_draft_if_it_does_not_exist(self): mail = MailBuilder().with_subject('A new draft').build_json() + print '\nAdding mail\n' yield self.put_mail(mail)[0] + print '\nAdded mail\n' mails = yield self.get_mails_by_tag('drafts') + print '\ngot mails by tag\n' self.assertEquals('A new draft', mails[0].subject) diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py index 76b75920..c5e419b1 100644 --- a/service/test/support/integration/app_test_client.py +++ b/service/test/support/integration/app_test_client.py @@ -76,7 +76,7 @@ class AppTestClient(object): account_ready_cb = defer.Deferred() self.account = IMAPAccount(self.ACCOUNT, self.soledad, account_ready_cb) yield account_ready_cb - self.mailboxes = Mailboxes(self.account, self.soledad_querier, self.search_engine) + self.mailboxes = Mailboxes(self.account, self.mail_store, self.soledad_querier, self.search_engine) self.draft_service = DraftService(self.mailboxes) self.mail_service = self._create_mail_service(self.mailboxes, self.mail_sender, self.mail_store, self.soledad_querier, self.search_engine) diff --git a/service/test/unit/adapter/mailstore/test_leap_mailstore.py b/service/test/unit/adapter/mailstore/test_leap_mailstore.py index ec68f3b7..322fa23d 100644 --- a/service/test/unit/adapter/mailstore/test_leap_mailstore.py +++ b/service/test/unit/adapter/mailstore/test_leap_mailstore.py @@ -69,6 +69,7 @@ class TestLeapMailStore(TestCase): self.soledad = mock() self.mbox_uuid = str(uuid4()) self.doc_by_id = {} + self.mbox_uuid_by_name = {} @defer.inlineCallbacks def test_get_mail_not_exist(self): @@ -185,6 +186,7 @@ class TestLeapMailStore(TestCase): self.assertIsNotNone(mbox) self.assertEqual(self.mbox_uuid, mbox.doc_id) self.assertEqual('TEST', mbox.mbox) + # assert index got updated @defer.inlineCallbacks def test_add_mail(self): @@ -233,22 +235,37 @@ class TestLeapMailStore(TestCase): verify(self.soledad).delete_doc(self.doc_by_id[mbox_soledad_doc.doc_id]) # should also verify index is updated - def _assert_message_docs_created(self, expected_message, actual_message): + @defer.inlineCallbacks + def test_copy_mail_to_mailbox(self): + expected_message = self._add_create_mail_mocks_to_soledad('mbox00000000') + mail_id, fdoc_id = self._add_mail_fixture_to_soledad('mbox00000000') + self._mock_get_mailbox('TRASH') + store = LeapMailStore(self.soledad) + + mail = yield store.copy_mail_to_mailbox(mail_id, 'TRASH') + + self._assert_message_docs_created(expected_message, mail, only_mdoc_and_fdoc=True) + + def _assert_message_docs_created(self, expected_message, actual_message, only_mdoc_and_fdoc=False): wrapper = expected_message.get_wrapper() verify(self.soledad).create_doc(wrapper.mdoc.serialize(), doc_id=actual_message.mail_id) verify(self.soledad).create_doc(wrapper.fdoc.serialize(), doc_id=wrapper.fdoc.future_doc_id) - verify(self.soledad).create_doc(wrapper.hdoc.serialize(), doc_id=wrapper.hdoc.future_doc_id) - for nr, cdoc in wrapper.cdocs.items(): - verify(self.soledad).create_doc(cdoc.serialize(), doc_id=wrapper.cdocs[nr].future_doc_id) + if not only_mdoc_and_fdoc: + verify(self.soledad).create_doc(wrapper.hdoc.serialize(), doc_id=wrapper.hdoc.future_doc_id) + for nr, cdoc in wrapper.cdocs.items(): + verify(self.soledad).create_doc(cdoc.serialize(), doc_id=wrapper.cdocs[nr].future_doc_id) - def _mock_get_mailbox(self, mailbox_name): + def _mock_get_mailbox(self, mailbox_name, create_new_uuid=False): + mbox_uuid = self.mbox_uuid if not create_new_uuid else str(uuid4()) when(self.soledad).list_indexes().thenReturn(defer.succeed(MAIL_INDEXES)).thenReturn( defer.succeed(MAIL_INDEXES)) - mbox = MailboxWrapper(doc_id=self.mbox_uuid, mbox=mailbox_name, uuid=self.mbox_uuid) - soledad_doc = SoledadDocument(self.mbox_uuid, json=json.dumps(mbox.serialize())) + mbox = MailboxWrapper(doc_id=mbox_uuid, mbox=mailbox_name, uuid=mbox_uuid) + soledad_doc = SoledadDocument(mbox_uuid, json=json.dumps(mbox.serialize())) when(self.soledad).get_from_index('by-type-and-mbox', 'mbox', mailbox_name).thenReturn(defer.succeed([soledad_doc])) - self._mock_soledad_doc(self.mbox_uuid, mbox) + self._mock_soledad_doc(mbox_uuid, mbox) + + self.mbox_uuid_by_name[mailbox_name] = mbox_uuid return mbox, soledad_doc diff --git a/service/test/unit/adapter/test_mailboxes.py b/service/test/unit/adapter/test_mailboxes.py index 081e47fb..814d36a1 100644 --- a/service/test/unit/adapter/test_mailboxes.py +++ b/service/test/unit/adapter/test_mailboxes.py @@ -17,7 +17,7 @@ import unittest from pixelated.adapter.model.mail import PixelatedMail from pixelated.adapter.services.mailboxes import Mailboxes -from mockito import mock, when, verify +from mockito import mock, when, verify, any as ANY from twisted.internet import defer from test.support import test_helper from mock import MagicMock @@ -27,15 +27,16 @@ class PixelatedMailboxesTest(unittest.TestCase): def setUp(self): self.querier = mock() + self.mail_store = mock() self.search_engine = mock() self.account = MagicMock() - self.mailboxes = Mailboxes(self.account, self.querier, self.search_engine) + self.mailboxes = Mailboxes(self.account, self.mail_store, self.querier, self.search_engine) @defer.inlineCallbacks def test_move_to_inbox(self): mail = PixelatedMail.from_soledad(*test_helper.leap_mail(), soledad_querier=self.querier) - when(self.querier).mail(1).thenReturn(mail) - when(mail).save().thenReturn(None) + when(self.mail_store).mail(1).thenReturn(defer.succeed(mail)) + when(self.mail_store).update_mail(ANY()).thenReturn(defer.succeed(None)) mail.set_mailbox('TRASH') recovered_mail = yield self.mailboxes.move_to_inbox(1) -- cgit v1.2.3