diff options
-rw-r--r-- | mediagoblin/tests/test_util.py | 41 | ||||
-rw-r--r-- | mediagoblin/util.py | 97 |
2 files changed, 138 insertions, 0 deletions
diff --git a/mediagoblin/tests/test_util.py b/mediagoblin/tests/test_util.py index 0e7a2967..5bc31fd6 100644 --- a/mediagoblin/tests/test_util.py +++ b/mediagoblin/tests/test_util.py @@ -14,9 +14,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import email + from mediagoblin import util +util._activate_testing() + + def _import_component_testing_method(silly_string): # Just for the sake of testing that our component importer works. return u"'%s' is the silliest string I've ever seen" % silly_string @@ -28,3 +33,39 @@ def test_import_component(): result = imported_func('hooobaladoobala') expected = u"'hooobaladoobala' is the silliest string I've ever seen" assert result == expected + + +def test_send_email(): + util._clear_test_inboxes() + + # send the email + util.send_email( + "sender@mediagoblin.example.org", + ["amanda@example.org", "akila@example.org"], + "Testing is so much fun!", + """HAYYY GUYS! + +I hope you like unit tests JUST AS MUCH AS I DO!""") + + # check the main inbox + assert len(util.EMAIL_TEST_INBOX) == 1 + message = util.EMAIL_TEST_INBOX.pop() + assert message['From'] == "sender@mediagoblin.example.org" + assert message['To'] == "amanda@example.org, akila@example.org" + assert message['Subject'] == "Testing is so much fun!" + assert message.get_payload(decode=True) == """HAYYY GUYS! + +I hope you like unit tests JUST AS MUCH AS I DO!""" + + # Check everything that the FakeMhost.sendmail() method got is correct + assert len(util.EMAIL_TEST_MBOX_INBOX) == 1 + mbox_dict = util.EMAIL_TEST_MBOX_INBOX.pop() + assert mbox_dict['from'] == "sender@mediagoblin.example.org" + assert mbox_dict['to'] == ["amanda@example.org", "akila@example.org"] + mbox_message = email.message_from_string(mbox_dict['message']) + assert mbox_message['From'] == "sender@mediagoblin.example.org" + assert mbox_message['To'] == "amanda@example.org, akila@example.org" + assert mbox_message['Subject'] == "Testing is so much fun!" + assert mbox_message.get_payload(decode=True) == """HAYYY GUYS! + +I hope you like unit tests JUST AS MUCH AS I DO!""" diff --git a/mediagoblin/util.py b/mediagoblin/util.py index c9c57dfc..d24b59b6 100644 --- a/mediagoblin/util.py +++ b/mediagoblin/util.py @@ -14,11 +14,23 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +from email.MIMEText import MIMEText +import smtplib import sys import jinja2 import mongokit + +TESTS_ENABLED = False +def _activate_testing(): + """ + Call this to activate testing in util.py + """ + global TESTS_ENABLED + TESTS_ENABLED = True + + def get_jinja_env(user_template_path=None): """ Set up the Jinja environment, possibly allowing for user @@ -72,3 +84,88 @@ def import_component(import_string): module = sys.modules[module_name] func = getattr(module, func_name) return func + + +### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +### Special email test stuff begins HERE +### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# We have two "test inboxes" here: +# +# EMAIL_TEST_INBOX: +# ---------------- +# If you're writing test views, you'll probably want to check this. +# It contains a list of MIMEText messages. +# +# EMAIL_TEST_MBOX_INBOX: +# ---------------------- +# This collects the messages from the FakeMhost inbox. It's reslly +# just here for testing the send_email method itself. +# +# Anyway this contains: +# - from +# - to: a list of email recipient addresses +# - message: not just the body, but the whole message, including +# headers, etc. +# +# ***IMPORTANT!*** +# ---------------- +# Before running tests that call functions which send email, you should +# always call _clear_test_inboxes() to "wipe" the inboxes clean. + +EMAIL_TEST_INBOX = [] +EMAIL_TEST_MBOX_INBOX = [] + + +class FakeMhost(object): + """ + Just a fake mail host so we can capture and test messages + from send_email + """ + def connect(self): + pass + + def sendmail(self, from_addr, to_addrs, message): + EMAIL_TEST_MBOX_INBOX.append( + {'from': from_addr, + 'to': to_addrs, + 'message': message}) + +def _clear_test_inboxes(): + global EMAIL_TEST_INBOX + global EMAIL_TEST_MBOX_INBOX + EMAIL_TEST_INBOX = [] + EMAIL_TEST_MBOX_INBOX = [] + +### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +### </Special email test stuff> +### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def send_email(from_addr, to_addrs, subject, message_body): + """ + Simple email sending wrapper, use this so we can capture messages + for unit testing purposes. + + Args: + - from_addr: address you're sending the email from + - to_addrs: list of recipient email addresses + - subject: subject of the email + - message_body: email body text + """ + # TODO: make a mock mhost if testing is enabled + if TESTS_ENABLED: + mhost = FakeMhost() + else: + mhost = smtplib.SMTP() + + mhost.connect() + + message = MIMEText(message_body.encode('utf-8'), 'plain', 'utf-8') + message['Subject'] = subject + message['From'] = from_addr + message['To'] = ', '.join(to_addrs) + + if TESTS_ENABLED: + EMAIL_TEST_INBOX.append(message) + + return mhost.sendmail(from_addr, to_addrs, message.as_string()) |