summaryrefslogtreecommitdiff
path: root/service/test/support/integration
diff options
context:
space:
mode:
Diffstat (limited to 'service/test/support/integration')
-rw-r--r--service/test/support/integration/__init__.py19
-rw-r--r--service/test/support/integration/app_test_client.py156
-rw-r--r--service/test/support/integration/model.py88
-rw-r--r--service/test/support/integration/soledad_test_base.py83
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