summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuda Dornelles <ddornell@thoughtworks.com>2014-09-01 16:24:46 -0300
committerDuda Dornelles <ddornell@thoughtworks.com>2014-09-01 16:24:56 -0300
commita44f7738f43a349a8c3fd4768dd54add13b3ce12 (patch)
treef247e611fa2eae630e5a74205c2abeda6eae6404
parent19391f5b4701d6ec933b016c28808e7d60157cbf (diff)
support multiple to, cc and bcc
-rw-r--r--service/pixelated/adapter/pixelated_mail.py12
-rw-r--r--service/pixelated/adapter/pixelated_mail_sender.py10
-rw-r--r--service/pixelated/support/__init__.py15
-rw-r--r--service/pixelated/support/functional.py20
-rw-r--r--service/test/adapter/pixelated_mail_sender_test.py44
-rw-r--r--service/test/adapter/pixelated_mail_test.py18
-rw-r--r--service/test/adapter/test_helper.py14
7 files changed, 120 insertions, 13 deletions
diff --git a/service/pixelated/adapter/pixelated_mail.py b/service/pixelated/adapter/pixelated_mail.py
index e43d5510..d20a93f4 100644
--- a/service/pixelated/adapter/pixelated_mail.py
+++ b/service/pixelated/adapter/pixelated_mail.py
@@ -42,7 +42,13 @@ class PixelatedMail:
self.headers['from'] = [_from]
def get_to(self):
- return self.headers['to'][0]
+ return self.headers['to']
+
+ def get_cc(self):
+ return self.headers['cc']
+
+ def get_bcc(self):
+ return self.headers['bcc']
def _extract_status(self):
return Status.from_flags(self.leap_mail.getFlags())
@@ -81,7 +87,9 @@ class PixelatedMail:
def to_mime_multipart(self):
mime_multipart = MIMEMultipart()
- mime_multipart['To'] = self.headers['to'][0]
+ mime_multipart['To'] = ", ".join(self.headers['to'])
+ mime_multipart['Cc'] = ", ".join(self.headers['cc'])
+ mime_multipart['Bcc'] = ", ".join(self.headers['bcc'])
mime_multipart['Subject'] = self.headers['subject']
mime_multipart.attach(MIMEText(self.body, 'plain'))
return mime_multipart
diff --git a/service/pixelated/adapter/pixelated_mail_sender.py b/service/pixelated/adapter/pixelated_mail_sender.py
index 3ace6814..6f6340da 100644
--- a/service/pixelated/adapter/pixelated_mail_sender.py
+++ b/service/pixelated/adapter/pixelated_mail_sender.py
@@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
import smtplib
+from pixelated.support.functional import flatten
class PixelatedMailSender():
@@ -22,7 +23,10 @@ class PixelatedMailSender():
self.smtp_client = smtplib.SMTP('localhost', 4650)
def sendmail(self, mail):
- _from = self.account_email_address
- _to = mail.get_to()
+ recipients = flatten([mail.get_to(), mail.get_cc(), mail.get_bcc()])
- self.smtp_client.sendmail(_from, _to, mail.to_smtp_format(_from=_from))
+ self.smtp_client.sendmail(
+ self.account_email_address,
+ recipients,
+ mail.to_smtp_format(_from=self.account_email_address)
+ )
diff --git a/service/pixelated/support/__init__.py b/service/pixelated/support/__init__.py
new file mode 100644
index 00000000..2756a319
--- /dev/null
+++ b/service/pixelated/support/__init__.py
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
diff --git a/service/pixelated/support/functional.py b/service/pixelated/support/functional.py
new file mode 100644
index 00000000..e779f5bc
--- /dev/null
+++ b/service/pixelated/support/functional.py
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+from itertools import chain
+
+
+def flatten(_list):
+ return list(chain.from_iterable(_list))
diff --git a/service/test/adapter/pixelated_mail_sender_test.py b/service/test/adapter/pixelated_mail_sender_test.py
new file mode 100644
index 00000000..0a8c017b
--- /dev/null
+++ b/service/test/adapter/pixelated_mail_sender_test.py
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+import unittest
+from pixelated.adapter.pixelated_mail import PixelatedMail
+from pixelated.adapter.pixelated_mail_sender import PixelatedMailSender
+from mockito import *
+import test_helper
+
+
+class PixelatedMailSenderTest(unittest.TestCase):
+ def setUp(self):
+ self.mail_address = "pixelated@pixelated.org"
+ self.mail_sender = PixelatedMailSender(self.mail_address)
+ self.mail_sender.smtp_client = mock()
+
+ def test_send_mail_sends_to_To_Cc_and_Bcc(self):
+ mail_dict = test_helper.mail_dict()
+ mail_dict['header']['to'] = ['to@pixelated.org', 'anotherto@pixelated.org']
+ mail_dict['header']['cc'] = ['cc@pixelated.org', 'anothercc@pixelated.org']
+ mail_dict['header']['bcc'] = ['bcc@pixelated.org', 'anotherbcc@pixelated.org']
+
+ mail = PixelatedMail.from_dict(mail_dict)
+ mail.to_smtp_format = lambda _from: "mail as smtp string"
+
+ self.mail_sender.sendmail(mail)
+
+ expected_recipients = ['to@pixelated.org', 'anotherto@pixelated.org', 'cc@pixelated.org',
+ 'anothercc@pixelated.org',
+ 'bcc@pixelated.org', 'anotherbcc@pixelated.org']
+
+ verify(self.mail_sender.smtp_client).sendmail(self.mail_address, expected_recipients, "mail as smtp string")
diff --git a/service/test/adapter/pixelated_mail_test.py b/service/test/adapter/pixelated_mail_test.py
index 8c1d5896..e0b9a662 100644
--- a/service/test/adapter/pixelated_mail_test.py
+++ b/service/test/adapter/pixelated_mail_test.py
@@ -24,10 +24,10 @@ class TestPixelatedMail(unittest.TestCase):
mail_dict = {
'body': 'Este \xe9 o corpo',
'header': {
- 'cc': ['cc@pixelated.org'],
- 'to': ['to@pixelated.org'],
- 'subject': 'Oi',
- 'bcc': ['bcc@pixelated.org']
+ 'cc': ['cc@pixelated.org', 'anothercc@pixelated.org'],
+ 'to': ['to@pixelated.org', 'anotherto@pixelated.org'],
+ 'bcc': ['bcc@pixelated.org', 'anotherbcc@pixelated.org'],
+ 'subject': 'Oi'
},
'ident': '',
'tags': ['sent']
@@ -62,9 +62,9 @@ class TestPixelatedMail(unittest.TestCase):
mail = PixelatedMail.from_dict(self.mail_dict)
- self.assertEqual(mail.headers['cc'], ['cc@pixelated.org'])
- self.assertEqual(mail.headers['to'], ['to@pixelated.org'])
- self.assertEqual(mail.headers['bcc'], ['bcc@pixelated.org'])
+ self.assertEqual(mail.headers['cc'], ['cc@pixelated.org', 'anothercc@pixelated.org'])
+ self.assertEqual(mail.headers['to'], ['to@pixelated.org', 'anotherto@pixelated.org'])
+ self.assertEqual(mail.headers['bcc'], ['bcc@pixelated.org', 'anotherbcc@pixelated.org'])
self.assertEqual(mail.headers['subject'], 'Oi')
self.assertEqual(mail.ident, '')
self.assertEqual(mail.tags, ['sent'])
@@ -81,7 +81,9 @@ class TestPixelatedMail(unittest.TestCase):
mime_multipart = mail.to_mime_multipart()
- self.assertRegexpMatches(mime_multipart.as_string(), "\nTo: to@pixelated.org\n")
+ self.assertRegexpMatches(mime_multipart.as_string(), "\nTo: to@pixelated.org, anotherto@pixelated.org\n")
+ self.assertRegexpMatches(mime_multipart.as_string(), "\nCc: cc@pixelated.org, anothercc@pixelated.org\n")
+ self.assertRegexpMatches(mime_multipart.as_string(), "\nBcc: bcc@pixelated.org, anotherbcc@pixelated.org\n")
self.assertRegexpMatches(mime_multipart.as_string(), "\nSubject: Oi\n")
self.assertRegexpMatches(mime_multipart.as_string(), "\nEste \xe9 o corpo")
diff --git a/service/test/adapter/test_helper.py b/service/test/adapter/test_helper.py
index f61ee49d..07914aea 100644
--- a/service/test/adapter/test_helper.py
+++ b/service/test/adapter/test_helper.py
@@ -25,6 +25,20 @@ LEAP_FLAGS = ['\\Seen',
'List']
+def mail_dict():
+ return {
+ 'header': {
+ 'to': ['to@pixelated.org', 'anotherto@pixelated.org'],
+ 'cc': ['cc@pixelated.org', 'anothercc@pixelated.org'],
+ 'bcc': ['bcc@pixelated.org', 'anotherbcc@pixelated.org'],
+ 'subject': 'Subject'
+ },
+ 'body': 'Body',
+ 'ident': '',
+ 'tags': []
+ }
+
+
def leap_mail(uid=0, leap_flags=LEAP_FLAGS, extra_flags=[], headers={'date': str(datetime.now())}):
flags = leap_flags + extra_flags
return Mock(getUID=Mock(return_value=uid),