diff --git a/templates/zerver/email.html b/templates/zerver/email.html
index da4e670196..fca9f3f0fe 100644
--- a/templates/zerver/email.html
+++ b/templates/zerver/email.html
@@ -1,16 +1,12 @@
-{% if failed %}
-
{{template}} failed to render: {{ reason }}
-{% else %}
- From: {{ from_email }}
- To:
- {% for recipient in recipients %}
- {{ recipient }}
- {% endfor %}
-
- Subject: {{subject}}
- {% autoescape off %}
- {{ html_message }}
- {% endautoescape %}
- {{ body }}
-{% endif %}
+From: {{ from_email }}
+To:
+ {% for recipient in recipients %}
+ {{ recipient }}
+ {% endfor %}
+
+Subject: {{subject}}
+{% autoescape off %}
+{{ html_message }}
+{% endautoescape %}
+{{ body }}
diff --git a/zerver/lib/send_email.py b/zerver/lib/send_email.py
index 9c4da4e7c2..e6781af1d3 100644
--- a/zerver/lib/send_email.py
+++ b/zerver/lib/send_email.py
@@ -23,35 +23,6 @@ class FromAddress(object):
SUPPORT = parseaddr(settings.ZULIP_ADMINISTRATOR)[1]
NOREPLY = parseaddr(settings.NOREPLY_EMAIL_ADDRESS)[1]
-def log_email(email, template_prefix):
- # type: (EmailMultiAlternatives, str) -> None
- """Used in development to record sent emails in a nice HTML log"""
- html_message = 'Missing HTML message'
- if len(email.alternatives) > 0:
- html_message = email.alternatives[0][0]
-
- context = {
- 'template': template_prefix + ".html",
- 'subject': email.subject,
- 'from_email': email.from_email,
- 'recipients': email.to,
- 'body': email.body,
- 'html_message': html_message
- }
-
- new_email = loader.render_to_string('zerver/email.html', context)
-
- # Read in the pre-existing log, so that we can add the new entry
- # at the top.
- try:
- with open(settings.EMAIL_CONTENT_LOG_PATH, "r") as f:
- previous_emails = f.read()
- except FileNotFoundError:
- previous_emails = ""
-
- with open(settings.EMAIL_CONTENT_LOG_PATH, "w+") as f:
- f.write(new_email + previous_emails)
-
def build_email(template_prefix, to_user_id=None, to_email=None, from_name=None,
from_address=None, reply_to_email=None, context=None):
# type: (str, Optional[int], Optional[Text], Optional[Text], Optional[Text], Optional[Text], Optional[Dict[str, Any]]) -> EmailMultiAlternatives
@@ -117,9 +88,6 @@ def send_email(template_prefix, to_user_id=None, to_email=None, from_name=None,
template = template_prefix.split("/")[-1]
logger.info("Sending %s email to %s" % (template, mail.to))
- if settings.DEVELOPMENT:
- log_email(mail, template_prefix)
-
if mail.send() == 0:
logger.error("Error sending %s email to %s" % (template, mail.to))
raise EmailNotDeliveredException
@@ -135,13 +103,10 @@ def send_future_email(template_prefix, to_user_id=None, to_email=None, from_name
email_fields = {'template_prefix': template_prefix, 'to_user_id': to_user_id, 'to_email': to_email,
'from_name': from_name, 'from_address': from_address, 'context': context}
- if settings.DEVELOPMENT:
- mail = build_email(template_prefix, to_user_id=to_user_id, to_email=to_email, from_name=from_name,
- from_address=from_address, context=context)
- # Technically, this will be called. But we currently don't
- # run the `manage.py deliver_email` backend job in the
- # development environment.
- log_email(mail, template_prefix)
+ if settings.DEVELOPMENT and not settings.TEST_SUITE:
+ send_email(template_prefix, to_user_id=to_user_id, to_email=to_email, from_name=from_name,
+ from_address=from_address, context=context)
+ # For logging the email
assert (to_user_id is None) ^ (to_email is None)
if to_user_id is not None:
diff --git a/zerver/tests/test_docs.py b/zerver/tests/test_docs.py
index 9795b6e009..bcfeeae1de 100644
--- a/zerver/tests/test_docs.py
+++ b/zerver/tests/test_docs.py
@@ -76,19 +76,19 @@ class DocPageTest(ZulipTestCase):
self._test('/errors/404/', 'Page not found')
self._test('/errors/5xx/', 'Internal server error')
- # For reaching full coverage for clear_emails function
- self._test('/emails/', 'manually generate most of the emails by clicking')
- if os.path.isfile(settings.EMAIL_CONTENT_LOG_PATH):
- os.remove(settings.EMAIL_CONTENT_LOG_PATH)
- result = self.client_get('/emails/clear/')
- self.assertEqual(result.status_code, 302)
- result = self.client_get(result['Location'])
- self.assertIn('manually generate most of the emails by clicking', str(result.content))
+ with self.settings(EMAIL_BACKEND='zproject.backends.EmailLogBackEnd'):
+ # For reaching full coverage for clear_emails function
+ result = self.client_get('/emails/clear/')
+ self.assertEqual(result.status_code, 302)
+ result = self.client_get(result['Location'])
+ self.assertIn('manually generate most of the emails by clicking', str(result.content))
- result = self.client_get('/emails/generate/')
- self.assertEqual(result.status_code, 302)
- self.assertIn('emails', result['Location'])
- self._test('/register/', 'Sign up for Zulip')
+ result = self.client_get('/emails/generate/')
+ self.assertEqual(result.status_code, 302)
+ self.assertIn('emails', result['Location'])
+
+ self._test('/emails/', 'manually generate most of the emails by clicking')
+ self._test('/register/', 'Sign up for Zulip')
result = self.client_get('/integrations/doc-html/nonexistent_integration', follow=True)
self.assertEqual(result.status_code, 404)
diff --git a/zerver/tests/test_signup.py b/zerver/tests/test_signup.py
index 153172df9c..fed5f6ab9a 100644
--- a/zerver/tests/test_signup.py
+++ b/zerver/tests/test_signup.py
@@ -305,7 +305,7 @@ class LoginTest(ZulipTestCase):
with queries_captured() as queries:
self.register(self.nonreg_email('test'), "test")
# Ensure the number of queries we make is not O(streams)
- self.assert_length(queries, 68)
+ self.assert_length(queries, 66)
user_profile = self.nonreg_user('test')
self.assertEqual(get_session_dict_user(self.client.session), user_profile.id)
self.assertFalse(user_profile.enable_stream_desktop_notifications)
diff --git a/zproject/backends.py b/zproject/backends.py
index 5a6f30ed4a..cc00d6b387 100644
--- a/zproject/backends.py
+++ b/zproject/backends.py
@@ -6,6 +6,9 @@ from django.contrib.auth.backends import RemoteUserBackend
from django.conf import settings
from django.http import HttpResponse
import django.contrib.auth
+from django.core.mail.backends.base import BaseEmailBackend
+from django.core.mail import EmailMultiAlternatives
+from django.template import loader
from django_auth_ldap.backend import LDAPBackend, _LDAPUser
from zerver.lib.actions import do_create_user
@@ -575,3 +578,40 @@ AUTH_BACKEND_NAME_MAP = {
u'LDAP': ZulipLDAPAuthBackend,
u'RemoteUser': ZulipRemoteUserBackend,
} # type: Dict[Text, Any]
+
+class EmailLogBackEnd(BaseEmailBackend):
+ def log_email(self, email):
+ # type: (EmailMultiAlternatives) -> None
+ """Used in development to record sent emails in a nice HTML log"""
+ html_message = 'Missing HTML message'
+ if len(email.alternatives) > 0:
+ html_message = email.alternatives[0][0]
+
+ context = {
+ 'subject': email.subject,
+ 'from_email': email.from_email,
+ 'recipients': email.to,
+ 'body': email.body,
+ 'html_message': html_message
+ }
+
+ new_email = loader.render_to_string('zerver/email.html', context)
+
+ # Read in the pre-existing log, so that we can add the new entry
+ # at the top.
+ try:
+ with open(settings.EMAIL_CONTENT_LOG_PATH, "r") as f:
+ previous_emails = f.read()
+ except FileNotFoundError:
+ previous_emails = ""
+
+ with open(settings.EMAIL_CONTENT_LOG_PATH, "w+") as f:
+ f.write(new_email + previous_emails)
+
+ def send_messages(self, email_messages):
+ # type: (List[EmailMultiAlternatives]) -> int
+ for email in email_messages:
+ self.log_email(email)
+ email_log_url = settings.ROOT_DOMAIN_URI + "/emails"
+ print("You can access all the emails sent in development environment by visiting ", email_log_url)
+ return len(email_messages)
diff --git a/zproject/settings.py b/zproject/settings.py
index 798b638b97..1317d6df1e 100644
--- a/zproject/settings.py
+++ b/zproject/settings.py
@@ -1386,7 +1386,7 @@ elif not EMAIL_HOST and PRODUCTION:
EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
elif DEVELOPMENT:
# In the dev environment, emails are printed to the run-dev.py console.
- EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+ EMAIL_BACKEND = 'zproject.backends.EmailLogBackEnd'
else:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'