diff options
10 files changed, 0 insertions, 588 deletions
diff --git a/service/pixelated/adapter/soledad/__init__.py b/service/pixelated/adapter/soledad/__init__.py deleted file mode 100644 index 2756a319..00000000 --- a/service/pixelated/adapter/soledad/__init__.py +++ /dev/null @@ -1,15 +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 <http://www.gnu.org/licenses/>. diff --git a/service/pixelated/adapter/soledad/soledad_duplicate_removal_mixin.py b/service/pixelated/adapter/soledad/soledad_duplicate_removal_mixin.py deleted file mode 100644 index a2b4b6d7..00000000 --- a/service/pixelated/adapter/soledad/soledad_duplicate_removal_mixin.py +++ /dev/null @@ -1,46 +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 <http://www.gnu.org/licenses/>. -from pixelated.adapter.soledad.soledad_facade_mixin import SoledadDbFacadeMixin -from twisted.internet import defer - - -class SoledadDuplicateRemovalMixin(SoledadDbFacadeMixin, object): - -    @defer.inlineCallbacks -    def remove_duplicates(self): -        for mailbox in ['INBOX', 'DRAFTS', 'SENT', 'TRASH']: -            yield self._remove_dup_inboxes(mailbox) -            yield self._remove_dup_recent(mailbox) - -    @defer.inlineCallbacks -    def _remove_many(self, docs): -        [(yield self.delete_doc(doc)) for doc in docs] - -    @defer.inlineCallbacks -    def _remove_dup_inboxes(self, mailbox_name): -        mailboxes = yield self.get_mbox(mailbox_name) -        if len(mailboxes) == 0: -            return -        mailboxes_to_remove = sorted(mailboxes, key=lambda x: x.content['created'])[1:len(mailboxes)] -        yield self._remove_many(mailboxes_to_remove) - -    @defer.inlineCallbacks -    def _remove_dup_recent(self, mailbox_name): -        rct = yield self.get_recent_by_mbox(mailbox_name) -        if len(rct) == 0: -            return -        rct_to_remove = sorted(rct, key=lambda x: len(x.content['rct']), reverse=True)[1:len(rct)] -        yield self._remove_many(rct_to_remove) diff --git a/service/pixelated/adapter/soledad/soledad_facade_mixin.py b/service/pixelated/adapter/soledad/soledad_facade_mixin.py deleted file mode 100644 index 81280eaa..00000000 --- a/service/pixelated/adapter/soledad/soledad_facade_mixin.py +++ /dev/null @@ -1,91 +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 <http://www.gnu.org/licenses/>. - -from twisted.internet import defer -from leap.mail.mailbox_indexer import MailboxIndexer - - -class SoledadDbFacadeMixin(object): - -    @defer.inlineCallbacks -    def get_all_flags(self): -        flags = yield self.soledad.get_from_index('by-type', 'flags') -        defer.returnValue(flags) - -    def get_all_flags_by_mbox(self, mbox): -        return self.soledad.get_from_index('by-type-and-mbox', 'flags', mbox) if mbox else [] - -    @defer.inlineCallbacks -    def get_content_by_phash(self, phash): -        content = yield self.soledad.get_from_index('by-type-and-payloadhash', 'cnt', phash) if phash else [] -        if len(content): -            defer.returnValue(content[0]) - -    @defer.inlineCallbacks -    def get_flags_by_chash(self, chash): -        flags = yield self.soledad.get_from_index('by-type-and-contenthash', 'flags', chash) if chash else [] -        if len(flags): -            defer.returnValue(flags[0]) - -    @defer.inlineCallbacks -    def get_header_by_chash(self, chash): -        header = yield self.soledad.get_from_index('by-type-and-contenthash', 'head', chash) if chash else [] -        if len(header): -            defer.returnValue(header[0]) - -    @defer.inlineCallbacks -    def get_recent_by_mbox(self, mbox): -        defer.returnValue( -            (yield self.soledad.get_from_index('by-type-and-mbox', 'rct', mbox) if mbox else [])) - -    def put_doc(self, doc): -        return self.soledad.put_doc(doc) - -    def create_doc(self, doc): -        return self.soledad.create_doc(doc) - -    @defer.inlineCallbacks -    def create_docs(self, docs): -        for doc in docs: -            yield self.create_doc(doc) - -    def delete_doc(self, doc): -        return self.soledad.delete_doc(doc) - -    @defer.inlineCallbacks -    def idents_by_mailbox(self, mbox): -        mbox_docs = (yield self.soledad.get_from_index('by-type-and-mbox-and-deleted', 'flags', mbox, '0')) if mbox else [] -        defer.returnValue(set(doc.content['chash'] for doc in mbox_docs)) - -    def get_all_mbox(self): -        return self.soledad.get_from_index('by-type', 'mbox') - -    def get_mbox(self, mbox): -        return self.soledad.get_from_index('by-type-and-mbox', 'mbox', mbox) if mbox else [] - -    @defer.inlineCallbacks -    def get_lastuid(self, mbox): -        if isinstance(mbox, str): -            mbox = (yield defer.maybeDeferred(self.get_mbox, mbox))[0] - -        indexer = MailboxIndexer(self.soledad) -        yield indexer.create_table(mbox.content['uuid']) -        last_uuid = yield indexer.get_last_uid(mbox.content['uuid']) - -        defer.returnValue(last_uuid) - -    def get_search_index_masterkey(self): -        return self.soledad.get_from_index('by-type', 'index_key') diff --git a/service/pixelated/adapter/soledad/soledad_querier.py b/service/pixelated/adapter/soledad/soledad_querier.py deleted file mode 100644 index e0b215d3..00000000 --- a/service/pixelated/adapter/soledad/soledad_querier.py +++ /dev/null @@ -1,29 +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 <http://www.gnu.org/licenses/>. -from pixelated.adapter.soledad.soledad_duplicate_removal_mixin import SoledadDuplicateRemovalMixin -from pixelated.adapter.soledad.soledad_reader_mixin import SoledadReaderMixin -from pixelated.adapter.soledad.soledad_search_key_masterkey_retrieval_mixin import SoledadSearchIndexMasterkeyRetrievalMixin -from pixelated.adapter.soledad.soledad_writer_mixin import SoledadWriterMixin - - -class SoledadQuerier(SoledadWriterMixin, -                     SoledadReaderMixin, -                     SoledadDuplicateRemovalMixin, -                     SoledadSearchIndexMasterkeyRetrievalMixin, -                     object): - -    def __init__(self, soledad): -        self.soledad = soledad diff --git a/service/pixelated/adapter/soledad/soledad_reader_mixin.py b/service/pixelated/adapter/soledad/soledad_reader_mixin.py deleted file mode 100644 index e86298dd..00000000 --- a/service/pixelated/adapter/soledad/soledad_reader_mixin.py +++ /dev/null @@ -1,130 +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 <http://www.gnu.org/licenses/>. -import base64 -import logging -import quopri -import re - -from twisted.internet import defer -from pixelated.adapter.model.mail import PixelatedMail -from pixelated.adapter.soledad.soledad_facade_mixin import SoledadDbFacadeMixin - - -logger = logging.getLogger(__name__) - - -class SoledadReaderMixin(SoledadDbFacadeMixin, object): - -    @defer.inlineCallbacks -    def all_mails(self): -        fdocs_chash = [(fdoc, fdoc.content['chash']) for fdoc in (yield self.get_all_flags())] -        if len(fdocs_chash) == 0: -            defer.returnValue([]) -        defer.returnValue((yield self._build_mails_from_fdocs(fdocs_chash))) - -    @defer.inlineCallbacks -    def _build_mails_from_fdocs(self, fdocs_chash): -        if len(fdocs_chash) == 0: -            defer.returnValue([]) - -        fdocs_hdocs = [] -        for fdoc, chash in fdocs_chash: -            hdoc = yield self.get_header_by_chash(chash) -            if not hdoc: -                continue -            fdocs_hdocs.append((fdoc, hdoc)) - -        fdocs_hdocs_bodyphash = [(f[0], f[1], f[1].content.get('body')) for f in fdocs_hdocs] -        fdocs_hdocs_bdocs_parts = [] -        for fdoc, hdoc, body_phash in fdocs_hdocs_bodyphash: -            bdoc = yield self.get_content_by_phash(body_phash) -            if not bdoc: -                continue -            parts = yield self._extract_parts(hdoc.content) -            fdocs_hdocs_bdocs_parts.append((fdoc, hdoc, bdoc, parts)) - -        defer.returnValue([PixelatedMail.from_soledad(*raw_mail) for raw_mail in fdocs_hdocs_bdocs_parts]) - -    def mail_exists(self, ident): -        return self.get_flags_by_chash(ident) - -    @defer.inlineCallbacks -    def mail(self, ident): -        fdoc = yield self.get_flags_by_chash(ident) -        hdoc = yield self.get_header_by_chash(ident) -        bdoc = yield self.get_content_by_phash(hdoc.content['body']) -        parts = yield self._extract_parts(hdoc.content) - -        mail = PixelatedMail.from_soledad(fdoc, hdoc, bdoc, parts=parts) -        defer.returnValue(mail) - -    @defer.inlineCallbacks -    def mails(self, idents): -        fdocs_chash = [((yield self.get_flags_by_chash(ident)), ident) for ident in -                       idents] -        fdocs_chash = [(result, ident) for result, ident in fdocs_chash if result] -        defer.returnValue((yield self._build_mails_from_fdocs(fdocs_chash))) - -    @defer.inlineCallbacks -    def attachment(self, attachment_ident, encoding): -        bdoc = yield self.get_content_by_phash(attachment_ident) -        defer.returnValue({'content': self._try_decode(bdoc.content['raw'], encoding), -                           'content-type': bdoc.content['content_type']}) - -    def _try_decode(self, raw, encoding): -        encoding = encoding.lower() -        if encoding == 'base64': -            return base64.decodestring(raw) -        elif encoding == 'quoted-printable': -            return quopri.decodestring(raw) -        else: -            return str(raw) - -    @defer.inlineCallbacks -    def _extract_parts(self, hdoc, parts=None): -        if not parts: -            parts = {'alternatives': [], 'attachments': []} - -        if hdoc['multi']: -            for part_key in hdoc.get('part_map', {}).keys(): -                yield self._extract_parts(hdoc['part_map'][part_key], parts) -        else: -            headers_dict = {elem[0]: elem[1] for elem in hdoc.get('headers', [])} -            if 'attachment' in headers_dict.get('Content-Disposition', ''): -                parts['attachments'].append(self._extract_attachment(hdoc, headers_dict)) -            else: -                parts['alternatives'].append((yield self._extract_alternative(hdoc, headers_dict))) -        defer.returnValue(parts) - -    @defer.inlineCallbacks -    def _extract_alternative(self, hdoc, headers_dict): -        bdoc = yield self.get_content_by_phash(hdoc['phash']) - -        if bdoc is None: -            logger.warning("No BDOC content found for message!!!") -            raw_content = "" -        else: -            raw_content = bdoc.content['raw'] - -        defer.returnValue({'headers': headers_dict, 'content': raw_content}) - -    def _extract_attachment(self, hdoc, headers_dict): -        content_disposition = headers_dict['Content-Disposition'] -        match = re.compile('.*name=\"(.*)\".*').search(content_disposition) -        filename = '' -        if match: -            filename = match.group(1) -        return {'headers': headers_dict, 'ident': hdoc['phash'], 'name': filename} diff --git a/service/pixelated/adapter/soledad/soledad_search_key_masterkey_retrieval_mixin.py b/service/pixelated/adapter/soledad/soledad_search_key_masterkey_retrieval_mixin.py deleted file mode 100644 index 8a912bc2..00000000 --- a/service/pixelated/adapter/soledad/soledad_search_key_masterkey_retrieval_mixin.py +++ /dev/null @@ -1,35 +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 <http://www.gnu.org/licenses/>. -from pixelated.adapter.soledad.soledad_facade_mixin import SoledadDbFacadeMixin -import os -import base64 - - -class SoledadSearchIndexMasterkeyRetrievalMixin(SoledadDbFacadeMixin, object): - -    def get_index_masterkey(self): -        deferred = self.get_search_index_masterkey() -        deferred.addCallback(self._ensure_masterkey_exists) -        return deferred - -    def _ensure_masterkey_exists(self, result): -        index_key_doc = result[0] if result else None - -        if not index_key_doc: -            new_index_key = os.urandom(64)  # 32 for encryption, 32 for hmac -            self.create_doc(dict(type='index_key', value=base64.encodestring(new_index_key))) -            return new_index_key -        return base64.decodestring(index_key_doc.content['value']) diff --git a/service/pixelated/adapter/soledad/soledad_writer_mixin.py b/service/pixelated/adapter/soledad/soledad_writer_mixin.py deleted file mode 100644 index d47e722a..00000000 --- a/service/pixelated/adapter/soledad/soledad_writer_mixin.py +++ /dev/null @@ -1,54 +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 <http://www.gnu.org/licenses/>. -from pixelated.adapter.soledad.soledad_facade_mixin import SoledadDbFacadeMixin - -from twisted.internet import defer - - -class SoledadWriterMixin(SoledadDbFacadeMixin, object): - -    @defer.inlineCallbacks -    def mark_all_as_not_recent(self): -        for mailbox in ['INBOX', 'DRAFTS', 'SENT', 'TRASH']: -            rct = yield self.get_recent_by_mbox(mailbox) -            if not rct or not rct[0].content['rct']: -                return -            rct = rct[0] -            rct.content['rct'] = [] -            yield self.put_doc(rct) - -    def save_mail(self, mail): -        return self.put_doc(mail.fdoc) - -    @defer.inlineCallbacks -    def create_mail(self, mail, mailbox_name): -        mbox_doc = (yield self.get_mbox(mailbox_name))[0] -        uid = 1 + (yield self.get_lastuid(mbox_doc)) - -        yield self.create_docs(mail.get_for_save(next_uid=uid, mailbox=mailbox_name)) - -        # FIXME need to update meta message (mdoc) -        # mbox_doc.content['lastuid'] = uid + 1 -        # self.put_doc(mbox_doc) - -        defer.returnValue((yield self.mail(mail.ident))) - -    @defer.inlineCallbacks -    def remove_mail(self, mail): -        # FIX-ME: Must go through all the part_map phash to delete all the cdocs -        yield self.delete_doc(mail.fdoc) -        yield self.delete_doc(mail.hdoc) -        yield self.delete_doc(mail.bdoc) diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py index f5c50712..0b3e71a2 100644 --- a/service/test/support/integration/app_test_client.py +++ b/service/test/support/integration/app_test_client.py @@ -40,7 +40,6 @@ 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.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 @@ -67,7 +66,6 @@ class AppTestClient(object):          self.soledad = yield 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) @@ -161,11 +159,6 @@ class AppTestClient(object):          defer.returnValue(mails) -    def _create_soledad_querier(self, soledad, index_key): -        soledad_querier = SoledadQuerier(soledad) -        soledad_querier.get_index_masterkey = lambda: index_key -        return soledad_querier -      def _create_mail_sender(self):          mail_sender = Mock()          mail_sender.sendmail.side_effect = lambda mail: succeed(mail) diff --git a/service/test/unit/adapter/test_mail.py b/service/test/unit/adapter/test_mail.py index 0c81bda0..4b0160ac 100644 --- a/service/test/unit/adapter/test_mail.py +++ b/service/test/unit/adapter/test_mail.py @@ -31,9 +31,6 @@ from twisted.internet import defer  class TestPixelatedMail(unittest.TestCase): -    def setUp(self): -        self.querier = mock() -      def tearDown(self):          unstub() diff --git a/service/test/unit/adapter/test_soledad_querier.py b/service/test/unit/adapter/test_soledad_querier.py deleted file mode 100644 index 03d62d58..00000000 --- a/service/test/unit/adapter/test_soledad_querier.py +++ /dev/null @@ -1,178 +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 <http://www.gnu.org/licenses/>. -from twisted.trial import unittest -import json -import base64 -import quopri -from uuid import uuid4 -import pkg_resources - -import pixelated.adapter.soledad.soledad_facade_mixin -from pixelated.adapter.soledad.soledad_querier import SoledadQuerier -from mockito import mock, when, any, unstub -from twisted.internet import defer - - -class SoledadQuerierTest(unittest.TestCase): - -    def tearDown(self): -        unstub() - -    @defer.inlineCallbacks -    def test_extract_parts(self): -        soledad = mock() -        bdoc = mock() -        bdoc.content = {'raw': 'esse papo seu ta qualquer coisa'} -        when(soledad).get_from_index('by-type-and-payloadhash', 'cnt', any(unicode)).thenReturn([bdoc]) -        multipart_attachment_file = pkg_resources.resource_filename('test.unit.fixtures', 'multipart_attachment.json') -        with open(multipart_attachment_file) as f: -            hdoc = json.loads(f.read()) -        querier = SoledadQuerier(soledad) - -        parts = yield querier._extract_parts(hdoc) - -        self.assertIn('alternatives', parts.keys()) -        self.assertIn('attachments', parts.keys()) -        self.assertEquals(2, len(parts['alternatives'])) -        self.assertEquals(1, len(parts['attachments'])) - -        self.check_alternatives(parts) -        self.check_attachments(parts) - -    def check_alternatives(self, parts): -        for alternative in parts['alternatives']: -            self.assertIn('headers', alternative) -            self.assertIn('content', alternative) - -    def check_attachments(self, parts): -        for attachment in parts['attachments']: -            self.assertIn('headers', attachment) -            self.assertIn('ident', attachment) -            self.assertIn('name', attachment) - -    @defer.inlineCallbacks -    def test_extract_part_without_headers(self): -        soledad = mock() -        bdoc = mock() -        bdoc.content = {'raw': 'esse papo seu ta qualquer coisa'} -        when(soledad).get_from_index('by-type-and-payloadhash', 'cnt', any(unicode)).thenReturn([bdoc]) -        hdoc = {'multi': True, 'part_map': {'1': {'multi': False, 'phash': u'0400BEBACAFE'}}} -        querier = SoledadQuerier(soledad) - -        parts = yield querier._extract_parts(hdoc) - -        self.assertEquals(bdoc.content['raw'], parts['alternatives'][0]['content']) - -    @defer.inlineCallbacks -    def test_extract_handles_missing_part_map(self): -        soledad = mock() -        hdoc = {u'multi': True, -                u'ctype': u'message/delivery-status', -                u'headers': [[u'Content-Description', u'Delivery report'], [u'Content-Type', u'message/delivery-status']], -                u'parts': 2, -                u'phash': None, -                u'size': 554} -        querier = SoledadQuerier(soledad) - -        parts = yield querier._extract_parts(hdoc) - -        self.assertEquals(0, len(parts['alternatives'])) -        self.assertEquals(0, len(parts['attachments'])) - -    @defer.inlineCallbacks -    def test_attachment_base64(self): -        soledad = mock() -        bdoc = mock() -        bdoc.content = {'raw': base64.encodestring('esse papo seu ta qualquer coisa'), 'content_type': 'text/plain'} -        when(soledad).get_from_index('by-type-and-payloadhash', 'cnt', any(unicode)).thenReturn([bdoc]) -        querier = SoledadQuerier(soledad) - -        attachment = yield querier.attachment(u'0400BEBACAFE', 'base64') - -        self.assertEquals('esse papo seu ta qualquer coisa', attachment['content']) - -    @defer.inlineCallbacks -    def test_attachment_quoted_printable(self): -        soledad = mock() -        bdoc = mock() -        bdoc.content = {'raw': quopri.encodestring('esse papo seu ta qualquer coisa'), 'content_type': 'text/plain'} -        when(soledad).get_from_index('by-type-and-payloadhash', 'cnt', any(unicode)).thenReturn([bdoc]) -        querier = SoledadQuerier(soledad) - -        attachment = yield querier.attachment(u'0400BEBACAFE', 'quoted-printable') - -        self.assertEquals('esse papo seu ta qualquer coisa', attachment['content']) - -    @defer.inlineCallbacks -    def test_empty_or_null_queries_are_ignored(self): -        soledad = mock() -        when(soledad).get_from_index(any(), any(), any()).thenReturn(['nonempty', 'list']) -        querier = SoledadQuerier(soledad) - -        test_parameters = ['', None] - -        def call_with_bad_parameters(funct): -            deferreds = [] -            for param in test_parameters: -                d = defer.maybeDeferred(funct, param) -                d.addCallback(self.assertFalse) -                deferreds.append(d) -            return defer.DeferredList(deferreds) - -        yield call_with_bad_parameters(querier.get_all_flags_by_mbox) -        yield call_with_bad_parameters(querier.get_content_by_phash) -        yield call_with_bad_parameters(querier.get_flags_by_chash) -        yield call_with_bad_parameters(querier.get_header_by_chash) -        yield call_with_bad_parameters(querier.get_recent_by_mbox) -        yield call_with_bad_parameters(querier.idents_by_mailbox) -        yield call_with_bad_parameters(querier.get_mbox) - -    @defer.inlineCallbacks -    def test_get_lastuid(self): -        soledad = mock() -        mbox = mock() -        indexer = mock() -        mbox.content = {'uuid': str(uuid4())} -        when(soledad).get_from_index('by-type-and-mbox', 'mbox', 'INBOX').thenReturn(defer.succeed([mbox])) -        querier = SoledadQuerier(soledad) - -        when(pixelated.adapter.soledad.soledad_facade_mixin).MailboxIndexer(soledad).thenReturn(indexer) -        when(indexer).create_table(any()).thenReturn(defer.succeed(None)) -        when(indexer).get_last_uid(any()).thenReturn(defer.succeed(42)) - -        last_uid = (yield querier.get_lastuid('INBOX')) - -        self.assertEquals(42, last_uid) - -    @defer.inlineCallbacks -    def test_create_mail(self): -        soledad = mock() -        mbox = mock() -        mail = mock() -        indexer = mock() -        mbox.content = {'uuid': 'some uuid'} -        when(mail).get_for_save(next_uid=any(), mailbox='INBOX').thenReturn([]) -        when(soledad).get_from_index('by-type-and-mbox', 'mbox', 'INBOX').thenReturn(defer.succeed([mbox])) -        querier = SoledadQuerier(soledad) -        when(querier).mail(any()).thenReturn([]) - -        when(pixelated.adapter.soledad.soledad_facade_mixin).MailboxIndexer(soledad).thenReturn(indexer) -        when(indexer).create_table(any()).thenReturn('') -        when(indexer).get_last_uid('some uuid').thenReturn(defer.succeed(42)) - -        mail_result = yield querier.create_mail(mail, 'INBOX') - -        self.assertEquals([], mail_result)  | 
