Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dax/jmc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Rousselie <dax@happycoders.org>2007-06-18 21:58:13 +0400
committerDavid Rousselie <dax@happycoders.org>2007-06-18 21:58:13 +0400
commit86a1367f26dd347b6afc197725679f1b10e561ac (patch)
tree869615c02dbd531d649538e05c858b014f26f07c /src
parentd6b91f8d02195fee85499bb09870ebabd47a8b42 (diff)
SMTP send_email real implementation
darcs-hash:20070618175813-86b55-990d6242426508e186abfc454d69fc9e0cd424b0.gz
Diffstat (limited to 'src')
-rw-r--r--src/jmc/jabber/component.py17
-rw-r--r--src/jmc/jabber/tests/component.py38
-rw-r--r--src/jmc/model/account.py118
-rw-r--r--src/jmc/model/tests/account.py202
-rw-r--r--src/jmc/model/tests/server.py18
5 files changed, 314 insertions, 79 deletions
diff --git a/src/jmc/jabber/component.py b/src/jmc/jabber/component.py
index 1164cbd..71ec10c 100644
--- a/src/jmc/jabber/component.py
+++ b/src/jmc/jabber/component.py
@@ -243,9 +243,11 @@ class SendMailMessageHandler(MailHandler):
def handle(self, message, lang_class, accounts):
to_node = message.get_to().node
to_email = to_node.replace('%', '@', 1)
- accounts[0].send_email(to_email,
- message.get_subject(),
- message.get_body())
+ accounts[0].send_email(\
+ accounts[0].create_email(accounts[0].default_from,
+ to_email,
+ message.get_subject(),
+ message.get_body()))
return self.send_mail_result(message, lang_class, to_email)
class RootSendMailMessageHandler(SendMailMessageHandler):
@@ -253,7 +255,7 @@ class RootSendMailMessageHandler(SendMailMessageHandler):
def __init__(self):
SendMailMessageHandler.__init__(self)
- self.to_regexp = re.compile("^\s*(to|TO)\s*:\s*(?P<to_email>.*)")
+ self.to_regexp = re.compile("^\s*(to|TO|To)\s*:\s*(?P<to_email>.*)")
self.__logger = logging.getLogger(\
"jmc.jabber.component.RootSendMailMessageHandler")
@@ -285,8 +287,11 @@ class RootSendMailMessageHandler(SendMailMessageHandler):
message_body.append(line)
message_body.extend(lines)
if to_email is not None:
- accounts[0].send_email(to_email, message.get_subject(),
- "\n".join(message_body))
+ accounts[0].send_email(\
+ accounts[0].create_email(accounts[0].default_from,
+ to_email,
+ message.get_subject(),
+ "\n".join(message_body)))
return self.send_mail_result(message, lang_class, to_email)
else:
return [Message(from_jid=message.get_to(),
diff --git a/src/jmc/jabber/tests/component.py b/src/jmc/jabber/tests/component.py
index 9cf85c6..8004fa4 100644
--- a/src/jmc/jabber/tests/component.py
+++ b/src/jmc/jabber/tests/component.py
@@ -142,6 +142,16 @@ class MockPOP3Account(MockMailAccount, POP3Account):
IMAPAccount._init(self, *args, **kw)
MockMailAccount._init(self)
+class MockSMTPAccount(object):
+ def __init__(self):
+ self.default_from = "user1@test.com"
+
+ def create_email(self, from_email, to_email, subject, body):
+ return (from_email, to_email, subject, body)
+
+ def send_email(self, email):
+ self.email = email
+
class MailComponent_TestCase(unittest.TestCase):
def setUp(self):
if os.path.exists(DB_PATH):
@@ -525,16 +535,11 @@ class SendMailMessageHandler_TestCase(unittest.TestCase):
to_jid="user%test.com@jcl.test.com",
subject="message subject",
body="message body")
- class MockSMTPAccount(object):
- def send_email(self, to_email, subject, body):
- self.to_email = to_email
- self.subject = subject
- self.body = body
accounts = [MockSMTPAccount()]
result = self.handler.handle(message, Lang.en, accounts)
- self.assertEquals(accounts[0].to_email, "user@test.com")
- self.assertEquals(accounts[0].subject, "message subject")
- self.assertEquals(accounts[0].body, "message body")
+ self.assertEquals(accounts[0].email[1], "user@test.com")
+ self.assertEquals(accounts[0].email[2], "message subject")
+ self.assertEquals(accounts[0].email[3], "message body")
self.assertEquals(len(result), 1)
self.assertEquals(result[0].stanza_type, "message")
self.assertEquals(result[0].get_from(), "user%test.com@jcl.test.com")
@@ -632,16 +637,12 @@ class RootSendMailMessageHandler_TestCase(unittest.TestCase):
subject="message subject",
body="to: user@test.com\n" \
"message body\nother line")
- class MockSMTPAccount(object):
- def send_email(self, to_email, subject, body):
- self.to_email = to_email
- self.subject = subject
- self.body = body
accounts = [MockSMTPAccount()]
result = self.handler.handle(message, Lang.en, accounts)
- self.assertEquals(accounts[0].to_email, "user@test.com")
- self.assertEquals(accounts[0].subject, "message subject")
- self.assertEquals(accounts[0].body, "message body\nother line")
+ self.assertEquals(accounts[0].email[1], "user@test.com")
+ self.assertEquals(accounts[0].email[2], "message subject")
+ self.assertEquals(accounts[0].email[3],
+ "message body\nother line")
self.assertEquals(len(result), 1)
self.assertEquals(result[0].get_type(), None)
self.assertEquals(result[0].get_from(), "jcl.test.com")
@@ -656,11 +657,6 @@ class RootSendMailMessageHandler_TestCase(unittest.TestCase):
to_jid="jcl.test.com",
subject="message subject",
body="message body")
- class MockSMTPAccount(object):
- def send_email(self, to_email, subject, body):
- self.to_email = to_email
- self.subject = subject
- self.body = body
accounts = [MockSMTPAccount()]
result = self.handler.handle(message, Lang.en, accounts)
self.assertEquals(len(result), 1)
diff --git a/src/jmc/model/account.py b/src/jmc/model/account.py
index 250018d..9edae05 100644
--- a/src/jmc/model/account.py
+++ b/src/jmc/model/account.py
@@ -4,18 +4,18 @@
## Login : <dax@happycoders.org>
## Started on Fri Jan 19 18:21:44 2007 David Rousselie
## $Id$
-##
+##
## Copyright (C) 2007 David Rousselie
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
-##
+##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
-##
+##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -24,12 +24,15 @@
import sys
import logging
import email
-import email.Header
+from email.Header import Header
+from email.MIMEText import MIMEText
+from email.MIMEMultipart import MIMEMultipart
import traceback
import poplib
import imaplib
import socket
+import smtplib
from sqlobject.inheritance import InheritableSQLObject
from sqlobject.col import StringCol, IntCol, BoolCol
@@ -80,9 +83,9 @@ class MYPOP3(poplib.POP3):
self.port = port
msg = "getaddrinfo returns an empty list"
self.sock = None
- for res in socket.getaddrinfo(self.host,
- self.port,
- 0,
+ for res in socket.getaddrinfo(self.host,
+ self.port,
+ 0,
socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
@@ -103,7 +106,7 @@ class MYPOP3(poplib.POP3):
self.welcome = self._getresp()
class MYPOP3_SSL(poplib.POP3_SSL):
- def __init__(self, host, port=poplib.POP3_SSL_PORT, keyfile=None,
+ def __init__(self, host, port=poplib.POP3_SSL_PORT, keyfile=None,
certfile=None):
self.host = host
self.port = port
@@ -112,7 +115,7 @@ class MYPOP3_SSL(poplib.POP3_SSL):
self.buffer = ""
msg = "getaddrinfo returns an empty list"
self.sock = None
- for res in socket.getaddrinfo(self.host, self.port, 0,
+ for res in socket.getaddrinfo(self.host, self.port, 0,
socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
@@ -154,11 +157,11 @@ class MailAccount(PresenceAccount):
interval = IntCol(default=5)
store_password = BoolCol(default=True)
live_email_only = BoolCol(default=False)
-
+
lastcheck = IntCol(default=0)
waiting_password_reply = BoolCol(default=False)
first_check = BoolCol(default=True)
-
+
def _init(self, *args, **kw):
"""MailAccount init
Initialize class attributes"""
@@ -167,7 +170,7 @@ class MailAccount(PresenceAccount):
self.connection = None
self.connected = False
self.default_lang_class = Lang.en
-
+
def _get_register_fields(cls, real_class=None):
"""See Account._get_register_fields
"""
@@ -204,13 +207,13 @@ class MailAccount(PresenceAccount):
("interval", "text-single", None,
account.int_post_func,
lambda bare_from_jid: 5)]
-
+
get_register_fields = classmethod(_get_register_fields)
def _get_default_port(cls):
return 42
get_default_port = classmethod(_get_default_port)
-
+
def _get_presence_actions_fields(cls):
"""See PresenceAccount._get_presence_actions_fields
"""
@@ -226,7 +229,7 @@ class MailAccount(PresenceAccount):
MailAccount.DIGEST),
'offline_action': (cls.possibles_actions,
PresenceAccount.DO_NOTHING)}
-
+
get_presence_actions_fields = classmethod(_get_presence_actions_fields)
def get_decoded_part(self, part, charset_hint):
@@ -255,7 +258,7 @@ class MailAccount(PresenceAccount):
(type, value, stack, 5))
return result
-
+
def format_message(self, email_msg, include_body = True):
from_decoded = email.Header.decode_header(email_msg["From"])
charset_hint = None
@@ -312,7 +315,7 @@ class MailAccount(PresenceAccount):
print >>sys.stderr, \
"".join(traceback.format_exception
(type, value, stack, 5))
-
+
result += u"\n\n"
if include_body:
@@ -329,7 +332,7 @@ class MailAccount(PresenceAccount):
def format_message_summary(self, email_msg):
return self.format_message(email_msg, False)
-
+
def get_status_msg(self):
return self.get_type() + "://" + self.login + "@" + self.host + ":" + \
unicode(self.port)
@@ -371,13 +374,13 @@ class IMAPAccount(MailAccount):
[("mailbox", "text-single", None,
account.default_post_func,
lambda bare_from_jid: "INBOX")]
-
+
get_register_fields = classmethod(_get_register_fields)
def _get_default_port(cls):
"""Return default IMAP server port"""
return 143
-
+
get_default_port = classmethod(_get_default_port)
def _init(self, *args, **kw):
@@ -388,7 +391,7 @@ class IMAPAccount(MailAccount):
if self.ssl:
return "imaps"
return "imap"
-
+
def get_status(self):
return MailAccount.get_status(self) + "/" + self.mailbox
@@ -426,7 +429,7 @@ class IMAPAccount(MailAccount):
return self.format_message(\
email.message_from_string(data[0][1]))
return u"Error while fetching mail " + str(index)
-
+
def get_mail_summary(self, index):
self.__logger.debug("Getting mail summary " + str(index))
typ, data = self.connection.select(self.mailbox, True)
@@ -444,13 +447,13 @@ class IMAPAccount(MailAccount):
def mark_all_as_read(self):
self.get_mail_list()
-
+
type = property(get_type)
class POP3Account(MailAccount):
nb_mail = IntCol(default=0)
lastmail = IntCol(default=0)
-
+
def _init(self, *args, **kw):
MailAccount._init(self, *args, **kw)
self.__logger = logging.getLogger("jmc.model.account.POP3Account")
@@ -458,7 +461,7 @@ class POP3Account(MailAccount):
def _get_default_port(cls):
"""Return default POP3 server port"""
return 110
-
+
get_default_port = classmethod(_get_default_port)
def get_type(self):
@@ -470,7 +473,7 @@ class POP3Account(MailAccount):
def connect(self):
self.__logger.debug("Connecting to POP3 server "
- + self.login + "@" + self.host + ":" +
+ + self.login + "@" + self.host + ":" +
str(self.port) + ". SSL=" + str(self.ssl))
if self.ssl:
self.connection = MYPOP3_SSL(self.host, self.port)
@@ -482,7 +485,7 @@ class POP3Account(MailAccount):
self.connection.user(self.login)
self.connection.pass_(self.password)
self.connected = True
-
+
def disconnect(self):
self.__logger.debug("Disconnecting from POP3 server "
@@ -493,7 +496,7 @@ class POP3Account(MailAccount):
def get_mail_list(self):
self.__logger.debug("Getting mail list")
count, size = self.connection.stat()
- self.nb_mail = count
+ self.nb_mail = count
return [str(i) for i in range(1, count + 1)]
def get_mail(self, index):
@@ -535,7 +538,7 @@ class POP3Account(MailAccount):
def mark_all_as_read(self):
self.get_mail_list()
self.lastmail = self.nb_mail
-
+
class SMTPAccount(Account):
"""Send email account"""
@@ -559,7 +562,7 @@ class SMTPAccount(Account):
def _get_default_port(cls):
"""Return default SMTP server port"""
return 25
-
+
get_default_port = classmethod(_get_default_port)
def _get_register_fields(cls, real_class=None):
@@ -628,12 +631,55 @@ class SMTPAccount(Account):
("default_account", "boolean", None,
default_account_post_func,
default_account_default_func)]
-
+
get_register_fields = classmethod(_get_register_fields)
- def send_email(self, to_email, subject, body):
+ def create_email(self, from_email, to_email, subject, body):
+ """Create new email"""
+ email = MIMEText(body)
+ email['Subject'] = Header(str(subject))
+ email['From'] = Header(str(from_email))
+ email['To'] = Header(str(to_email))
+ return email
+
+ def __say_hello(self, connection):
+ if not (200 <= connection.ehlo()[0] <= 299):
+ (code, resp) = connection.helo()
+ if not (200 <= code <= 299):
+ raise SMTPHeloError(code, resp)
+
+ def send_email(self, email):
+ """Send email according to current account parameters"""
self.__logger.debug("Sending email:\n"
- "From: " + self.default_from + "\n" +
- "To: " + to_email + "\n" +
- "Subject: " + subject + "\n\n" +
- body)
+ + str(email))
+ smtp_connection = smtplib.SMTP()
+ if self.__logger.getEffectiveLevel() == logging.DEBUG:
+ smtp_connection.set_debuglevel(1)
+ smtp_connection.connect(self.host, self.port)
+ self.__say_hello(smtp_connection)
+ if self.tls:
+ smtp_connection.starttls()
+ self.__say_hello(smtp_connection)
+ if self.login is not None and len(self.login) > 0:
+ auth_methods = smtp_connection.esmtp_features["auth"].split()
+ auth_methods.reverse()
+ current_error = None
+ for auth_method in auth_methods:
+ self.__logger.debug("Trying to authenticate using "
+ + auth_method + " method")
+ smtp_connection.esmtp_features["auth"] = auth_method
+ try:
+ smtp_connection.login(self.login, self.password)
+ current_error = None
+ self.__logger.debug("Successfuly to authenticate using "
+ + auth_method + " method")
+ break
+ except smtplib.SMTPAuthenticationError, error:
+ self.__logger.debug("Failed to authenticate using "
+ + auth_method + " method")
+ current_error = error
+ if current_error is not None:
+ raise current_error
+ smtp_connection.sendmail(str(email['From']), str(email['To']),
+ email.as_string())
+ smtp_connection.quit()
diff --git a/src/jmc/model/tests/account.py b/src/jmc/model/tests/account.py
index c9d205f..e5a1e15 100644
--- a/src/jmc/model/tests/account.py
+++ b/src/jmc/model/tests/account.py
@@ -4,18 +4,18 @@
## Login : <dax@happycoders.org>
## Started on Wed Feb 14 08:23:17 2007 David Rousselie
## $Id$
-##
+##
## Copyright (C) 2007 David Rousselie
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
-##
+##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
-##
+##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -168,7 +168,7 @@ class POP3Account_TestCase(InheritableAccount_TestCase):
self.pop3_account.ssl = False
del account.hub.threadConnection
self.account_class = POP3Account
-
+
def tearDown(self):
account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url)
POP3Account.dropTable(ifExists = True)
@@ -210,7 +210,7 @@ class POP3Account_TestCase(InheritableAccount_TestCase):
return inner
test_connection = make_test()
-
+
test_get_mail_list = \
make_test(["+OK 2 20\r\n"], \
["STAT\r\n"], \
@@ -340,7 +340,7 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
self.imap_account.disconnect()
self.failUnless(self.server.verify_queries())
return inner
-
+
test_connection = make_test()
test_get_mail_list = make_test([lambda data: "* 42 EXISTS\n* 1 RECENT\n* OK" +\
@@ -433,7 +433,7 @@ class SMTPAccount_TestCase(Account_TestCase):
value = post_func("False", None, "user1@test.com")
self.assertTrue(value)
del account.hub.threadConnection
-
+
def test_default_account_post_func_true(self):
account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url)
account11 = SMTPAccount(user_jid="user1@test.com",
@@ -466,6 +466,194 @@ class SMTPAccount_TestCase(Account_TestCase):
self.assertTrue(account12.default_account)
del account.hub.threadConnection
+ def test_create_email(self):
+ account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url)
+ account11 = SMTPAccount(user_jid="user1@test.com",
+ name="account11",
+ jid="account11@jmc.test.com")
+ del account.hub.threadConnection
+ email = account11.create_email("from@test.com",
+ "to@test.com",
+ "subject",
+ "body")
+ self.assertEqual(email['From'], "from@test.com")
+ self.assertEqual(email['To'], "to@test.com")
+ self.assertEqual(email['Subject'], "subject")
+ self.assertEqual(email.get_payload(), "body")
+
+ def make_test(self, responses=None, queries=None, core=None):
+ def inner():
+ self.server = server.DummyServer("localhost", 1025)
+ thread.start_new_thread(self.server.serve, ())
+ self.server.responses = []
+ if responses:
+ self.server.responses += responses
+ self.server.responses += ["221 localhost closing connection\r\n"]
+ self.server.queries = []
+ if queries:
+ self.server.queries += queries
+ self.server.queries += ["quit\r\n"]
+ if core:
+ account.hub.threadConnection = connectionForURI('sqlite://'
+ + self.db_url)
+ core(self)
+ del account.hub.threadConnection
+ self.failUnless(self.server.verify_queries())
+ return inner
+
+ def test_send_email_esmtp_no_auth(self):
+ account.hub.threadConnection = connectionForURI('sqlite://'
+ + self.db_url)
+ smtp_account = SMTPAccount(user_jid="user1@test.com",
+ name="account11",
+ jid="account11@jmc.test.com")
+ smtp_account.host = "localhost"
+ smtp_account.port = 1025
+ del account.hub.threadConnection
+ email = smtp_account.create_email("from@test.com",
+ "to@test.com",
+ "subject",
+ "body")
+ test_func = self.make_test(["220 localhost ESMTP\r\n",
+ "250-localhost Hello 127.0.0.1\r\n"
+ + "250-SIZE 52428800\r\n"
+ + "250-PIPELINING\r\n"
+ + "250 HELP\r\n",
+ "250 OK\r\n",
+ "250 Accepted\r\n",
+ "354 Enter message\r\n",
+ None, None, None, None,
+ None, None, None, None,
+ "250 OK\r\n"],
+ ["ehlo \[127.0.0.1\]\r\n",
+ "mail FROM:<" + str(email['From']) + ">.*",
+ "rcpt TO:<" + str(email['To']) + ">\r\n",
+ "data\r\n"] +
+ email.as_string().split("\n") + [".\r\n"],
+ lambda self: \
+ smtp_account.send_email(email))
+ test_func()
+
+ def test_send_email_no_auth(self):
+ account.hub.threadConnection = connectionForURI('sqlite://'
+ + self.db_url)
+ smtp_account = SMTPAccount(user_jid="user1@test.com",
+ name="account11",
+ jid="account11@jmc.test.com")
+ smtp_account.host = "localhost"
+ smtp_account.port = 1025
+ del account.hub.threadConnection
+ email = smtp_account.create_email("from@test.com",
+ "to@test.com",
+ "subject",
+ "body")
+ test_func = self.make_test(["220 localhost SMTP\r\n",
+ "504 ESMTP not supported\r\n",
+ "250-localhost Hello 127.0.0.1\r\n"
+ + "250-SIZE 52428800\r\n"
+ + "250-PIPELINING\r\n"
+ + "250 HELP\r\n",
+ "250 OK\r\n",
+ "250 Accepted\r\n",
+ "354 Enter message\r\n",
+ None, None, None, None,
+ None, None, None, None,
+ "250 OK\r\n"],
+ ["ehlo \[127.0.0.1\]\r\n",
+ "helo \[127.0.0.1\]\r\n",
+ "mail FROM:<" + str(email['From']) + ">.*",
+ "rcpt TO:<" + str(email['To']) + ">\r\n",
+ "data\r\n"] +
+ email.as_string().split("\n") + [".\r\n"],
+ lambda self: \
+ smtp_account.send_email(email))
+ test_func()
+
+ def test_send_email_esmtp_auth(self):
+ account.hub.threadConnection = connectionForURI('sqlite://'
+ + self.db_url)
+ smtp_account = SMTPAccount(user_jid="user1@test.com",
+ name="account11",
+ jid="account11@jmc.test.com")
+ smtp_account.host = "localhost"
+ smtp_account.port = 1025
+ smtp_account.login = "user"
+ smtp_account.password = "pass"
+ del account.hub.threadConnection
+ email = smtp_account.create_email("from@test.com",
+ "to@test.com",
+ "subject",
+ "body")
+ test_func = self.make_test(["220 localhost ESMTP\r\n",
+ "250-localhost Hello 127.0.0.1\r\n"
+ + "250-SIZE 52428800\r\n"
+ + "250-AUTH PLAIN LOGIN CRAM-MD5\r\n"
+ + "250-PIPELINING\r\n"
+ + "250 HELP\r\n",
+ "334 ZGF4IDNmNDM2NzY0YzBhNjgyMTQ1MzhhZGNiMjE2YTYxZjRm\r\n",
+ "235 Authentication succeeded\r\n",
+ "250 OK\r\n",
+ "250 Accepted\r\n",
+ "354 Enter message\r\n",
+ None, None, None, None,
+ None, None, None, None,
+ "250 OK\r\n"],
+ ["ehlo \[127.0.0.1\]\r\n",
+ "AUTH CRAM-MD5\r\n",
+ ".*\r\n",
+ "mail FROM:<" + str(email['From']) + ">.*",
+ "rcpt TO:<" + str(email['To']) + ">\r\n",
+ "data\r\n"] +
+ email.as_string().split("\n") + [".\r\n"],
+ lambda self: \
+ smtp_account.send_email(email))
+ test_func()
+
+ def test_send_email_esmtp_auth_method2(self):
+ account.hub.threadConnection = connectionForURI('sqlite://'
+ + self.db_url)
+ smtp_account = SMTPAccount(user_jid="user1@test.com",
+ name="account11",
+ jid="account11@jmc.test.com")
+ smtp_account.host = "localhost"
+ smtp_account.port = 1025
+ smtp_account.login = "user"
+ smtp_account.password = "pass"
+ del account.hub.threadConnection
+ email = smtp_account.create_email("from@test.com",
+ "to@test.com",
+ "subject",
+ "body")
+ test_func = self.make_test(["220 localhost ESMTP\r\n",
+ "250-localhost Hello 127.0.0.1\r\n"
+ + "250-SIZE 52428800\r\n"
+ + "250-AUTH PLAIN LOGIN CRAM-MD5\r\n"
+ + "250-PIPELINING\r\n"
+ + "250 HELP\r\n",
+ "334 ZGF4IDNmNDM2NzY0YzBhNjgyMTQ1MzhhZGNiMjE2YTYxZjRm\r\n",
+ "535 Incorrect Authentication data\r\n",
+ "334 asd235r4\r\n",
+ "235 Authentication succeeded\r\n",
+ "250 OK\r\n",
+ "250 Accepted\r\n",
+ "354 Enter message\r\n",
+ None, None, None, None,
+ None, None, None, None,
+ "250 OK\r\n"],
+ ["ehlo \[127.0.0.1\]\r\n",
+ "AUTH CRAM-MD5\r\n",
+ ".*\r\n",
+ "AUTH LOGIN .*\r\n",
+ ".*\r\n",
+ "mail FROM:<" + str(email['From']) + ">.*",
+ "rcpt TO:<" + str(email['To']) + ">\r\n",
+ "data\r\n"] +
+ email.as_string().split("\n") + [".\r\n"],
+ lambda self: \
+ smtp_account.send_email(email))
+ test_func()
+
+
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(MailAccount_TestCase, 'test'))
diff --git a/src/jmc/model/tests/server.py b/src/jmc/model/tests/server.py
index 1b939aa..a318091 100644
--- a/src/jmc/model/tests/server.py
+++ b/src/jmc/model/tests/server.py
@@ -1,20 +1,20 @@
##
## dummy_server.py
## Login : David Rousselie <david.rousselie@happycoders.org>
-## Started on Fri May 13 12:53:17 2005
+## Started on Fri May 13 12:53:17 2005
## $Id: dummy_server.py,v 1.1 2005/07/11 20:39:31 dax Exp $
-##
-## Copyright (C) 2005
+##
+## Copyright (C) 2005
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
-##
+##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
-##
+##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -75,7 +75,7 @@ class DummyServer:
self.responses = None
self.queries = None
self.real_queries = []
-
+
def serve(self):
conn = None
try:
@@ -150,7 +150,7 @@ class XMLDummyServer(DummyServer):
r = self._reader.feed(data)
except:
type, value, stack = sys.exc_info()
- print "".join (traceback.format_exception
+ print "".join (traceback.format_exception
(type, value, stack, 5))
raise
# TODO verify got all data </stream>
@@ -175,7 +175,7 @@ class XMLDummyServer(DummyServer):
self.socket = None
except:
type, value, stack = sys.exc_info()
- print "".join (traceback.format_exception
+ print "".join (traceback.format_exception
(type, value, stack, 5))
raise
@@ -205,5 +205,5 @@ def test():
if __name__ == '__main__':
test()
-
+