live tests continuing, triggering callbacks

This commit is contained in:
Mathieu Agopian
2013-03-19 17:21:59 +01:00
parent 34e8906bcc
commit 3069d6ac0b
4 changed files with 88 additions and 11 deletions

View File

@@ -2,8 +2,9 @@
from email import message_from_string
from imapclient import FLAGGED
from os.path import dirname, join
from .. import register, MailBot
from .. import register, MailBot, Callback
from ..tests import MailBotTestCase
try:
@@ -75,3 +76,81 @@ class MailReceivedTest(MailBotTestCase):
ids = self.mb.client.search(['UNFLAGGED'])
self.assertEqual(ids, [])
def test_process_messages(self):
# real mail
email_file = join(dirname(dirname(__file__)),
'tests', 'mails', 'mail_with_attachment.txt')
email = open(email_file, 'r').read()
self.mb.client.append(self.home_folder, email)
class MatchingCallback(Callback):
"""Callback with each rule matching the test mail.
Each rule contains a non matching regexp, which shouldn't prevent
the callback from being triggered
"""
rules = {
'subject': [r'Task name \w+', r'Task name (\w+)', 'NOMATCH'],
'to': [r'\w+\+\w+@gmail.com', r'(\w+)\+(\w+)@gmail.com',
'NOMATCH'],
'from': [r'\w+\.\w+@gmail.com', r'(\w+)\.(\w+)@gmail.com',
'NOMATCH'],
'body': [r'Mail content \w+', r'Mail content (\w+)',
'NOMATCH']}
def check_rules(self):
res = super(MatchingCallback, self).check_rules()
assert res, "Matching callback check_rules returned False"
return res
def trigger(self):
m = self.matches['subject']
assert len(m) == 3
assert m[0].group(0) == 'Task name here'
assert m[1].group(1) == 'here'
assert m[2] is None
m = self.matches['to']
assert len(m) == 3
assert m[0].group(0) == 'testmagopian+RANDOM_KEY@gmail.com'
assert m[1].group(1) == 'testmagopian'
assert m[1].group(2) == 'RANDOM_KEY'
assert m[2] is None
m = self.matches['from']
assert len(m) == 3
assert m[0].group(0) == 'mathieu.agopian@gmail.com'
assert m[1].group(1) == 'mathieu'
assert m[1].group(2) == 'agopian'
assert m[2] is None
m = self.matches['body']
assert len(m) == 3
assert m[0].group(0) == 'Mail content here'
assert m[1].group(1) == 'here'
assert m[2] is None
class NonMatchingCallback(Callback):
"""Callback with each rule but one matching the test mail.
To prevent the callback from being triggered, at least one rule
must completely fail (have 0 regexp that matches).
"""
rules = { # only difference is that one rule doesn't match
'subject': [r'Task name \w+', r'Task name (\w+)', 'NOMATCH'],
'to': [r'\w+\+\w+@gmail.com', r'(\w+)\+(\w+)@gmail.com',
'NOMATCH'],
'from': [r'\w+\.\w+@gmail.com', r'(\w+)\.(\w+)@gmail.com',
'NOMATCH'],
'body': ['NOMATCH', 'DOESNT MATCH EITHER']}
def trigger(self):
assert False, "Non matching callback has been triggered"
register(MatchingCallback)
register(NonMatchingCallback)
self.mb.process_messages()

View File

@@ -15,7 +15,6 @@ class MailBot(object):
"""
home_folder = 'INBOX'
imapclient = IMAPClient
message_constructor = message_from_string # easier for testing
def __init__(self, host, username, password, port=None, use_uid=True,
ssl=False, stream=False):
@@ -45,7 +44,7 @@ class MailBot(object):
messages = self.get_messages()
for uid, msg in messages.items():
message = self.message_constructor(msg['RFC822'])
message = message_from_string(msg['RFC822'])
for callback_class, rules in CALLBACKS_MAP.items():
self.process_message(message, callback_class, rules)
self.mark_processed(uid)

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from email import message_from_file, message_from_string
from os import path
from os.path import dirname, join
from re import search
from mock import Mock
@@ -51,8 +51,7 @@ class CallbackTest(MailBotTestCase):
self.assertEqual(callback.check_item('foobar', ['(.*)']), None)
# test on real mail
email_file = path.join(path.dirname(__file__),
'mails/mail_with_attachment.txt')
email_file = join(dirname(__file__), 'mails/mail_with_attachment.txt')
email = message_from_file(open(email_file, 'r'))
callback = Callback(email, {})
@@ -89,8 +88,7 @@ class CallbackTest(MailBotTestCase):
self.assertEqual(callback.get_email_body(empty_message), '')
# real email
email_file = path.join(path.dirname(__file__),
'mails/mail_with_attachment.txt')
email_file = join(dirname(__file__), 'mails/mail_with_attachment.txt')
email = message_from_file(open(email_file, 'r'))
self.assertEqual(callback.get_email_body(email), 'Mail content here\n')

View File

@@ -81,13 +81,14 @@ class MailBotTest(MailBotClientTest):
callback.check_rules.assert_called_once_with()
self.assertEqual(res, None)
def test_process_messages(self):
@patch('mailbot.mailbot.message_from_string')
def test_process_messages(self, message_from_string):
messages = {1: {'RFC822': sentinel.mail1},
2: {'RFC822': sentinel.mail2}}
self.bot.get_messages = Mock(return_value=messages)
# message constructor will return exactly what it's given
# mock of email.message_from_string will return exactly what it's given
# to be used in the "self.bot.process_message.assert_has_calls" below
self.bot.message_constructor = Mock(side_effect=lambda m: m)
message_from_string.side_effect = lambda m: m
self.bot.process_message = Mock()
self.bot.mark_processed = Mock()
CALLBACKS_MAP.update({sentinel.callback1: sentinel.rules1,