From 819ec4f0c82a258793987f06fd8e0954d1edbf92 Mon Sep 17 00:00:00 2001 From: Chad Whitacre Date: Tue, 15 Aug 2017 11:23:54 -0400 Subject: [PATCH] Store MessageId for sent email messages --- gratipay/email.py | 14 +++++++++----- gratipay/testing/email.py | 28 ++++++++++++++++------------ sql/branch.sql | 3 ++- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/gratipay/email.py b/gratipay/email.py index 55ee9d443d..356ed18955 100644 --- a/gratipay/email.py +++ b/gratipay/email.py @@ -110,18 +110,20 @@ def flush(self): for rec in messages: try: message = self._prepare_email_message_for_ses(rec) - self._mailer.send_email(**message) + result = self._mailer.send_email(**message) + remote_message_id = result['MessageId'] # let KeyErrors go to Sentry except Exception as exc: - self._store_result(rec.id, repr(exc)) + self._store_result(rec.id, repr(exc), None) raise # we want to see this in Sentry - self._store_result(rec.id, '') + self._store_result(rec.id, '', remote_message_id) nsent += 1 sleep(self.sleep_for) return nsent - def _store_result(self, message_id, result): - self.db.run("UPDATE email_messages SET result=%s WHERE id=%s", (result, message_id)) + def _store_result(self, message_id, result, remote_message_id): + self.db.run("UPDATE email_messages SET result=%s, remote_message_id=%s " + "WHERE id=%s", (result, remote_message_id, message_id)) def _prepare_email_message_for_ses(self, rec): @@ -239,3 +241,5 @@ def send_email(self, **email): p(' ', line) p() p('-'*78) + + return {'MessageId': 'deadbeef'} # simulate a remote message id diff --git a/gratipay/testing/email.py b/gratipay/testing/email.py index bd0bf25c57..807923207b 100644 --- a/gratipay/testing/email.py +++ b/gratipay/testing/email.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals -import mock - from gratipay.testing import Harness @@ -49,21 +47,27 @@ def count_email_messages(self): class SentEmailHarness(_AbstractEmailHarness): - """An email harness that mocks ``_mailer.send_email`` to ``get_last_email`` - post-queue. + """An email harness that patches ``_mailer.send_email`` to ``get_last_email`` + after running through the email queue machinery. """ def setUp(self): _AbstractEmailHarness.setUp(self) - self.mailer_patcher = mock.patch.object(self.app.email_queue._mailer, 'send_email') - self.mailer = self.mailer_patcher.start() - self.addCleanup(self.mailer_patcher.stop) - sleep_patcher = mock.patch('gratipay.application.email.sleep') - sleep_patcher.start() - self.addCleanup(sleep_patcher.stop) + self._messages = [] + + def _send_email(**message): + self._messages.append(message) + return {'MessageId': 'deadbeef'} + + self.__send_email = self.app.email_queue._mailer.send_email + self.app.email_queue._mailer.send_email = _send_email + + def tearDown(self): + self.app.email_queue._mailer.send_email = self.__send_email + _AbstractEmailHarness.tearDown(self) def _get_last_email(self): - return self.mailer.call_args[1] + return self._message[-1] def count_email_messages(self): - return self.mailer.call_count + return len(self._message) diff --git a/sql/branch.sql b/sql/branch.sql index 47d89cad78..32354e28ce 100644 --- a/sql/branch.sql +++ b/sql/branch.sql @@ -1,7 +1,8 @@ BEGIN; ALTER TABLE emails RENAME TO email_addresses; ALTER TABLE email_queue RENAME TO email_messages; - ALTER TABLE email_messages ADD COLUMN result text DEFAULT NULL; + ALTER TABLE email_messages ADD COLUMN result text; + ALTER TABLE email_messages ADD COLUMN remote_message_id text; -- transfer dead to result UPDATE email_messages SET result='unknown failure' WHERE dead;