live tests continuing, triggering callbacks
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user