diff options
Diffstat (limited to 'service/test/support/integration')
-rw-r--r-- | service/test/support/integration/__init__.py | 1 | ||||
-rw-r--r-- | service/test/support/integration/app_test_client.py | 126 | ||||
-rw-r--r-- | service/test/support/integration/model.py | 11 | ||||
-rw-r--r-- | service/test/support/integration/soledad_test_base.py | 28 | ||||
-rw-r--r-- | service/test/support/integration/util.py | 31 |
5 files changed, 147 insertions, 50 deletions
diff --git a/service/test/support/integration/__init__.py b/service/test/support/integration/__init__.py index 8d0bbb7a..1c94eab8 100644 --- a/service/test/support/integration/__init__.py +++ b/service/test/support/integration/__init__.py @@ -16,3 +16,4 @@ from .app_test_client import AppTestClient from .model import MailBuilder, ResponseMail from .soledad_test_base import SoledadTestBase +from .util import load_mail_from_file diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py index 52372507..369a393d 100644 --- a/service/test/support/integration/app_test_client.py +++ b/service/test/support/integration/app_test_client.py @@ -15,26 +15,31 @@ # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. import json import multiprocessing +from leap.mail.adaptors.soledad import SoledadMailAdaptor from mockito import mock import os import shutil import time import uuid +import random -from leap.mail.imap.account import SoledadBackedAccount + +from leap.mail.imap.account import IMAPAccount from leap.soledad.client import Soledad -from mock import MagicMock, Mock -from twisted.internet import reactor +from mock import Mock +from twisted.internet import reactor, defer from twisted.internet.defer import succeed from twisted.web.resource import getChildForRequest -from twisted.web.server import Site +# from twisted.web.server import Site as PixelatedSite +from pixelated.adapter.services.feedback_service import FeedbackService +from pixelated.config.site import PixelatedSite + +from pixelated.adapter.mailstore import LeapMailStore +from pixelated.adapter.mailstore.searchable_mailstore import SearchableMailStore -from pixelated.adapter.model.mail import PixelatedMail from pixelated.adapter.search import SearchEngine from pixelated.adapter.services.draft_service import DraftService from pixelated.adapter.services.mail_service import MailService -from pixelated.adapter.services.mailboxes import Mailboxes -from pixelated.adapter.soledad.soledad_querier import SoledadQuerier from pixelated.resources.root_resource import RootResource from test.support.integration.model import MailBuilder from test.support.test_helper import request_mock @@ -47,33 +52,39 @@ class AppTestClient(object): ACCOUNT = 'test' MAIL_ADDRESS = 'test@pixelated.org' - def __init__(self): - self.start_client() + # def __init__(self): + # self.start_client() + @defer.inlineCallbacks def start_client(self): soledad_test_folder = self._generate_soledad_test_folder_name() SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder self.cleanup = lambda: shutil.rmtree(soledad_test_folder) - PixelatedMail.from_email_address = self.MAIL_ADDRESS + self.soledad = yield initialize_soledad(tempdir=soledad_test_folder) - self.soledad = initialize_soledad(tempdir=soledad_test_folder) - self.soledad_querier = self._create_soledad_querier(self.soledad, self.INDEX_KEY) self.keymanager = mock() self.search_engine = SearchEngine(self.INDEX_KEY, agent_home=soledad_test_folder) self.mail_sender = self._create_mail_sender() - self.account = SoledadBackedAccount(self.ACCOUNT, self.soledad, MagicMock()) - self.mailboxes = Mailboxes(self.account, self.soledad_querier, self.search_engine) - self.draft_service = DraftService(self.mailboxes) + self.mail_store = SearchableMailStore(LeapMailStore(self.soledad), self.search_engine) - self.mail_service = self._create_mail_service(self.mailboxes, self.mail_sender, self.soledad_querier, self.search_engine) - self.search_engine.index_mails(self.mail_service.all_mails()) + account_ready_cb = defer.Deferred() + self.account = IMAPAccount(self.ACCOUNT, self.soledad, account_ready_cb) + yield account_ready_cb + self.draft_service = DraftService(self.mail_store) + self.leap_session = mock() + self.feedback_service = FeedbackService(self.leap_session) + + self.mail_service = self._create_mail_service(self.mail_sender, self.mail_store, self.search_engine) + mails = yield self.mail_service.all_mails() + self.search_engine.index_mails(mails) self.resource = RootResource() - self.resource.initialize(self.keymanager, self.search_engine, self.mail_service, self.draft_service) + self.resource.initialize( + self.keymanager, self.search_engine, self.mail_service, self.draft_service, self.feedback_service) def _render(self, request, as_json=True): def get_str(_str): @@ -95,9 +106,12 @@ class AppTestClient(object): d.addCallback(get_request_written_data) return d, request - def run_on_a_thread(self, logfile='/tmp/app_test_client.log', port=4567, host='0.0.0.0'): + def listenTCP(self, port=4567, host='127.0.0.1'): + reactor.listenTCP(port, PixelatedSite(self.resource), interface=host) + + def run_on_a_thread(self, logfile='/tmp/app_test_client.log', port=4567, host='127.0.0.1'): def _start(): - reactor.listenTCP(port, Site(self.resource), interface=host) + self.listenTCP(port, host) reactor.run() process = multiprocessing.Process(target=_start) process.start() @@ -121,37 +135,38 @@ class AppTestClient(object): request = request_mock(path=path, body=body, headers={'Content-Type': ['application/json']}, method="DELETE") return self._render(request) - def add_document_to_soledad(self, _dict): - self.soledad_querier.soledad.create_doc(_dict) - + @defer.inlineCallbacks def add_mail_to_inbox(self, input_mail): - mail = self.mailboxes.inbox.add(input_mail) - if input_mail.tags: - mail.update_tags(input_mail.tags) - self.search_engine.index_mail(mail) + mail = yield self.mail_store.add_mail('INBOX', input_mail.raw) + defer.returnValue(mail) + @defer.inlineCallbacks def add_multiple_to_mailbox(self, num, mailbox='', flags=[], tags=[], to='recipient@to.com', cc='recipient@cc.com', bcc='recipient@bcc.com'): mails = [] + yield self.mail_store.add_mailbox(mailbox) for _ in range(num): - input_mail = MailBuilder().with_status(flags).with_tags(tags).with_to(to).with_cc(cc).with_bcc(bcc).build_input_mail() - mail = self.mailboxes._create_or_get(mailbox).add(input_mail) + builder = MailBuilder().with_status(flags).with_tags(tags).with_to(to).with_cc(cc).with_bcc(bcc) + builder.with_body(str(random.random())) + input_mail = builder.build_input_mail() + mail = yield self.mail_store.add_mail(mailbox, input_mail.raw) + if tags: + mail.tags |= set(tags) + if flags: + for flag in flags: + mail.flags.add(flag) + if tags or flags: + yield self.mail_store.update_mail(mail) mails.append(mail) - mail.update_tags(input_mail.tags) if tags else None - self.search_engine.index_mails(mails) if tags else None - return mails - def _create_soledad_querier(self, soledad, index_key): - soledad_querier = SoledadQuerier(soledad) - soledad_querier.get_index_masterkey = lambda: index_key - return soledad_querier + defer.returnValue(mails) def _create_mail_sender(self): mail_sender = Mock() mail_sender.sendmail.side_effect = lambda mail: succeed(mail) return mail_sender - def _create_mail_service(self, mailboxes, mail_sender, soledad_querier, search_engine): - mail_service = MailService(mailboxes, mail_sender, soledad_querier, search_engine) + def _create_mail_service(self, mail_sender, mail_store, search_engine): + mail_service = MailService(mail_sender, mail_store, search_engine) return mail_service def _generate_soledad_test_folder_name(self, soledad_test_folder='/tmp/soledad-test/test'): @@ -161,17 +176,27 @@ class AppTestClient(object): tags = 'tag:%s' % tag return self.search(tags, page, window) + @defer.inlineCallbacks def search(self, query, page=1, window=100): - res, req = self.get("/mails", { + res, _ = self.get("/mails", { 'q': [query], 'w': [str(window)], 'p': [str(page)] }) - return [ResponseMail(m) for m in res['mails']] + res = yield res + defer.returnValue([ResponseMail(m) for m in res['mails']]) + + @defer.inlineCallbacks + def get_mails_by_mailbox_name(self, mbox_name): + mail_ids = yield self.mail_store.get_mailbox_mail_ids(mbox_name) + mails = yield self.mail_store.get_mails(mail_ids) + defer.returnValue(mails) + @defer.inlineCallbacks def get_attachment(self, ident, encoding): - res, req = self.get("/attachment/%s" % ident, {'encoding': [encoding]}, as_json=False) - return res + deferred_result, req = self.get("/attachment/%s" % ident, {'encoding': [encoding]}, as_json=False) + res = yield deferred_result + defer.returnValue((res, req)) def put_mail(self, data): res, req = self.put('/mails', data) @@ -191,25 +216,26 @@ class AppTestClient(object): def delete_mail(self, mail_ident): res, req = self.delete("/mail/%s" % mail_ident) - return req + return res def delete_mails(self, idents): res, req = self.post("/mails/delete", json.dumps({'idents': idents})) - return req + return res def mark_many_as_unread(self, idents): res, req = self.post('/mails/unread', json.dumps({'idents': idents})) - return req + return res def mark_many_as_read(self, idents): res, req = self.post('/mails/read', json.dumps({'idents': idents})) - return req + return res def get_contacts(self, query): res, req = self.get('/contacts', get_args={'q': query}) return res +@defer.inlineCallbacks def initialize_soledad(tempdir): if os.path.isdir(tempdir): shutil.rmtree(tempdir) @@ -240,5 +266,9 @@ def initialize_soledad(tempdir): local_db_path, server_url, cert_file, - defer_encryption=False) - return _soledad + defer_encryption=False, + syncable=False) + + yield SoledadMailAdaptor().initialize_store(_soledad) + + defer.returnValue(_soledad) diff --git a/service/test/support/integration/model.py b/service/test/support/integration/model.py index e90a3ec5..c6f6a754 100644 --- a/service/test/support/integration/model.py +++ b/service/test/support/integration/model.py @@ -15,6 +15,7 @@ # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. import json +from pixelated.support import date from pixelated.adapter.model.mail import InputMail from pixelated.adapter.model.status import Status @@ -26,7 +27,8 @@ class MailBuilder: 'to': ['recipient@to.com'], 'cc': ['recipient@cc.com'], 'bcc': ['recipient@bcc.com'], - 'subject': 'Hi! This the subject' + 'subject': 'Hi! This the subject', + 'date': date.mail_date_now() }, 'body': "Hello,\nThis is the body of this message\n\nRegards,\n\n--\nPixelated.\n", 'status': [] @@ -45,6 +47,10 @@ class MailBuilder: self.mail['header']['subject'] = subject return self + def with_from(self, sender): + self.mail['header']['from'] = sender + return self + def with_to(self, to): self.mail['header']['to'] = to return self @@ -76,6 +82,9 @@ class MailBuilder: def build_input_mail(self): return InputMail.from_dict(self.mail) + def build_leap_mail(self): + return LeapMail.from_dict(self.mail) + class ResponseMail: def __init__(self, mail_dict): diff --git a/service/test/support/integration/soledad_test_base.py b/service/test/support/integration/soledad_test_base.py index c49de00a..e3e582d2 100644 --- a/service/test/support/integration/soledad_test_base.py +++ b/service/test/support/integration/soledad_test_base.py @@ -13,8 +13,14 @@ # # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. +from uuid import uuid4 +from leap.mail.adaptors.soledad import SoledadMailAdaptor +from leap.mail.mail import Message +from twisted.internet import defer from twisted.trial import unittest +from pixelated.adapter.mailstore import LeapMailStore from test.support.integration.app_test_client import AppTestClient +from leap.common.events.flags import set_events_enabled class SoledadTestBase(unittest.TestCase, AppTestClient): @@ -22,8 +28,28 @@ class SoledadTestBase(unittest.TestCase, AppTestClient): DEFERRED_TIMEOUT = 120 DEFERRED_TIMEOUT_LONG = 300 + @defer.inlineCallbacks def setUp(self): - self.start_client() + set_events_enabled(False) + super(SoledadTestBase, self).setUp() + self.adaptor = SoledadMailAdaptor() + self.mbox_uuid = str(uuid4()) + yield self.start_client() def tearDown(self): + set_events_enabled(True) self.cleanup() + + @defer.inlineCallbacks + def _create_mail_in_soledad(self, mail): + yield self.adaptor.initialize_store(self.soledad) + mbox = yield self.adaptor.get_or_create_mbox(self.soledad, 'INBOX') + message = self._convert_mail_to_leap_message(mail, mbox.uuid) + yield self.adaptor.create_msg(self.soledad, message) + + defer.returnValue(message.get_wrapper().mdoc.doc_id) + + def _convert_mail_to_leap_message(self, mail, mbox_uuid): + message = self.adaptor.get_msg_from_string(Message, mail.as_string()) + message.get_wrapper().set_mbox_uuid(mbox_uuid) + return message diff --git a/service/test/support/integration/util.py b/service/test/support/integration/util.py new file mode 100644 index 00000000..302edeaa --- /dev/null +++ b/service/test/support/integration/util.py @@ -0,0 +1,31 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see <http://www.gnu.org/licenses/>. +from email.parser import Parser +from email.utils import make_msgid +import os +import pkg_resources + + +def load_mail_from_file(mail_file, enforceUniqueMessageId=False): + mailset_dir = pkg_resources.resource_filename('test.unit.fixtures', 'mailset') + mail_file = os.path.join(mailset_dir, 'new', mail_file) + with open(mail_file) as f: + mail = Parser().parse(f) + + if enforceUniqueMessageId: + mail.add_header('Message-Id', make_msgid()) + + return mail |