From 70e6d825d6b3e6804d42f931f30a18445650f9b2 Mon Sep 17 00:00:00 2001 From: Duda Dornelles Date: Wed, 21 Jan 2015 19:48:50 -0200 Subject: #240 Adapted tests after change to twisted web --- service/pixelated/resources/__init__.py | 3 +- service/pixelated/resources/mails_resource.py | 8 +- .../test/integration/retrieve_attachment_test.py | 8 +- .../test/support/integration/app_test_client.py | 43 ++++--- service/test/support/test_helper.py | 21 ++++ service/test/unit/controllers/__init__.py | 0 .../test/unit/controllers/mails_controller_test.py | 126 --------------------- .../unit/controllers/sync_info_controller_test.py | 53 --------- service/test/unit/resources/__init__.py | 0 .../unit/resources/sync_info_controller_test.py | 54 +++++++++ 10 files changed, 106 insertions(+), 210 deletions(-) delete mode 100644 service/test/unit/controllers/__init__.py delete mode 100644 service/test/unit/controllers/mails_controller_test.py delete mode 100644 service/test/unit/controllers/sync_info_controller_test.py create mode 100644 service/test/unit/resources/__init__.py create mode 100644 service/test/unit/resources/sync_info_controller_test.py (limited to 'service') diff --git a/service/pixelated/resources/__init__.py b/service/pixelated/resources/__init__.py index a2e4c9d4..9e9c154e 100644 --- a/service/pixelated/resources/__init__.py +++ b/service/pixelated/resources/__init__.py @@ -19,7 +19,8 @@ def respond_json(entity, request, status_code=200): json_response = json.dumps(entity) request.responseHeaders.addRawHeader(b"content-type", b"application/json") request.code = status_code - return json_response + request.write(json_response) + request.finish() def respond_json_deferred(entity, request, status_code=200): diff --git a/service/pixelated/resources/mails_resource.py b/service/pixelated/resources/mails_resource.py index 75c73349..d391382d 100644 --- a/service/pixelated/resources/mails_resource.py +++ b/service/pixelated/resources/mails_resource.py @@ -24,7 +24,7 @@ class MailsUnreadResource(Resource): for ident in idents: mail = self._mail_service.mark_as_unread(ident) self._search_engine.index_mail(mail) - return "" + return respond_json(None, request) class MailsReadResource(Resource): @@ -42,7 +42,7 @@ class MailsReadResource(Resource): for ident in idents: mail = self._mail_service.mark_as_read(ident) self._search_engine.index_mail(mail) - return "" + return respond_json(None, request) class MailsDeleteResource(Resource): @@ -89,11 +89,11 @@ class MailsResource(Resource): response = { "stats": { "total": total, - }, + }, "mails": [mail.as_dict() for mail in mails] } - return json.dumps(response) + return respond_json(response, request) def render_POST(self, request): try: diff --git a/service/test/integration/retrieve_attachment_test.py b/service/test/integration/retrieve_attachment_test.py index 5f754a27..41ffd89d 100644 --- a/service/test/integration/retrieve_attachment_test.py +++ b/service/test/integration/retrieve_attachment_test.py @@ -36,6 +36,10 @@ class RetrieveAttachmentTest(SoledadTestBase): self.client.add_document_to_soledad(attachment_dict) - attachment = self.get_attachment(ident, 'base64') + d = self.get_attachment(ident, 'base64') - self.assertEquals('pequeno anexo :D\n', attachment) + def _assert(attachment): + self.assertEquals('pequeno anexo :D\n', attachment) + d.addCallback(_assert) + + return d diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py index b032eefd..47674e75 100644 --- a/service/test/support/integration/app_test_client.py +++ b/service/test/support/integration/app_test_client.py @@ -18,8 +18,6 @@ import multiprocessing import shutil import time -from pixelated.config.routes import setup_routes -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 @@ -29,12 +27,15 @@ 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.adapter.services.tag_service import TagService -from pixelated.resources import FeaturesController, HomeController, MailsController, TagsController, \ - SyncInfoController, AttachmentsController, ContactsController +from pixelated.resources.root_resource import RootResource import pixelated.runserver from pixelated.adapter.model.mail import PixelatedMail from pixelated.adapter.search import SearchEngine from test.support.integration.model import MailBuilder +from test.support.test_helper import request_mock +from twisted.internet.defer import succeed +from twisted.web import server +from twisted.web.resource import getChildForRequest class AppTestClient: @@ -63,32 +64,26 @@ class AppTestClient: 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) - contacts_controller = ContactsController(search_engine=self.search_engine) - sync_info_controller = SyncInfoController() - attachments_controller = AttachmentsController(self.soledad_querier) + self.app.resource = RootResource() - setup_routes(self.app, home_controller, mails_controller, tags_controller, - features_controller, sync_info_controller, attachments_controller, contacts_controller) + self.app.resource.initialize(self.soledad_querier, self.search_engine, self.mail_service, self.draft_service) def _render(self, request, as_json=True): def get_request_written_data(_=None): - written_data = request.getWrittenData() + written_data = None + if len(request.written): + written_data = request.written[0] if written_data: return json.loads(written_data) if as_json else written_data - d = _render(self.app.resource(), request) + resource = getChildForRequest(self.app.resource, request) + + result = resource.render(request) + if request.finished: return get_request_written_data(), request else: - d.addCallback(get_request_written_data) - return d, request + return request.notifyFinish().addCallback(lambda _: request).addCallback(get_request_written_data), request def run_on_a_thread(self, logfile='/tmp/app_test_client.log', port=4567, host='localhost'): worker = lambda: self.app.run(host=host, port=port, logFile=open(logfile, 'w')) @@ -98,20 +93,20 @@ class AppTestClient: return lambda: process.terminate() def get(self, path, get_args, as_json=True): - request = requestMock(path) + request = request_mock(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']}) + request = request_mock(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']}) + request = request_mock(path=path, method="PUT", body=body, headers={'Content-Type': ['application/json']}) return self._render(request) def delete(self, path, body=""): - request = requestMock(path=path, body=body, headers={'Content-Type': ['application/json']}, method="DELETE") + 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): diff --git a/service/test/support/test_helper.py b/service/test/support/test_helper.py index ff1de64a..f43776d1 100644 --- a/service/test/support/test_helper.py +++ b/service/test/support/test_helper.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see . from datetime import datetime +import io from pixelated.adapter.model.mail import InputMail @@ -79,3 +80,23 @@ class TestRequest: def __init__(self, json): self.json = json + + +from twisted.web.test.test_web import DummyRequest + + +class PixRequestMock(DummyRequest): + def __init__(self, path): + DummyRequest.__init__(self, path) + self.content = None + self.code = None + + +def request_mock(path='', method='GET', body='', headers={}): + dummy = PixRequestMock(path.split('/')) + for name, value in headers.iteritems(): + dummy.setHeader(name, value) + dummy.method = method + dummy.content = io.BytesIO(body) + return dummy + diff --git a/service/test/unit/controllers/__init__.py b/service/test/unit/controllers/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/service/test/unit/controllers/mails_controller_test.py b/service/test/unit/controllers/mails_controller_test.py deleted file mode 100644 index 7e5d0e7d..00000000 --- a/service/test/unit/controllers/mails_controller_test.py +++ /dev/null @@ -1,126 +0,0 @@ -# -# 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 . -import json -import unittest -from io import BytesIO - -from klein.test_resource import requestMock -from mock import MagicMock -from mockito import * -from pixelated.resources.mails_controller import MailsController - - -class TestMailsController(unittest.TestCase): - - def setUp(self): - self.mail_service = mock() - self.search_engine = mock() - self.dummy_request = MagicMock(spec=['code', 'responseHeaders']) - draft_service = mock() - - self.mails_controller = MailsController(mail_service=self.mail_service, - draft_service=draft_service, - search_engine=self.search_engine) - - self.input_mail = mock() - self.input_mail.json = {'header': {'from': 'a@a.a', 'to': 'b@b.b'}, - 'ident': 1, - 'tags': [], - 'status': [], - 'security_casing': {}, - 'body': 'email body'} - - def tearDown(self): - unstub() - - def test_sending_mail_return_sent_mail_data_when_send_succeeds(self): - self.mail_service.send = self._successfuly_send_mail - request = requestMock('', body=json.dumps(self.input_mail.json)) - - result = self.mails_controller.send_mail(request) - - self.assertEqual(request.code, 200) - self.assertEqual(result, - '{"status": [], "body": "email body", "ident": 1, "tags": [], "header": {"to": "b@b.b", "from": "a@a.a"}, "security_casing": {}}') - - def test_sending_mail_return_error_message_when_send_fails(self): - self.mail_service.send = self._send_that_throws_exception - - request = requestMock('', body=json.dumps(self.input_mail.json)) - result = self.mails_controller.send_mail(request) - - self.assertEqual(request.code, 422) - self.assertEqual(result, - '{"message": "email sending failed\\nmore information of error\\n123\\nthere was a code before this"}') - - def test_fetching_mail_gets_mail_from_mail_service(self): - mail = mock() - mail.as_dict = lambda: {'ident': 1, 'body': 'le mail body'} - when(self.mail_service).mail(1).thenReturn(mail) - - response = self.mails_controller.mail(self.dummy_request, 1) - - verify(self.mail_service).mail(1) - self.assertEqual(response, '{"body": "le mail body", "ident": 1}') - - def test_marking_mail_as_read_set_mail_as_read_on_the_service(self): - mail = mock() - when(self.mail_service).mark_as_read("1").thenReturn(mail) - when(self.search_engine).index_mail(mail).thenReturn(None) - self.dummy_request.content = BytesIO('{"idents":["1"]}') - - self.mails_controller.mark_many_mail_read(self.dummy_request) - - verify(self.mail_service).mark_as_read(u'1') - verify(self.search_engine).index_mail(mail) - - def test_marking_mail_as_unread_set_mail_as_unread_on_the_service(self): - mail = mock() - when(self.mail_service).mark_as_unread("1").thenReturn(mail) - when(self.search_engine).index_mail(mail).thenReturn(None) - self.dummy_request.content = BytesIO('{"idents":["1"]}') - - self.mails_controller.mark_many_mail_unread(self.dummy_request) - - verify(self.mail_service).mark_as_unread(u'1') - verify(self.search_engine).index_mail(mail) - - def test_move_message_to_trash(self): - mail = mock() - mail.mailbox_name = 'INBOX' - when(self.mail_service).mail(1).thenReturn(mail) - when(self.mail_service).delete_mail(1).thenReturn(mail) - - self.mails_controller.delete_mail(self.dummy_request, 1) - - verify(self.search_engine).index_mail(mail) - - def test_delete_permanently_when_mail_in_trash(self): - mail = mock() - mail.mailbox_name = 'TRASH' - when(self.mail_service).mail(1).thenReturn(mail) - self.mails_controller.delete_mail(self.dummy_request, 1) - - verify(self.mail_service).delete_permanent(1) - - def _successfuly_send_mail(self, ident, mail): - sent_mail = mock() - sent_mail.as_dict = lambda: self.input_mail.json - - return sent_mail - - def _send_that_throws_exception(self, ident, mail): - raise Exception('email sending failed', 'more information of error', 123, 'there was a code before this') diff --git a/service/test/unit/controllers/sync_info_controller_test.py b/service/test/unit/controllers/sync_info_controller_test.py deleted file mode 100644 index 1fb38822..00000000 --- a/service/test/unit/controllers/sync_info_controller_test.py +++ /dev/null @@ -1,53 +0,0 @@ -# -# 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 . -import unittest -import json - -from mock import MagicMock -from pixelated.resources import SyncInfoController -from mockito import * - - -class SyncInfoControllerTest(unittest.TestCase): - - def setUp(self): - self.dummy_request = MagicMock() - self.controller = SyncInfoController() - - def _set_count(self, current, total): - soledad_sync_data = mock() - soledad_sync_data.content = "%s/%s" % (current, total) - self.controller.set_sync_info(soledad_sync_data) - - def get_sync_info(self): - return json.loads(self.controller.sync_info(self.dummy_request)) - - def test_is_not_syncing_if_total_is_equal_to_current(self): - self._set_count(total=0, current=0) - - sync_info = self.get_sync_info() - - self.assertFalse(sync_info['is_syncing']) - - def test_is_syncing_if_total_is_not_equal_to_current_and_adds_count(self): - self._set_count(total=10, current=5) - - sync_info = self.get_sync_info() - - self.assertTrue(sync_info['is_syncing']) - self.assertEquals(5, sync_info['count']['current']) - self.assertEquals(10, sync_info['count']['total']) - self.assertEquals(0.5, sync_info['count']['progress']) diff --git a/service/test/unit/resources/__init__.py b/service/test/unit/resources/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/service/test/unit/resources/sync_info_controller_test.py b/service/test/unit/resources/sync_info_controller_test.py new file mode 100644 index 00000000..c24c7181 --- /dev/null +++ b/service/test/unit/resources/sync_info_controller_test.py @@ -0,0 +1,54 @@ +# +# 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 . +import unittest +import json + +from test.support.test_helper import request_mock +from pixelated.resources.sync_info_resource import SyncInfoResource +from mockito import * + + +class SyncInfoControllerTest(unittest.TestCase): + + def setUp(self): + self.dummy_request = request_mock() + self.controller = SyncInfoResource() + + def _set_count(self, current, total): + soledad_sync_data = mock() + soledad_sync_data.content = "%s/%s" % (current, total) + self.controller.set_sync_info(soledad_sync_data) + + def get_sync_info(self): + self.controller.render_GET(self.dummy_request) + return json.loads(self.dummy_request.written[0]) + + def test_is_not_syncing_if_total_is_equal_to_current(self): + self._set_count(total=0, current=0) + + sync_info = self.get_sync_info() + + self.assertFalse(sync_info['is_syncing']) + + def test_is_syncing_if_total_is_not_equal_to_current_and_adds_count(self): + self._set_count(total=10, current=5) + + sync_info = self.get_sync_info() + + self.assertTrue(sync_info['is_syncing']) + self.assertEquals(5, sync_info['count']['current']) + self.assertEquals(10, sync_info['count']['total']) + self.assertEquals(0.5, sync_info['count']['progress']) -- cgit v1.2.3