def __init__(self, soledad_test_folder='/tmp/soledad-test/test'):

        self.soledad = initialize_soledad(tempdir=soledad_test_folder)
        self.mail_address = "*****@*****.**"

        # setup app
        PixelatedMail.from_email_address = self.mail_address

        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.app = App()

        self.soledad_querier = SoledadQuerier(self.soledad)
        self.soledad_querier.get_index_masterkey = lambda: self.INDEX_KEY

        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())

        self.app.resource = RootResource()

        self.app.resource.initialize(self.soledad_querier, self.search_engine,
                                     self.mail_service, self.draft_service)
예제 #2
0
    def setUp(self):
        self.querier = mock()
        self.mailboxes = mock()
        self.tag_service = mock()
        self.mailboxes.drafts = lambda: mock()
        self.mailboxes.trash = lambda: mock()
        self.mailboxes.sent = lambda: mock()

        self.mail_sender = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender,
                                        self.tag_service, self.querier)
예제 #3
0
    def setUp(self):
        self.drafts = mock()
        self.querier = mock()
        self.mailboxes = mock()
        self.mailboxes.drafts = lambda: self.drafts
        self.mailboxes.trash = lambda: mock()
        self.mailboxes.sent = lambda: mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender,
                                        self.querier, self.search_engine)
    def setUp(self):
        self.drafts = mock()
        self.mail_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mail_sender, self.mail_store,
                                        self.search_engine)
def init_app(app, leap_home, leap_session):
    leap_session.start_background_jobs()
    keymanager = leap_session.nicknym.keymanager

    soledad_querier = SoledadQuerier(soledad=leap_session.account._soledad)

    search_engine = SearchEngine(soledad_querier, agent_home=leap_home)
    pixelated_mail_sender = MailSender(
        leap_session.account_email(),
        lambda: leap_session.smtp.ensure_running())

    pixelated_mailboxes = Mailboxes(leap_session.account, soledad_querier,
                                    search_engine)
    draft_service = DraftService(pixelated_mailboxes)
    mail_service = MailService(pixelated_mailboxes, pixelated_mail_sender,
                               soledad_querier, search_engine)

    MailboxIndexerListener.SEARCH_ENGINE = search_engine
    InputMail.FROM_EMAIL_ADDRESS = leap_session.account_email()

    app.resource.initialize(soledad_querier, keymanager, search_engine,
                            mail_service, draft_service)

    register(signal=proto.SOLEDAD_DONE_DATA_SYNC,
             callback=init_index_and_remove_dupes(querier=soledad_querier,
                                                  search_engine=search_engine,
                                                  mail_service=mail_service))

    register(signal=proto.SOLEDAD_DONE_DATA_SYNC,
             uid=CREATE_KEYS_IF_KEYS_DONT_EXISTS_CALLBACK,
             callback=look_for_user_key_and_create_if_cant_find(leap_session))

    reactor.threadpool.adjustPoolsize(20, 40)
    reactor.stop = stop_incoming_mail_fetcher(reactor.stop, leap_session)
    def __init__(self, soledad_test_folder='/tmp/soledad-test/test'):

        self.soledad = initialize_soledad(tempdir=soledad_test_folder)
        self.mail_address = "*****@*****.**"

        # setup app
        PixelatedMail.from_email_address = self.mail_address

        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.app = App()

        self.soledad_querier = SoledadQuerier(self.soledad)
        self.soledad_querier.get_index_masterkey = lambda: self.INDEX_KEY

        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())

        self.app.resource = RootResource()

        self.app.resource.initialize(self.soledad_querier, self.search_engine, self.mail_service, self.draft_service)
예제 #7
0
    def setUp(self):
        self.drafts = mock()
        self.mail_store = mock()
        self.attachment_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mail_sender, self.mail_store,
                                        self.search_engine, 'acount@email',
                                        self.attachment_store)
        self.mail = InputMail.from_dict(duplicates_in_fields_mail_dict(),
                                        from_address='pixelated@org')
예제 #8
0
    def _setup_mail_service(self, search_engine):
        pixelated_mail_sender = MailSender(
            self._leap_session.smtp_config,
            self._leap_session.keymanager.keymanager)

        return MailService(pixelated_mail_sender,
                           self._leap_session.mail_store, search_engine,
                           self._leap_session.account_email(),
                           LeapAttachmentStore(self._leap_session.soledad))
예제 #9
0
 def setup_mail_service(self, leap_session, search_engine):
     # if False:   FIXME
     #    yield pixelated_mailboxes.add_welcome_mail_for_fresh_user()
     pixelated_mail_sender = MailSender(
         leap_session.account_email(),
         leap_session.smtp)
     return MailService(
         pixelated_mail_sender,
         leap_session.mail_store,
         search_engine)
    def setUp(self):
        self.querier = mock()
        self.mailboxes = mock()
        self.tag_service = mock()
        self.mailboxes.drafts = lambda: mock()
        self.mailboxes.trash = lambda: mock()
        self.mailboxes.sent = lambda: mock()

        self.mail_sender = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender, self.tag_service, self.querier)
    def setUp(self):
        self.drafts = mock()
        self.querier = mock()
        self.mailboxes = mock()
        self.mailboxes.drafts = lambda: self.drafts
        self.mailboxes.trash = lambda: mock()
        self.mailboxes.sent = lambda: mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender, self.querier, self.search_engine)
예제 #12
0
 def setup_mail_service(self, leap_session, soledad_querier, search_engine, pixelated_mailboxes):
     if False:   # FIXME
         yield pixelated_mailboxes.add_welcome_mail_for_fresh_user()
     pixelated_mail_sender = MailSender(
         leap_session.account_email(),
         leap_session.smtp)
     defer.returnValue(MailService(
         pixelated_mailboxes,
         pixelated_mail_sender,
         leap_session.mail_store,
         soledad_querier,
         search_engine))
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.querier = mock()
        self.mailboxes = mock()
        self.tag_service = mock()
        self.mailboxes.drafts = lambda: mock()
        self.mailboxes.trash = lambda: mock()
        self.mailboxes.sent = lambda: mock()

        self.mail_sender = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender, self.tag_service, self.querier)

    def test_send_mail(self):
        mail = "mail"

        self.mail_service.send(1, mail)

        verify(self.mail_sender).sendmail(mail)

    def test_mark_as_read(self):
        mail = mock()
        when(self.mail_service).mail(any()).thenReturn(mail)
        self.mail_service.mark_as_read(1)

        verify(mail).mark_as_read()

    def test_delete_mail(self):
        self.mail_service.delete_mail(1)

        verify(self.mailboxes).move_to_trash(1)
예제 #14
0
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.querier = mock()
        self.mailboxes = mock()
        self.tag_service = mock()
        self.mailboxes.drafts = lambda: mock()
        self.mailboxes.trash = lambda: mock()
        self.mailboxes.sent = lambda: mock()

        self.mail_sender = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender,
                                        self.tag_service, self.querier)

    def test_send_mail(self):
        mail = "mail"

        self.mail_service.send(mail)

        verify(self.mail_sender).sendmail(mail)

    def test_mark_as_read(self):
        mail = mock()
        when(self.mail_service).mail(any()).thenReturn(mail)
        self.mail_service.mark_as_read(1)

        verify(mail).mark_as_read()

    def test_delete_mail(self):
        self.mail_service.delete_mail(1)

        verify(self.mailboxes).move_to_trash(1)
    def setUp(self):
        self.drafts = mock()
        self.mail_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mail_sender, self.mail_store, self.search_engine, 'acount@email')
    def setUp(self):
        self.drafts = mock()
        self.mail_store = mock()
        self.attachment_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mail_sender, self.mail_store, self.search_engine, 'acount@email', self.attachment_store)
        self.mail = InputMail.from_dict(duplicates_in_fields_mail_dict(), from_address='pixelated@org')
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.drafts = mock()
        self.mail_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mail_sender, self.mail_store,
                                        self.search_engine)

    def tearDown(self):
        unstub()

    def test_send_mail(self):
        when(InputMail).from_dict(ANY()).thenReturn('inputmail')
        when(self.mail_sender).sendmail(ANY()).thenReturn(defer.Deferred())

        sent_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail("inputmail")

        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    @defer.inlineCallbacks
    def test_send_mail_removes_draft(self):
        mail = LeapMail('id', 'INBOX')
        when(mail).raw = 'raw mail'
        when(InputMail).from_dict(ANY()).thenReturn(mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_store).add_mail('SENT', ANY()).thenReturn(mail)

        deferred_success = defer.succeed(None)
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_success)

        yield self.mail_service.send_mail({'ident': '12'})

        verify(self.mail_sender).sendmail(mail)
        verify(self.mail_store).add_mail('SENT', mail.raw)
        verify(self.mail_store).delete_mail('12')

    @defer.inlineCallbacks
    def test_send_mail_marks_as_read(self):
        mail = LeapMail('id', 'INBOX')
        when(mail).raw = 'raw mail'
        when(InputMail).from_dict(ANY()).thenReturn(mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_sender).sendmail(ANY()).thenReturn(defer.succeed(None))

        sent_mail = LeapMail('id', 'INBOX')
        add_mail_deferral = defer.succeed(sent_mail)
        when(self.mail_store).add_mail('SENT',
                                       ANY()).thenReturn(add_mail_deferral)

        yield self.mail_service.send_mail({'ident': '12'})

        self.assertIn(Status.SEEN, sent_mail.flags)
        verify(self.mail_store).update_mail(sent_mail)

    @defer.inlineCallbacks
    def test_send_mail_does_not_delete_draft_on_error(self):
        when(InputMail).from_dict(ANY()).thenReturn('inputmail')

        deferred_failure = defer.fail(Exception("Assume sending mail failed"))
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_failure)

        try:
            yield self.mail_service.send_mail({'ident': '12'})
            self.fail(
                "send_mail is expected to raise if underlying call fails")
        except:
            verify(self.mail_sender).sendmail("inputmail")
            verifyNoMoreInteractions(self.drafts)

    @defer.inlineCallbacks
    def test_mark_as_read(self):
        mail = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_read(1)

        self.assertIn(Status.SEEN, mail.flags)
        verify(self.mail_store).update_mail(mail)

    @defer.inlineCallbacks
    def test_mark_as_unread(self):
        mail = LeapMail(1, 'INBOX')
        mail.flags.add(Status.SEEN)

        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_unread(1)

        verify(self.mail_store).update_mail(mail)

        self.assertNotEqual(mail.status, Status.SEEN)

    @defer.inlineCallbacks
    def test_delete_mail(self):
        mail_to_delete = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(
            defer.succeed(mail_to_delete))

        yield self.mail_service.delete_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'TRASH')

    @defer.inlineCallbacks
    def test_recover_mail(self):
        mail_to_recover = LeapMail(1, 'TRASH')
        when(self.mail_service).mail(1).thenReturn(mail_to_recover)
        when(self.mail_store).move_mail_to_mailbox(
            1, 'INBOX').thenReturn(mail_to_recover)

        yield self.mail_service.recover_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'INBOX')

    @defer.inlineCallbacks
    def test_get_attachment(self):
        attachment_dict = {
            'content': bytearray('data'),
            'content-type': 'text/plain'
        }
        when(self.mail_store).get_mail_attachment(
            'some attachment id').thenReturn(defer.succeed(attachment_dict))

        attachment = yield self.mail_service.attachment('some attachment id')

        self.assertEqual(attachment_dict, attachment)

    @defer.inlineCallbacks
    def test_update_tags_return_a_set_with_the_current_tags(self):
        mail = LeapMail(1, 'INBOX', tags={'custom_1', 'custom_2'})
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        when(self.search_engine).tags(query='',
                                      skip_default_tags=True).thenReturn([])

        updated_mail = yield self.mail_service.update_tags(
            1, {'custom_1', 'custom_3'})

        verify(self.mail_store).update_mail(mail)
        self.assertEqual({'custom_1', 'custom_3'}, updated_mail.tags)
예제 #18
0
    def setup_mail_service(self, leap_session, search_engine):
        pixelated_mail_sender = MailSender(leap_session.smtp_config,
                                           leap_session.nicknym.keymanager)

        return MailService(pixelated_mail_sender, leap_session.mail_store,
                           search_engine, leap_session.account_email())
 def _create_mail_service(self, mailboxes, mail_sender, soledad_querier,
                          search_engine):
     mail_service = MailService(mailboxes, mail_sender, soledad_querier,
                                search_engine)
     return mail_service
예제 #20
0
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.drafts = mock()
        self.querier = mock()
        self.mail_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender,
                                        self.mail_store, self.querier,
                                        self.search_engine)

    def tearDown(self):
        unstub()

    def test_send_mail(self):
        when(InputMail).from_dict(ANY()).thenReturn('inputmail')
        when(self.mail_sender).sendmail(ANY()).thenReturn(defer.Deferred())

        sent_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail("inputmail")

        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    @defer.inlineCallbacks
    def test_send_mail_removes_draft(self):
        mail = mock()
        when(mail).raw = 'raw mail'
        when(InputMail).from_dict(ANY()).thenReturn(mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_store).add_mail('SENT',
                                       ANY()).thenReturn(defer.succeed(None))

        deferred_success = defer.succeed(None)
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_success)

        yield self.mail_service.send_mail({'ident': '12'})

        verify(self.mail_sender).sendmail(mail)
        verify(self.mail_store).add_mail('SENT', 'raw mail')
        verify(self.mail_store).delete_mail('12')

    @defer.inlineCallbacks
    def test_send_mail_does_not_delete_draft_on_error(self):
        when(InputMail).from_dict(ANY()).thenReturn('inputmail')

        deferred_failure = defer.fail(Exception("Assume sending mail failed"))
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_failure)

        try:
            yield self.mail_service.send_mail({'ident': '12'})
            self.fail(
                "send_mail is expected to raise if underlying call fails")
        except:
            verify(self.mail_sender).sendmail("inputmail")
            verifyNoMoreInteractions(self.drafts)

    @defer.inlineCallbacks
    def test_mark_as_read(self):
        mail = LeapMail('id', 'INBOX')
        when(self.mail_store).get_mail(ANY(),
                                       include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_read(1)

        self.assertIn(Status.SEEN, mail.flags)
        verify(self.mail_store).update_mail(mail)

    @defer.inlineCallbacks
    def test_delete_mail(self):
        mail_to_delete = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(
            defer.succeed(mail_to_delete))

        yield self.mail_service.delete_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'TRASH')

    def test_recover_mail(self):
        mail_to_recover = PixelatedMail.from_soledad(*leap_mail(),
                                                     soledad_querier=None)
        when(self.mail_service).mail(1).thenReturn(mail_to_recover)
        when(self.mailboxes).move_to_inbox(1).thenReturn(mail_to_recover)

        self.mail_service.recover_mail(1)

        verify(self.mailboxes).move_to_inbox(1)
        verify(self.search_engine).index_mail(mail_to_recover)
class AppTestClient:
    INDEX_KEY = '\xde3?\x87\xff\xd9\xd3\x14\xf0\xa7>\x1f%C{\x16.\\\xae\x8c\x13\xa7\xfb\x04\xd4]+\x8d_\xed\xd1\x8d\x0bI' \
                '\x8a\x0e\xa4tm\xab\xbf\xb4\xa5\x99\x00d\xd5w\x9f\x18\xbc\x1d\xd4_W\xd2\xb6\xe8H\x83\x1b\xd8\x9d\xad'

    def __init__(self, soledad_test_folder='/tmp/soledad-test/test'):

        self.soledad = initialize_soledad(tempdir=soledad_test_folder)
        self.mail_address = "*****@*****.**"

        # setup app
        PixelatedMail.from_email_address = self.mail_address

        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.app = App()

        self.soledad_querier = SoledadQuerier(self.soledad)
        self.soledad_querier.get_index_masterkey = lambda: self.INDEX_KEY

        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())

        self.app.resource = RootResource()

        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_str(_str):
            return json.loads(_str) if as_json else _str

        def get_request_written_data(_=None):
            written_data = request.getWrittenData()
            if written_data:
                return get_str(written_data)

        resource = getChildForRequest(self.app.resource, request)
        result = resource.render(request)

        if isinstance(result, basestring):
            return get_str(result), request

        # result is NOT_DONE_YET
        d = succeed(request) if request.finished else request.notifyFinish()
        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 _start():
            reactor.listenTCP(port, Site(self.app.resource), interface=host)
            reactor.run()
        process = multiprocessing.Process(target=_start)
        process.start()
        time.sleep(1)
        return lambda: process.terminate()

    def get(self, path, get_args='', as_json=True):
        request = request_mock(path)
        request.args = get_args
        return self._render(request, as_json)

    def post(self, path, body=''):
        request = request_mock(path=path, method="POST", body=body, headers={'Content-Type': ['application/json']})
        return self._render(request)

    def put(self, path, body):
        request = request_mock(path=path, method="PUT", body=body, headers={'Content-Type': ['application/json']})
        return self._render(request)

    def delete(self, path, body=""):
        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)

    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=[], to='*****@*****.**', cc='*****@*****.**', bcc='*****@*****.**'):
        mails = []
        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)
            mails.append(mail)
            mail.update_tags(input_mail.tags)
            self.search_engine.index_mail(mail)
        return mails
예제 #22
0
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.drafts = mock()
        self.mail_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mail_sender, self.mail_store, self.search_engine, 'acount@email')

    def tearDown(self):
        unstub()

    def test_send_mail(self):
        when(InputMail).from_dict(ANY()).thenReturn('inputmail')
        when(self.mail_sender).sendmail(ANY()).thenReturn(defer.Deferred())

        sent_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail("inputmail")

        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    @defer.inlineCallbacks
    def test_send_mail_removes_draft(self):
        mail = LeapMail('id', 'INBOX')
        when(mail).raw = 'raw mail'
        when(InputMail).from_dict(ANY()).thenReturn(mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_store).add_mail('SENT', ANY()).thenReturn(mail)

        deferred_success = defer.succeed(None)
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_success)

        yield self.mail_service.send_mail({'ident': '12'})

        verify(self.mail_sender).sendmail(mail)
        verify(self.mail_store).add_mail('SENT', mail.raw)
        verify(self.mail_store).delete_mail('12')

    @defer.inlineCallbacks
    def test_send_mail_marks_as_read(self):
        mail = LeapMail('id', 'INBOX')
        when(mail).raw = 'raw mail'
        when(InputMail).from_dict(ANY()).thenReturn(mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_sender).sendmail(ANY()).thenReturn(defer.succeed(None))

        sent_mail = LeapMail('id', 'INBOX')
        add_mail_deferral = defer.succeed(sent_mail)
        when(self.mail_store).add_mail('SENT', ANY()).thenReturn(add_mail_deferral)

        yield self.mail_service.send_mail({'ident': '12'})

        self.assertIn(Status.SEEN, sent_mail.flags)
        verify(self.mail_store).update_mail(sent_mail)

    @defer.inlineCallbacks
    def test_send_mail_does_not_delete_draft_on_error(self):
        when(InputMail).from_dict(ANY()).thenReturn('inputmail')

        deferred_failure = defer.fail(Exception("Assume sending mail failed"))
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_failure)

        try:
            yield self.mail_service.send_mail({'ident': '12'})
            self.fail("send_mail is expected to raise if underlying call fails")
        except:
            verify(self.mail_sender).sendmail("inputmail")
            verifyNoMoreInteractions(self.drafts)

    @defer.inlineCallbacks
    def test_mark_as_read(self):
        mail = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_read(1)

        self.assertIn(Status.SEEN, mail.flags)
        verify(self.mail_store).update_mail(mail)

    @defer.inlineCallbacks
    def test_mark_as_unread(self):
        mail = LeapMail(1, 'INBOX')
        mail.flags.add(Status.SEEN)

        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_unread(1)

        verify(self.mail_store).update_mail(mail)

        self.assertNotEqual(mail.status, Status.SEEN)

    @defer.inlineCallbacks
    def test_delete_mail(self):
        mail_to_delete = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(defer.succeed(mail_to_delete))

        yield self.mail_service.delete_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'TRASH')

    @defer.inlineCallbacks
    def test_recover_mail(self):
        mail_to_recover = LeapMail(1, 'TRASH')
        when(self.mail_service).mail(1).thenReturn(mail_to_recover)
        when(self.mail_store).move_mail_to_mailbox(1, 'INBOX').thenReturn(mail_to_recover)

        yield self.mail_service.recover_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'INBOX')

    @defer.inlineCallbacks
    def test_get_attachment(self):
        attachment_dict = {'content': bytearray('data'), 'content-type': 'text/plain'}
        when(self.mail_store).get_mail_attachment('some attachment id').thenReturn(defer.succeed(attachment_dict))

        attachment = yield self.mail_service.attachment('some attachment id')

        self.assertEqual(attachment_dict, attachment)

    @defer.inlineCallbacks
    def test_update_tags_return_a_set_with_the_current_tags(self):
        mail = LeapMail(1, 'INBOX', tags={'custom_1', 'custom_2'})
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        when(self.search_engine).tags(query='', skip_default_tags=True).thenReturn([])

        updated_mail = yield self.mail_service.update_tags(1, {'custom_1', 'custom_3'})

        verify(self.mail_store).update_mail(mail)
        self.assertEqual({'custom_1', 'custom_3'}, updated_mail.tags)
예제 #23
0
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.drafts = mock()
        self.querier = mock()
        self.mailboxes = mock()
        self.mailboxes.drafts = lambda: self.drafts
        self.mailboxes.trash = lambda: mock()
        self.mailboxes.sent = lambda: mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender,
                                        self.querier, self.search_engine)

    def tearDown(self):
        unstub()

    def test_send_mail(self):
        when(InputMail).from_dict(any()).thenReturn('inputmail')
        when(self.mail_sender).sendmail(any()).thenReturn(Deferred())

        sent_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail("inputmail")

        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    def test_send_mail_removes_draft(self):
        mail_ident = 'Some ident'
        mail = mail_dict()
        mail['ident'] = mail_ident
        when(InputMail).from_dict(any()).thenReturn('inputmail')
        deferred = Deferred()
        when(self.mail_sender).sendmail(any()).thenReturn(deferred)

        sent_deferred = self.mail_service.send_mail(mail)

        verify(self.mail_sender).sendmail("inputmail")

        def assert_removed_from_drafts(_):
            verify(self.drafts).remove(any())

        sent_deferred.addCallback(assert_removed_from_drafts)
        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    def test_send_mail_does_not_delete_draft_on_error(self):
        when(InputMail).from_dict(any()).thenReturn('inputmail')
        when(self.mail_sender).sendmail(any()).thenReturn(Deferred())

        send_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail("inputmail")

        def assert_not_removed_from_drafts(_):
            verifyNoMoreInteractions(self.drafts)

        send_deferred.addErrback(assert_not_removed_from_drafts)

        send_deferred.errback(Exception('Assume sending mail failed'))

        return send_deferred

    def test_mark_as_read(self):
        mail = mock()
        when(self.mail_service).mail(any()).thenReturn(mail)
        self.mail_service.mark_as_read(1)

        verify(mail).mark_as_read()

    def test_delete_mail(self):
        mail_to_delete = PixelatedMail.from_soledad(*leap_mail(),
                                                    soledad_querier=None)
        when(self.mail_service).mail(1).thenReturn(mail_to_delete)

        self.mail_service.delete_mail(1)

        verify(self.mailboxes).move_to_trash(1)

    def test_recover_mail(self):
        mail_to_recover = PixelatedMail.from_soledad(*leap_mail(),
                                                     soledad_querier=None)
        when(self.mail_service).mail(1).thenReturn(mail_to_recover)
        when(self.mailboxes).move_to_inbox(1).thenReturn(mail_to_recover)

        self.mail_service.recover_mail(1)

        verify(self.mailboxes).move_to_inbox(1)
        verify(self.search_engine).index_mail(mail_to_recover)
예제 #24
0
 def _create_mail_service(self, mail_sender, mail_store, search_engine, attachment_store):
     return MailService(mail_sender, mail_store, search_engine, self._mail_address, attachment_store)
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.drafts = mock()
        self.mail_store = mock()
        self.attachment_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mail_sender, self.mail_store, self.search_engine, 'acount@email', self.attachment_store)
        self.mail = InputMail.from_dict(duplicates_in_fields_mail_dict(), from_address='pixelated@org')

    def tearDown(self):
        unstub()

    def test_send_mail(self):
        when(InputMail).from_dict(ANY(), ANY()).thenReturn(self.mail)
        when(self.mail_sender).sendmail(ANY()).thenReturn(defer.Deferred())

        sent_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail(self.mail)

        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    @defer.inlineCallbacks
    def test_send_mail_removes_draft(self):
        mail = LeapMail('id', 'INBOX')
        when(mail).raw = 'raw mail'
        mail._headers['To'] = []
        mail._headers['Cc'] = []
        mail._headers['Bcc'] = []
        when(InputMail).from_dict(ANY(), ANY()).thenReturn(mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_store).add_mail('SENT', ANY()).thenReturn(mail)

        deferred_success = defer.succeed(None)
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_success)

        yield self.mail_service.send_mail({'ident': '12'})

        verify(self.mail_sender).sendmail(mail)
        verify(self.mail_store).add_mail('SENT', mail.raw)
        verify(self.mail_store).delete_mail('12')

    @defer.inlineCallbacks
    def test_send_mail_marks_as_read(self):
        when(self.mail).raw = 'raw mail'
        when(InputMail).from_dict(ANY(), ANY()).thenReturn(self.mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_sender).sendmail(self.mail).thenReturn(defer.succeed(None))

        sent_mail = LeapMail('id', 'INBOX')
        add_mail_deferral = defer.succeed(sent_mail)
        when(self.mail_store).add_mail('SENT', ANY()).thenReturn(add_mail_deferral)

        yield self.mail_service.send_mail({'ident': '12'})

        self.assertIn(Status.SEEN, sent_mail.flags)
        verify(self.mail_store).update_mail(sent_mail)

    @defer.inlineCallbacks
    def test_send_mail_does_not_delete_draft_on_error(self):
        when(InputMail).from_dict(ANY(), ANY()).thenReturn(self.mail)

        deferred_failure = defer.fail(Exception("Assume sending mail failed"))
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_failure)

        try:
            yield self.mail_service.send_mail({'ident': '12'})
            self.fail("send_mail is expected to raise if underlying call fails")
        except:
            verify(self.mail_sender).sendmail(self.mail)
            verifyNoMoreInteractions(self.drafts)

    @defer.inlineCallbacks
    def test_mark_as_read(self):
        mail = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_read(1)

        self.assertIn(Status.SEEN, mail.flags)
        verify(self.mail_store).update_mail(mail)

    @defer.inlineCallbacks
    def test_mark_as_unread(self):
        mail = LeapMail(1, 'INBOX')
        mail.flags.add(Status.SEEN)

        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_unread(1)

        verify(self.mail_store).update_mail(mail)

        self.assertNotEqual(mail.status, Status.SEEN)

    @defer.inlineCallbacks
    def test_delete_mail(self):
        mail_to_delete = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(defer.succeed(mail_to_delete))

        yield self.mail_service.delete_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'TRASH')

    @defer.inlineCallbacks
    def test_delete_mail_does_not_fail_for_invalid_mail(self):
        no_mail = None
        mail_id = 1
        when(self.mail_store).get_mail(mail_id, include_body=True).thenReturn(defer.succeed(no_mail))

        yield self.mail_service.delete_mail(mail_id)

        verify(self.mail_store, never).delete_mail(mail_id)
        verify(self.mail_store, never).move_mail_to_mailbox(mail_id, ANY())

    @defer.inlineCallbacks
    def test_recover_mail(self):
        mail_to_recover = LeapMail(1, 'TRASH')
        when(self.mail_service).mail(1).thenReturn(mail_to_recover)
        when(self.mail_store).move_mail_to_mailbox(1, 'INBOX').thenReturn(mail_to_recover)

        yield self.mail_service.recover_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'INBOX')

    @defer.inlineCallbacks
    def test_get_attachment(self):
        attachment_dict = {'content': bytearray('data'), 'content-type': 'text/plain'}
        when(self.attachment_store).get_mail_attachment('some attachment id').thenReturn(defer.succeed(attachment_dict))

        attachment = yield self.mail_service.attachment('some attachment id')

        self.assertEqual(attachment_dict, attachment)

    @defer.inlineCallbacks
    def test_update_tags_return_a_set_with_the_current_tags(self):
        mail = LeapMail(1, 'INBOX', tags={'custom_1', 'custom_2'})
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        when(self.search_engine).tags(query='', skip_default_tags=True).thenReturn([])

        updated_mail = yield self.mail_service.update_tags(1, {'custom_1', 'custom_3'})

        verify(self.mail_store).update_mail(mail)
        self.assertEqual({'custom_1', 'custom_3'}, updated_mail.tags)

    @defer.inlineCallbacks
    def test_if_recipient_doubled_in_fields_send_only_in_bcc(self):
        mail = InputMail.from_dict(duplicates_in_fields_mail_dict(), from_address='pixelated@org')

        yield self.mail_service._deduplicate_recipients(mail)

        self.assertIn('*****@*****.**', mail.to)
        self.assertNotIn('*****@*****.**', mail.to)
        self.assertIn('*****@*****.**', mail.bcc)

    @defer.inlineCallbacks
    def test_if_recipient_doubled_in_fields_send_only_in_to(self):
        mail = InputMail.from_dict(duplicates_in_fields_mail_dict(), from_address='pixelated@org')

        yield self.mail_service._deduplicate_recipients(mail)

        self.assertIn('*****@*****.**', mail.to)
        self.assertNotIn('*****@*****.**', mail.cc)
        self.assertIn('*****@*****.**', mail.cc)
        self.assertNotIn('*****@*****.**', mail.cc)

    @defer.inlineCallbacks
    def test_if_deduplicates_when_recipient_repeated_in_field(self):
        mail = InputMail.from_dict(duplicates_in_fields_mail_dict(), from_address='pixelated@org')

        yield self.mail_service._deduplicate_recipients(mail)

        self.assertItemsEqual(['*****@*****.**', '*****@*****.**'], mail.bcc)
        self.assertItemsEqual(['*****@*****.**', '*****@*****.**'], mail.to)
        self.assertItemsEqual(['*****@*****.**'], mail.cc)

    def test_remove_canonical_recipient_when_it_is_not_canonical(self):
        recipient = u'*****@*****.**'

        non_canonical = self.mail_service._remove_canonical_recipient(recipient)

        self.assertEqual(recipient, non_canonical)

    def test_remove_canonical_recipient_when_it_is_canonical(self):
        recipient = u'User <*****@*****.**>'

        non_canonical = self.mail_service._remove_canonical_recipient(recipient)

        self.assertEqual(u'*****@*****.**', non_canonical)
class AppTestClient:
    INDEX_KEY = '\xde3?\x87\xff\xd9\xd3\x14\xf0\xa7>\x1f%C{\x16.\\\xae\x8c\x13\xa7\xfb\x04\xd4]+\x8d_\xed\xd1\x8d\x0bI' \
                '\x8a\x0e\xa4tm\xab\xbf\xb4\xa5\x99\x00d\xd5w\x9f\x18\xbc\x1d\xd4_W\xd2\xb6\xe8H\x83\x1b\xd8\x9d\xad'

    def __init__(self, soledad_test_folder='/tmp/soledad-test/test'):

        self.soledad = initialize_soledad(tempdir=soledad_test_folder)
        self.mail_address = "*****@*****.**"

        # setup app
        PixelatedMail.from_email_address = self.mail_address

        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.app = App()

        self.soledad_querier = SoledadQuerier(self.soledad)
        self.soledad_querier.get_index_masterkey = lambda: self.INDEX_KEY

        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())

        self.app.resource = RootResource()

        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_str(_str):
            return json.loads(_str) if as_json else _str

        def get_request_written_data(_=None):
            written_data = request.getWrittenData()
            if written_data:
                return get_str(written_data)

        resource = getChildForRequest(self.app.resource, request)
        result = resource.render(request)

        if isinstance(result, basestring):
            return get_str(result), request

        # result is NOT_DONE_YET
        d = succeed(request) if request.finished else request.notifyFinish()
        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 _start():
            reactor.listenTCP(port, Site(self.app.resource), interface=host)
            reactor.run()

        process = multiprocessing.Process(target=_start)
        process.start()
        time.sleep(1)
        return lambda: process.terminate()

    def get(self, path, get_args='', as_json=True):
        request = request_mock(path)
        request.args = get_args
        return self._render(request, as_json)

    def post(self, path, body=''):
        request = request_mock(path=path,
                               method="POST",
                               body=body,
                               headers={'Content-Type': ['application/json']})
        return self._render(request)

    def put(self, path, body):
        request = request_mock(path=path,
                               method="PUT",
                               body=body,
                               headers={'Content-Type': ['application/json']})
        return self._render(request)

    def delete(self, path, body=""):
        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)

    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=[],
                                to='*****@*****.**',
                                cc='*****@*****.**',
                                bcc='*****@*****.**'):
        mails = []
        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)
            mails.append(mail)
            mail.update_tags(input_mail.tags)
            self.search_engine.index_mail(mail)
        return mails
예제 #27
0
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.drafts = mock()
        self.mail_store = mock()
        self.attachment_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mail_sender, self.mail_store,
                                        self.search_engine, 'acount@email',
                                        self.attachment_store)
        self.mail = InputMail.from_dict(duplicates_in_fields_mail_dict(),
                                        from_address='pixelated@org')

    def tearDown(self):
        unstub()

    def test_send_mail(self):
        when(InputMail).from_dict(ANY(), ANY()).thenReturn(self.mail)
        when(self.mail_sender).sendmail(ANY()).thenReturn(defer.Deferred())

        sent_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail(self.mail)

        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    @defer.inlineCallbacks
    def test_send_mail_removes_draft(self):
        mail = LeapMail('id', 'INBOX')
        when(mail).raw = 'raw mail'
        mail._headers['To'] = []
        mail._headers['Cc'] = []
        mail._headers['Bcc'] = []
        when(InputMail).from_dict(ANY(), ANY()).thenReturn(mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_store).add_mail('SENT', ANY()).thenReturn(mail)

        deferred_success = defer.succeed(None)
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_success)

        yield self.mail_service.send_mail({'ident': '12'})

        verify(self.mail_sender).sendmail(mail)
        verify(self.mail_store).add_mail('SENT', mail.raw)
        verify(self.mail_store).delete_mail('12')

    @defer.inlineCallbacks
    def test_send_mail_marks_as_read(self):
        when(self.mail).raw = 'raw mail'
        when(InputMail).from_dict(ANY(), ANY()).thenReturn(self.mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_sender).sendmail(self.mail).thenReturn(
            defer.succeed(None))

        sent_mail = LeapMail('id', 'INBOX')
        add_mail_deferral = defer.succeed(sent_mail)
        when(self.mail_store).add_mail('SENT',
                                       ANY()).thenReturn(add_mail_deferral)

        yield self.mail_service.send_mail({'ident': '12'})

        self.assertIn(Status.SEEN, sent_mail.flags)
        verify(self.mail_store).update_mail(sent_mail)

    @defer.inlineCallbacks
    def test_send_mail_does_not_delete_draft_on_error(self):
        when(InputMail).from_dict(ANY(), ANY()).thenReturn(self.mail)

        deferred_failure = defer.fail(Exception("Assume sending mail failed"))
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_failure)

        try:
            yield self.mail_service.send_mail({'ident': '12'})
            self.fail(
                "send_mail is expected to raise if underlying call fails")
        except:
            verify(self.mail_sender).sendmail(self.mail)
            verifyNoMoreInteractions(self.drafts)

    @defer.inlineCallbacks
    def test_mark_as_read(self):
        mail = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_read(1)

        self.assertIn(Status.SEEN, mail.flags)
        verify(self.mail_store).update_mail(mail)

    @defer.inlineCallbacks
    def test_mark_as_unread(self):
        mail = LeapMail(1, 'INBOX')
        mail.flags.add(Status.SEEN)

        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_unread(1)

        verify(self.mail_store).update_mail(mail)

        self.assertNotEqual(mail.status, Status.SEEN)

    @defer.inlineCallbacks
    def test_delete_mail(self):
        mail_to_delete = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(
            defer.succeed(mail_to_delete))

        yield self.mail_service.delete_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'TRASH')

    @defer.inlineCallbacks
    def test_delete_mail_does_not_fail_for_invalid_mail(self):
        no_mail = None
        mail_id = 1
        when(self.mail_store).get_mail(mail_id, include_body=True).thenReturn(
            defer.succeed(no_mail))

        yield self.mail_service.delete_mail(mail_id)

        verify(self.mail_store, never).delete_mail(mail_id)
        verify(self.mail_store, never).move_mail_to_mailbox(mail_id, ANY())

    @defer.inlineCallbacks
    def test_recover_mail(self):
        mail_to_recover = LeapMail(1, 'TRASH')
        when(self.mail_service).mail(1).thenReturn(mail_to_recover)
        when(self.mail_store).move_mail_to_mailbox(
            1, 'INBOX').thenReturn(mail_to_recover)

        yield self.mail_service.recover_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'INBOX')

    @defer.inlineCallbacks
    def test_get_attachment(self):
        attachment_dict = {
            'content': bytearray('data'),
            'content-type': 'text/plain'
        }
        when(self.attachment_store).get_mail_attachment(
            'some attachment id').thenReturn(defer.succeed(attachment_dict))

        attachment = yield self.mail_service.attachment('some attachment id')

        self.assertEqual(attachment_dict, attachment)

    @defer.inlineCallbacks
    def test_update_tags_return_a_set_with_the_current_tags(self):
        mail = LeapMail(1, 'INBOX', tags={'custom_1', 'custom_2'})
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(mail)
        when(self.search_engine).tags(query='',
                                      skip_default_tags=True).thenReturn([])

        updated_mail = yield self.mail_service.update_tags(
            1, {'custom_1', 'custom_3'})

        verify(self.mail_store).update_mail(mail)
        self.assertEqual({'custom_1', 'custom_3'}, updated_mail.tags)

    @defer.inlineCallbacks
    def test_if_recipient_doubled_in_fields_send_only_in_bcc(self):
        mail = InputMail.from_dict(duplicates_in_fields_mail_dict(),
                                   from_address='pixelated@org')

        yield self.mail_service._deduplicate_recipients(mail)

        self.assertIn('*****@*****.**', mail.to)
        self.assertNotIn('*****@*****.**', mail.to)
        self.assertIn('*****@*****.**', mail.bcc)

    @defer.inlineCallbacks
    def test_if_recipient_doubled_in_fields_send_only_in_to(self):
        mail = InputMail.from_dict(duplicates_in_fields_mail_dict(),
                                   from_address='pixelated@org')

        yield self.mail_service._deduplicate_recipients(mail)

        self.assertIn('*****@*****.**', mail.to)
        self.assertNotIn('*****@*****.**', mail.cc)
        self.assertIn('*****@*****.**', mail.cc)
        self.assertNotIn('*****@*****.**', mail.cc)

    @defer.inlineCallbacks
    def test_if_deduplicates_when_recipient_repeated_in_field(self):
        mail = InputMail.from_dict(duplicates_in_fields_mail_dict(),
                                   from_address='pixelated@org')

        yield self.mail_service._deduplicate_recipients(mail)

        self.assertItemsEqual(['*****@*****.**', '*****@*****.**'],
                              mail.bcc)
        self.assertItemsEqual(['*****@*****.**', '*****@*****.**'],
                              mail.to)
        self.assertItemsEqual(['*****@*****.**'], mail.cc)

    def test_remove_canonical_recipient_when_it_is_not_canonical(self):
        recipient = u'*****@*****.**'

        non_canonical = self.mail_service._remove_canonical_recipient(
            recipient)

        self.assertEqual(recipient, non_canonical)

    def test_remove_canonical_recipient_when_it_is_canonical(self):
        recipient = u'User <*****@*****.**>'

        non_canonical = self.mail_service._remove_canonical_recipient(
            recipient)

        self.assertEqual(u'*****@*****.**', non_canonical)
예제 #28
0
 def _create_mail_service(self, mail_sender, mail_store, search_engine):
     mail_service = MailService(mail_sender, mail_store, search_engine,
                                self.MAIL_ADDRESS)
     return mail_service
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.drafts = mock()
        self.querier = mock()
        self.mail_store = mock()
        self.mailboxes = mock()

        self.mailboxes.drafts = defer.succeed(self.drafts)

        self.mailboxes.trash = mock()
        self.mailboxes.sent = mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender, self.mail_store, self.querier, self.search_engine)

    def tearDown(self):
        unstub()

    def test_send_mail(self):
        when(InputMail).from_dict(ANY()).thenReturn('inputmail')
        when(self.mail_sender).sendmail(ANY()).thenReturn(defer.Deferred())

        sent_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail("inputmail")

        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    @defer.inlineCallbacks
    def test_send_mail_removes_draft(self):
        mail = mock()
        when(mail).raw = 'raw mail'
        when(InputMail).from_dict(ANY()).thenReturn(mail)
        when(self.mail_store).delete_mail('12').thenReturn(defer.succeed(None))
        when(self.mail_store).add_mail('SENT', ANY()).thenReturn(defer.succeed(None))

        deferred_success = defer.succeed(None)
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_success)

        yield self.mail_service.send_mail({'ident': '12'})

        verify(self.mail_sender).sendmail(mail)
        verify(self.mail_store).add_mail('SENT', 'raw mail')
        verify(self.mail_store).delete_mail('12')

    @defer.inlineCallbacks
    def test_send_mail_does_not_delete_draft_on_error(self):
        when(InputMail).from_dict(ANY()).thenReturn('inputmail')

        deferred_failure = defer.fail(Exception("Assume sending mail failed"))
        when(self.mail_sender).sendmail(ANY()).thenReturn(deferred_failure)

        try:
            yield self.mail_service.send_mail({'ident': '12'})
            self.fail("send_mail is expected to raise if underlying call fails")
        except:
            verify(self.mail_sender).sendmail("inputmail")
            verifyNoMoreInteractions(self.drafts)

    @defer.inlineCallbacks
    def test_mark_as_read(self):
        mail = LeapMail('id', 'INBOX')
        when(self.mail_store).get_mail(ANY(), include_body=True).thenReturn(mail)
        yield self.mail_service.mark_as_read(1)

        self.assertIn(Status.SEEN, mail.flags)
        verify(self.mail_store).update_mail(mail)

    @defer.inlineCallbacks
    def test_delete_mail(self):
        mail_to_delete = LeapMail(1, 'INBOX')
        when(self.mail_store).get_mail(1, include_body=True).thenReturn(defer.succeed(mail_to_delete))

        yield self.mail_service.delete_mail(1)

        verify(self.mail_store).move_mail_to_mailbox(1, 'TRASH')

    def test_recover_mail(self):
        mail_to_recover = PixelatedMail.from_soledad(*leap_mail(), soledad_querier=None)
        when(self.mail_service).mail(1).thenReturn(mail_to_recover)
        when(self.mailboxes).move_to_inbox(1).thenReturn(mail_to_recover)

        self.mail_service.recover_mail(1)

        verify(self.mailboxes).move_to_inbox(1)
        verify(self.search_engine).index_mail(mail_to_recover)
class TestMailService(unittest.TestCase):
    def setUp(self):
        self.drafts = mock()
        self.querier = mock()
        self.mailboxes = mock()
        self.mailboxes.drafts = lambda: self.drafts
        self.mailboxes.trash = lambda: mock()
        self.mailboxes.sent = lambda: mock()

        self.mail_sender = mock()
        self.search_engine = mock()
        self.mail_service = MailService(self.mailboxes, self.mail_sender, self.querier, self.search_engine)

    def tearDown(self):
        unstub()

    def test_send_mail(self):
        when(InputMail).from_dict(any()).thenReturn('inputmail')
        when(self.mail_sender).sendmail(any()).thenReturn(Deferred())

        sent_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail("inputmail")

        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    def test_send_mail_removes_draft(self):
        mail_ident = 'Some ident'
        mail = mail_dict()
        mail['ident'] = mail_ident
        when(InputMail).from_dict(any()).thenReturn('inputmail')
        deferred = Deferred()
        when(self.mail_sender).sendmail(any()).thenReturn(deferred)

        sent_deferred = self.mail_service.send_mail(mail)

        verify(self.mail_sender).sendmail("inputmail")

        def assert_removed_from_drafts(_):
            verify(self.drafts).remove(any())

        sent_deferred.addCallback(assert_removed_from_drafts)
        sent_deferred.callback('Assume sending mail succeeded')

        return sent_deferred

    def test_send_mail_does_not_delete_draft_on_error(self):
        when(InputMail).from_dict(any()).thenReturn('inputmail')
        when(self.mail_sender).sendmail(any()).thenReturn(Deferred())

        send_deferred = self.mail_service.send_mail(mail_dict())

        verify(self.mail_sender).sendmail("inputmail")

        def assert_not_removed_from_drafts(_):
            verifyNoMoreInteractions(self.drafts)

        send_deferred.addErrback(assert_not_removed_from_drafts)

        send_deferred.errback(Exception('Assume sending mail failed'))

        return send_deferred

    def test_mark_as_read(self):
        mail = mock()
        when(self.mail_service).mail(any()).thenReturn(mail)
        self.mail_service.mark_as_read(1)

        verify(mail).mark_as_read()

    def test_delete_mail(self):
        mail_to_delete = PixelatedMail.from_soledad(*leap_mail(), soledad_querier=None)
        when(self.mail_service).mail(1).thenReturn(mail_to_delete)

        self.mail_service.delete_mail(1)

        verify(self.mailboxes).move_to_trash(1)

    def test_recover_mail(self):
        mail_to_recover = PixelatedMail.from_soledad(*leap_mail(), soledad_querier=None)
        when(self.mail_service).mail(1).thenReturn(mail_to_recover)
        when(self.mailboxes).move_to_inbox(1).thenReturn(mail_to_recover)

        self.mail_service.recover_mail(1)

        verify(self.mailboxes).move_to_inbox(1)
        verify(self.search_engine).index_mail(mail_to_recover)