Update docs with information about how to use thread-unsafe code in
[salmon.git] / tests / test_message.py
blob1b2d7f1e70654a841a1d32fba0b4af411b6f39d3
1 # Copyright (C) 2008 Zed A. Shaw. Licensed under the terms of the GPLv3.
2 from unittest import TestCase
4 from salmon import encoding, mail
6 sample_message = """From: somedude@localhost
7 To: somedude@localhost
9 Test
10 """
13 class MessageTestCase(TestCase):
14 def test_mail_request(self):
15 # try with a half-assed message
16 msg = mail.MailRequest("localhost", "zedfrom@localhost",
17 "zedto@localhost", "Fake body.")
18 self.assertEqual(msg['to'], "zedto@localhost")
19 self.assertEqual(msg['from'], "zedfrom@localhost")
21 msg = mail.MailRequest("localhost", "somedude@localhost", ["somedude@localhost"], sample_message)
22 self.assertEqual(msg.original, sample_message)
24 self.assertEqual(msg['From'], "somedude@localhost")
26 assert("From" in msg)
27 del msg["From"]
28 assert("From" not in msg)
30 msg["From"] = "nobody@localhost"
31 assert("From" in msg)
32 self.assertEqual(msg["From"], "nobody@localhost")
33 msg["From"] = "somebody@localhost"
34 self.assertEqual(msg["From"], "somebody@localhost")
35 self.assertEqual(msg.keys(), ["To", "From"])
36 self.assertEqual(msg.items(), [("To", "somedude@localhost"), ("From", "somebody@localhost")])
38 # appending headers
39 msg.base.append_header("To", "nobody@example.com")
40 self.assertEqual(msg["To"], "somedude@localhost")
41 self.assertEqual(msg.keys(), ["To", "From", "To"])
42 self.assertEqual(msg.items(), [("To", "somedude@localhost"), ("From", "somebody@localhost"),
43 ("To", "nobody@example.com")])
45 # validate that upper and lower case work for headers
46 assert("FroM" in msg)
47 assert("from" in msg)
48 assert("From" in msg)
49 self.assertEqual(msg['From'], msg['fRom'])
50 self.assertEqual(msg['From'], msg['from'])
51 self.assertEqual(msg['from'], msg['fRom'])
53 # make sure repr runs
54 assert repr(msg)
56 assert str(msg)
58 def test_mail_attach_no_data_or_file(self):
59 msg = mail.MailResponse(
60 To="receiver@localhost",
61 Subject="Test message",
62 From="sender@localhost",
65 with self.assertRaises(TypeError):
66 msg.attach()
68 def test_mail_attach_file_no_exist(self):
69 msg = mail.MailResponse(
70 To="receiver@localhost",
71 Subject="Test message",
72 From="sender@localhost",
75 with self.assertRaises(TypeError):
76 msg.attach(filename="/filethatshouldnotexist")
78 def test_mail_response_plain_text(self):
79 sample = mail.MailResponse(
80 To="receiver@localhost",
81 Subject="Test message",
82 From="sender@localhost",
83 Body="Test from test_mail_response_plain_text.",
86 assert str(sample)
87 return sample
89 def test_mail_response_html(self):
90 sample = mail.MailResponse(
91 To="receiver@localhost",
92 Subject="Test message",
93 From="sender@localhost",
94 Html="<html><body><p>From test_mail_response_html</p></body></html>",
96 assert str(sample)
97 return sample
99 def test_mail_response_html_and_plain_text(self):
100 sample = mail.MailResponse(
101 To="receiver@localhost",
102 Subject="Test message",
103 From="sender@localhost",
104 Html="<html><body><p>Hi there.</p></body></html>",
105 Body="Test from test_mail_response_html_and_plain_text.",
107 assert str(sample)
108 return sample
110 def test_mail_response_empty(self):
111 sample = mail.MailResponse(
112 To="receiver@localhost",
113 Subject="Test message",
114 From="sender@localhost",
116 assert str(sample)
117 return sample
119 def test_mail_response_attachments(self):
120 sample = mail.MailResponse(
121 To="receiver@localhost",
122 Subject="Test message",
123 From="sender@localhost",
124 Body="Test from test_mail_response_attachments.",
126 with open("./LICENSE") as file_obj:
127 readme_data = file_obj.read()
129 with self.assertRaises(ValueError):
130 sample.attach(data=readme_data, disposition="inline")
132 sample.attach(filename="./LICENSE", content_type="text/plain", disposition="inline")
133 self.assertEqual(len(sample.attachments), 1)
134 assert sample.multipart
136 msg = sample.to_message()
137 self.assertEqual(len(msg.get_payload()), 2)
139 sample.clear()
140 self.assertEqual(len(sample.attachments), 0)
141 assert not sample.multipart
143 sample.attach(data=readme_data, filename="./LICENSE", content_type="text/plain")
145 msg = sample.to_message()
146 self.assertEqual(len(msg.get_payload()), 2)
147 sample.clear()
149 sample.attach(data=readme_data, content_type="text/plain")
150 msg = sample.to_message()
151 self.assertEqual(len(msg.get_payload()), 2)
153 assert str(sample)
154 return sample
156 def test_mail_request_attachments(self):
157 sample = self.test_mail_response_attachments()
158 data = str(sample)
160 msg = mail.MailRequest("localhost", None, None, data)
162 msg_parts = msg.all_parts()
163 sample_parts = sample.all_parts()
165 with open("./LICENSE") as file_obj:
166 readme = file_obj.read()
168 assert msg_parts[0].body == sample_parts[0].body
169 assert readme == msg_parts[1].body
170 assert msg.body() == sample_parts[0].body
172 # test that we get at least one message for messages without attachments
173 sample = self.test_mail_response_plain_text()
174 msg = mail.MailRequest("localhost", None, None, str(sample))
175 msg_parts = msg.all_parts()
176 self.assertEqual(len(msg_parts), 0)
177 assert msg.body()
179 def test_mail_response_mailing_list_headers(self):
180 list_addr = "test.users@localhost"
182 msg = mail.MailResponse(From='somedude@localhost', To=list_addr, Subject='subject', Body="Mailing list reply.")
184 print(repr(msg))
186 msg["Sender"] = list_addr
187 msg["Reply-To"] = list_addr
188 msg["List-Id"] = list_addr
189 msg["Return-Path"] = list_addr
190 msg["In-Reply-To"] = 'Message-Id-1231123'
191 msg["References"] = 'Message-Id-838845854'
192 msg["Precedence"] = 'list'
194 data = str(msg)
196 req = mail.MailRequest('localhost', 'somedude@localhost', list_addr, data)
198 headers = ['Sender', 'Reply-To', 'List-Id', 'Return-Path', 'In-Reply-To', 'References', 'Precedence']
199 for header in headers:
200 assert msg[header] == req[header], "%s: %r != %r" % (header, msg[header], req[header])
202 # try a delete
203 del msg['Precedence']
205 def test_mail_response_headers(self):
206 msg = self.test_mail_response_plain_text()
207 # validate that upper and lower case work for headers
208 assert("FroM" in msg)
209 assert("from" in msg)
210 assert("From" in msg)
211 self.assertEqual(msg['From'], msg['fRom'])
212 self.assertEqual(msg['From'], msg['from'])
213 self.assertEqual(msg['from'], msg['fRom'])
215 self.assertEqual(msg.keys(), [i[0] for i in msg.items()])
217 def test_walk(self):
218 with open("tests/data/bounce.msg") as file_obj:
219 bm = mail.MailRequest(None, None, None, file_obj.read())
220 parts = [x for x in bm.walk()]
222 assert parts
223 self.assertEqual(len(parts), 6)
225 def test_copy_parts(self):
226 with open("tests/data/bounce.msg") as file_obj:
227 bm = mail.MailRequest(None, None, None, file_obj.read())
229 resp = mail.MailResponse(To=bm['to'], From=bm['from'], Subject=bm['subject'])
231 resp.attach_all_parts(bm)
233 resp = resp.to_message()
234 bm = bm.to_message()
236 self.assertEqual(len([x for x in bm.walk()]), len([x for x in resp.walk()]))
238 def test_craft_from_sample(self):
239 list_name = "test.list"
240 user_full_address = "tester@localhost"
242 sample = mail.MailResponse(
243 To=list_name + "@localhost",
244 From=user_full_address,
245 Subject="Test message with attachments.",
246 Body="The body as one attachment.",
248 sample.update({"Test": "update"})
250 sample.attach(filename="tests/test_message.py", content_type="text/plain", disposition="attachment")
252 inmsg = mail.MailRequest("fakepeer", None, None, str(sample))
253 assert "Test" in sample.keys()
255 for part in inmsg.to_message().walk():
256 assert part.get_payload(), "inmsg busted."
258 outmsg = mail.MailResponse(To=inmsg['from'], From=inmsg['to'], Subject=inmsg['subject'])
260 outmsg.attach_all_parts(inmsg)
262 result = outmsg.to_message()
264 for part in result.walk():
265 assert part.get_payload(), "outmsg parts don't have payload."
267 def test_to_from_works(self):
268 msg = mail.MailRequest("fakepeer", "from@localhost", ["<to1@localhost>", "to2@localhost"], "")
269 assert '<' not in msg.To, msg.To
271 msg = mail.MailRequest("fakepeer", "from@localhost", ["to1@localhost", "to2@localhost"], "")
272 assert '<' not in msg.To, msg.To
274 msg = mail.MailRequest("fakepeer", "from@localhost", ["to1@localhost", "<to2@localhost>"], "")
275 assert '<' not in msg.To, msg.To
277 msg = mail.MailRequest("fakepeer", "from@localhost", ["to1@localhost"], "")
278 assert '<' not in msg.To, msg.To
280 msg = mail.MailRequest("fakepeer", "from@localhost", ["<to1@localhost>"], "")
281 assert '<' not in msg.To, msg.To
283 def test_decode_header_randomness(self):
284 self.assertEqual(mail._decode_header_randomness(None), set())
286 # with strings
287 self.assertEqual(mail._decode_header_randomness(["z@localhost", '"Z A" <z@localhost>']),
288 set(["z@localhost", "z@localhost"]))
289 self.assertEqual(mail._decode_header_randomness("z@localhost"), set(["z@localhost"]))
291 # with bytes
292 self.assertEqual(mail._decode_header_randomness([b"z@localhost", b'"Z A" <z@localhost>']),
293 set(["z@localhost", "z@localhost"]))
294 self.assertEqual(mail._decode_header_randomness(b"z@localhost"), set(["z@localhost"]))
296 # with literal nonsense
297 with self.assertRaises(encoding.EncodingError):
298 mail._decode_header_randomness(1)
299 with self.assertRaises(encoding.EncodingError):
300 mail._decode_header_randomness([1, "m@localhost"])