diff options
author | Duda Dornelles <ddornell@thoughtworks.com> | 2014-11-19 12:06:05 -0200 |
---|---|---|
committer | Duda Dornelles <ddornell@thoughtworks.com> | 2014-11-19 12:08:36 -0200 |
commit | a7e4c6238e29962653d2c53ad2887eab6e98b420 (patch) | |
tree | ca37991e2d72acc60d1d95ff05a6b9a21b663ef9 /service/test/support/integration | |
parent | 68a906b6eec347481a0b7aa4c60e24ff02f5c26e (diff) |
better organization for integration test support classes
Diffstat (limited to 'service/test/support/integration')
-rw-r--r-- | service/test/support/integration/__init__.py | 19 | ||||
-rw-r--r-- | service/test/support/integration/app_test_client.py | 156 | ||||
-rw-r--r-- | service/test/support/integration/model.py | 88 | ||||
-rw-r--r-- | service/test/support/integration/soledad_test_base.py | 83 |
4 files changed, 346 insertions, 0 deletions
diff --git a/service/test/support/integration/__init__.py b/service/test/support/integration/__init__.py new file mode 100644 index 00000000..bb2f0263 --- /dev/null +++ b/service/test/support/integration/__init__.py @@ -0,0 +1,19 @@ +# +# 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 .app_test_client import AppTestClient +from .model import MailBuilder, ResponseMail +from .soledad_test_base import SoledadTestBase + diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py new file mode 100644 index 00000000..f6a95422 --- /dev/null +++ b/service/test/support/integration/app_test_client.py @@ -0,0 +1,156 @@ +# +# 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/>. +import json +import shutil + +from klein.test_resource import requestMock, _render +from leap.mail.imap.account import SoledadBackedAccount +from leap.soledad.client import Soledad +from mock import MagicMock, Mock +import os +from pixelated.adapter.draft_service import DraftService +from pixelated.adapter.mail_service import MailService +from pixelated.adapter.mailboxes import Mailboxes +from pixelated.adapter.soledad_querier import SoledadQuerier +from pixelated.adapter.tag_service import TagService +from pixelated.config import app_factory +from pixelated.controllers import FeaturesController, HomeController, MailsController, TagsController, \ + SyncInfoController, AttachmentsController +import pixelated.runserver +from pixelated.adapter.mail import PixelatedMail +from pixelated.adapter.search import SearchEngine +from test.support.integration.model import MailBuilder + + +class AppTestClient: + def __init__(self, soledad_test_folder='soledad-test'): + + self.soledad = initialize_soledad(tempdir=soledad_test_folder) + self.mail_address = "test@pixelated.org" + + # setup app + PixelatedMail.from_email_address = self.mail_address + + SearchEngine.INDEX_FOLDER = soledad_test_folder + '/search_index' + + self.app = pixelated.runserver.app + + self.soledad_querier = SoledadQuerier(self.soledad) + self.soledad_querier.get_index_masterkey = lambda: '_yg2oG_5ELM8_-sQYcsxI37WesI0dOtZQXpwAqjvhR4=' + + self.account = SoledadBackedAccount('test', self.soledad, MagicMock()) + self.mailboxes = Mailboxes(self.account, self.soledad_querier) + self.mail_sender = Mock() + self.tag_service = TagService() + self.draft_service = DraftService(self.mailboxes) + self.mail_service = MailService(self.mailboxes, self.mail_sender, self.tag_service, + self.soledad_querier) + self.search_engine = SearchEngine(self.soledad_querier) + self.search_engine.index_mails(self.mail_service.all_mails()) + + features_controller = FeaturesController() + features_controller.DISABLED_FEATURES.append('autoReload') + home_controller = HomeController() + mails_controller = MailsController(mail_service=self.mail_service, + draft_service=self.draft_service, + search_engine=self.search_engine) + tags_controller = TagsController(search_engine=self.search_engine) + sync_info_controller = SyncInfoController() + attachments_controller = AttachmentsController(self.soledad_querier) + + app_factory._setup_routes(self.app, home_controller, mails_controller, tags_controller, + features_controller, sync_info_controller, attachments_controller) + + def _render(self, request, as_json=True): + def get_request_written_data(_=None): + written_data = request.getWrittenData() + if written_data: + return json.loads(written_data) if as_json else written_data + + d = _render(self.app.resource(), request) + if request.finished: + return get_request_written_data(), request + else: + d.addCallback(get_request_written_data) + return d, request + + def get(self, path, get_args, as_json=True): + request = requestMock(path) + request.args = get_args + return self._render(request, as_json) + + def post(self, path, body=''): + request = requestMock(path=path, method="POST", body=body, headers={'Content-Type': ['application/json']}) + return self._render(request) + + def put(self, path, body): + request = requestMock(path=path, method="PUT", body=body, headers={'Content-Type': ['application/json']}) + return self._render(request) + + def delete(self, path): + request = requestMock(path=path, method="DELETE") + return self._render(request) + + def add_document_to_soledad(self, _dict): + self.soledad_querier.soledad.create_doc(_dict) + + def add_mail_to_inbox(self, input_mail): + mail = self.mailboxes.inbox().add(input_mail) + mail.update_tags(input_mail.tags) + self.search_engine.index_mail(mail) + + def add_multiple_to_mailbox(self, num, mailbox='', flags=[], tags=[]): + mails = [] + for _ in range(num): + input_mail = MailBuilder().with_status(flags).with_tags(tags).build_input_mail() + mail = self.mailboxes._create_or_get(mailbox).add(input_mail) + mails.append(mail) + mail.update_tags(input_mail.tags) + self.search_engine.index_mail(mail) + return mails + + +def initialize_soledad(tempdir): + if os.path.isdir(tempdir): + shutil.rmtree(tempdir) + + uuid = "foobar-uuid" + passphrase = u"verysecretpassphrase" + secret_path = os.path.join(tempdir, "secret.gpg") + local_db_path = os.path.join(tempdir, "soledad.u1db") + server_url = "http://provider" + cert_file = "" + + class MockSharedDB(object): + get_doc = Mock(return_value=None) + put_doc = Mock() + lock = Mock(return_value=('atoken', 300)) + unlock = Mock(return_value=True) + close = Mock() + + def __call__(self): + return self + + Soledad._shared_db = MockSharedDB() + + _soledad = Soledad( + uuid, + passphrase, + secret_path, + local_db_path, + server_url, + cert_file) + return _soledad diff --git a/service/test/support/integration/model.py b/service/test/support/integration/model.py new file mode 100644 index 00000000..46da77fd --- /dev/null +++ b/service/test/support/integration/model.py @@ -0,0 +1,88 @@ +# +# 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/>. +import json +from pixelated.adapter.mail import InputMail +from pixelated.adapter.status import Status + + +class MailBuilder: + def __init__(self): + self.mail = { + 'header': { + 'to': ['recipient@to.com'], + 'cc': ['recipient@cc.com'], + 'bcc': ['recipient@bcc.com'], + 'subject': 'Hi! This the subject' + }, + 'body': "Hello,\nThis is the body of this message\n\nRegards,\n\n--\nPixelated.\n", + 'status': [] + } + + def with_body(self, body): + self.mail['body'] = body + return self + + def with_tags(self, tags): + self.mail['tags'] = tags + return self + + def with_subject(self, subject): + self.mail['header']['subject'] = subject + return self + + def with_status(self, flags): + for status in Status.from_flags(flags): + self.mail['status'].append(status) + return self + + def with_date(self, date_string): + self.mail['header']['date'] = date_string + return self + + def with_ident(self, ident): + self.mail['ident'] = ident + return self + + def build_json(self): + return json.dumps(self.mail) + + def build_input_mail(self): + return InputMail.from_dict(self.mail) + + +class ResponseMail: + def __init__(self, mail_dict): + self.mail_dict = mail_dict + + @property + def subject(self): + return self.headers['subject'] + + @property + def headers(self): + return self.mail_dict['header'] + + @property + def ident(self): + return self.mail_dict['ident'] + + @property + def tags(self): + return self.mail_dict['tags'] + + @property + def status(self): + return self.mail_dict['status']
\ No newline at end of file diff --git a/service/test/support/integration/soledad_test_base.py b/service/test/support/integration/soledad_test_base.py new file mode 100644 index 00000000..2221679f --- /dev/null +++ b/service/test/support/integration/soledad_test_base.py @@ -0,0 +1,83 @@ +# +# 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/>. +import unittest + +from pixelated.controllers import * +from test.support.integration.app_test_client import AppTestClient +from test.support.integration.model import ResponseMail + + +class SoledadTestBase(unittest.TestCase): + # these are so long because our CI is so slow at the moment. + DEFERRED_TIMEOUT = 120 + DEFERRED_TIMEOUT_LONG = 300 + + @classmethod + def setUpClass(cls): + from nose.twistedtools import threaded_reactor + + threaded_reactor() + + def setUp(self): + self.client = AppTestClient() + + def get_mails_by_tag(self, tag, page=1, window=100): + res, req = self.client.get("/mails", { + 'q': ['tag:%s' % tag], + 'w': [str(window)], + 'p': [str(page)] + }) + return [ResponseMail(m) for m in res['mails']] + + def post_mail(self, data): + res, req = self.client.post('/mails', data) + return ResponseMail(res) + + def get_attachment(self, ident, encoding): + res, req = self.client.get("/attachment/%s" % ident, {'encoding': [encoding]}, as_json=False) + return res + + def put_mail(self, data): + res, req = self.client.put('/mails', data) + return res['ident'] + + def post_tags(self, mail_ident, tags_json): + res, req = self.client.post("/mail/%s/tags" % mail_ident, tags_json) + return res + + def get_tags(self, **kwargs): + res, req = self.client.get('/tags', kwargs) + return res + + def delete_mail(self, mail_ident): + res, req = self.client.delete("/mail/%s" % mail_ident) + return req + + def mark_as_read(self, mail_ident): + res, req = self.client.post("/mail/%s/read" % mail_ident) + return req + + def mark_as_unread(self, mail_ident): + res, req = self.client.post("/mail/%s/unread" % mail_ident) + return req + + def mark_many_as_unread(self, idents): + res, req = self.client.post('/mails/unread', json.dumps({'idents': idents})) + return req + + def mark_many_as_read(self, idents): + res, req = self.client.post('/mails/read', json.dumps({'idents': idents})) + return req |