Skip to content

Commit 3b0a1f3

Browse files
committed
test(send_mail.py): add test cases for send_mail.py
issue pycontw#7
1 parent 3f7b212 commit 3b0a1f3

File tree

3 files changed

+256
-3
lines changed

3 files changed

+256
-3
lines changed

send_mail.py

+24-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import logging
44
import os
55
import smtplib
6+
import pickle
7+
from pathlib import Path
68
from email.mime.application import MIMEApplication
79
from email.mime.multipart import MIMEMultipart
810
from email.mime.text import MIMEText
@@ -69,6 +71,19 @@ def send_mail(mail, user, password, server_config=None):
6971
server.quit()
7072

7173

74+
def dump_mail(mail, suffix):
75+
if suffix:
76+
dump_path = "/tmp/mail_handler/with-separator"
77+
Path(dump_path).mkdir(parents=True, exist_ok=True)
78+
with open(f"{dump_path}/{mail['To']}", "wb") as dumpf:
79+
pickle.dump(mail, dumpf)
80+
else:
81+
dump_path = "/tmp/mail_handler/no-separator"
82+
Path(dump_path).mkdir(parents=True, exist_ok=True)
83+
with open(f"{dump_path}/{mail['To']}", "wb") as dumpf:
84+
pickle.dump(mail, dumpf)
85+
86+
7287
@click.command()
7388
@click.argument("config_path", type=click.Path(exists=True))
7489
@click.option(
@@ -77,14 +92,15 @@ def send_mail(mail, user, password, server_config=None):
7792
default="mails_to_sent",
7893
show_default=True,
7994
)
95+
@click.option("--debug", is_flag=True)
8096
@click.option(
8197
"--separator",
82-
default="",
98+
default=" - ",
8399
show_default=True,
84100
help="Separator used for subject suffix",
85101
)
86102
@click.option("--attachment_file", type=click.Path(exists=False))
87-
def main(mails_path, config_path, separator, attachment_file=None):
103+
def main(mails_path, config_path, debug, separator, attachment_file=None):
88104
if click.confirm(
89105
f'You are about to send the mails under "{mails_path}". Do you want to continue?',
90106
abort=True,
@@ -110,7 +126,12 @@ def main(mails_path, config_path, separator, attachment_file=None):
110126
attachment_file=attachment_file,
111127
suffix=mail_suffix,
112128
)
113-
send_mail(mail, user, password)
129+
130+
if debug:
131+
print("Debug mode is on. Dump mails instead of sending them.")
132+
dump_mail(mail, mail_suffix)
133+
else:
134+
send_mail(mail, user, password)
114135

115136

116137
# pylint: disable=no-value-for-parameter
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
2+
3+
Curabitur pretium tincidunt lacus. Nulla gravida orci a odio. Nullam varius, turpis et commodo pharetra, est eros bibendum elit, nec luctus magna felis sollicitudin mauris. Integer in mauris eu nibh euismod gravida. Duis ac tellus et risus vulputate vehicula. Donec lobortis risus a elit. Etiam tempor. Ut ullamcorper, ligula eu tempor congue, eros est euismod turpis, id tincidunt sapien risus a quam. Maecenas fermentum consequat mi. Donec fermentum. Pellentesque malesuada nulla a mi. Duis sapien sem, aliquet nec, commodo eget, consequat quis, neque. Aliquam faucibus, elit ut dictum aliquet, felis nisl adipiscing sapien, sed malesuada diam lacus eget erat. Cras mollis scelerisque nunc. Nullam arcu. Aliquam consequat. Curabitur augue lorem, dapibus quis, laoreet et, pretium ac, nisi. Aenean magna nisl, mollis quis, molestie eu, feugiat in, orci. In hac habitasse platea dictumst.

tests/test_send_mail.py

+229
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
import pickle
2+
import glob
3+
import json
4+
import os
5+
import pytest
6+
7+
from click.testing import CliRunner
8+
from send_mail import main
9+
10+
11+
path_mail_config = "./examples/sponsorship/spam_sponsors_2020_mail_config.json"
12+
path_receivers = "./examples/sponsorship/spam_sponsors_2020.json"
13+
path_pre_rendered_mails_no_separator = "./tests/data/no-separator"
14+
path_pre_rendered_mails_with_separator = "./tests/data/with-separator"
15+
path_attachment = "./tests/data/attachment-file/attachment01.txt"
16+
17+
18+
@pytest.fixture
19+
def all_mails_base_no_separator():
20+
return get_all_mail_names_from_path(
21+
glob.glob("/".join((path_pre_rendered_mails_no_separator, "*@*")))
22+
)
23+
24+
25+
@pytest.fixture
26+
def all_mails_base_with_separator():
27+
return get_all_mail_names_from_path(
28+
glob.glob("/".join((path_pre_rendered_mails_with_separator, "*@*")))
29+
)
30+
31+
32+
def get_mail_config():
33+
with open(path_mail_config, "rb") as f:
34+
return json.load(f)
35+
36+
37+
def get_receivers():
38+
with open(path_receivers, "rb") as f:
39+
return json.load(f)
40+
41+
42+
def get_all_mail_names_from_path(mails):
43+
all_mail_names = []
44+
for mail in mails:
45+
all_mail_names.append(os.path.basename(mail))
46+
47+
return all_mail_names
48+
49+
50+
def compare_on_sending_mail_all(
51+
targets, target_prefix="../examples", separator=" - ",
52+
):
53+
receivers = get_receivers()
54+
receiver_emails = []
55+
for mail_name in targets:
56+
for receiver in receivers["unique_data"]:
57+
mail_addr, *mail_suffix_and_more = mail_name.split(separator, maxsplit=1)
58+
mail_suffix = mail_suffix_and_more[0] if mail_suffix_and_more else None
59+
print(f"Mail suffix is {mail_suffix}")
60+
if receiver["receiver_email"] == mail_addr:
61+
receiver_emails.append(mail_name)
62+
63+
# Not all target emails could have the corresponding answers
64+
if len(receiver_emails) != len(targets):
65+
return False
66+
67+
for mail_name in targets:
68+
for receiver in receivers["unique_data"]:
69+
if receiver["receiver_email"] == mail_name:
70+
if not compare_on_sending_mail(
71+
"/".join((target_prefix, mail_name)), receivers
72+
):
73+
return False
74+
75+
return True
76+
77+
78+
def compare_on_sending_mail(target, receivers):
79+
mail_name = os.path.basename(target)
80+
mail_config = get_mail_config()
81+
82+
with open(target, "rb") as f:
83+
target_content = pickle.load(f)
84+
if target_content["From"] != mail_config["From"]:
85+
return False
86+
87+
if mail_name != target_content["To"]:
88+
return False
89+
90+
if target_content["CC"] != mail_config["CC"]:
91+
return False
92+
93+
for receiver in receivers["unique_data"]:
94+
if receiver["receiver_email"] == target_content["To"]:
95+
receiver_name = receiver["receiver_name"]
96+
97+
if (
98+
"no-separator" in target
99+
and mail_config["Subject"] != target_content["Subject"]
100+
):
101+
return False
102+
103+
if "with-separator" in target:
104+
subject = " - ".join((mail_config["Subject"], receiver_name))
105+
if subject != target_content["Subject"]:
106+
return False
107+
108+
if not is_attachment_expected(target_content):
109+
return False
110+
111+
return True
112+
113+
114+
def is_attachment_expected(target_content):
115+
for part in target_content.walk():
116+
content_disposition = part.get("Content-Disposition", None)
117+
if content_disposition:
118+
dispositions = content_disposition.strip().split(";")
119+
if bool(content_disposition and dispositions[0].lower() == "attachment"):
120+
target_data = part.get_payload(decode=True)
121+
with open(path_attachment, "rb") as fattachment:
122+
base_data = fattachment.readlines()
123+
data_str_target = target_data.decode("utf-8")
124+
base_data_tmp = []
125+
126+
for line in base_data:
127+
base_data_tmp.append(line.decode("utf-8"))
128+
data_str_base = "".join(base_data_tmp)
129+
130+
if data_str_base != data_str_target:
131+
return False
132+
133+
return True
134+
135+
136+
def test_send_mail_no_separator_no_attachment(all_mails_base_no_separator):
137+
runner = CliRunner()
138+
result = runner.invoke(
139+
main,
140+
[
141+
"--debug",
142+
"--mails_path",
143+
path_pre_rendered_mails_no_separator,
144+
path_mail_config,
145+
],
146+
input="y\nusername\npassword\n",
147+
)
148+
149+
targets = get_all_mail_names_from_path(all_mails_base_no_separator)
150+
151+
assert result.exit_code == 0
152+
assert compare_on_sending_mail_all(
153+
targets, target_prefix="/tmp/mail_handler/no-separator"
154+
)
155+
156+
157+
def test_send_mail_no_separator_with_attachment(all_mails_base_no_separator):
158+
runner = CliRunner()
159+
result = runner.invoke(
160+
main,
161+
[
162+
"--debug",
163+
"--mails_path",
164+
path_pre_rendered_mails_no_separator,
165+
"--attachment_file",
166+
path_attachment,
167+
path_mail_config,
168+
],
169+
input="y\nusername\npassword\n",
170+
)
171+
172+
targets = get_all_mail_names_from_path(all_mails_base_no_separator)
173+
174+
assert result.exit_code == 0
175+
assert compare_on_sending_mail_all(
176+
targets, target_prefix="/tmp/mail_handler/no-separator"
177+
)
178+
179+
180+
def test_send_mail_with_separator_dash_no_attachment(all_mails_base_with_separator):
181+
separator = " - "
182+
183+
runner = CliRunner()
184+
result = runner.invoke(
185+
main,
186+
[
187+
"--debug",
188+
"--separator",
189+
separator,
190+
"--mails_path",
191+
path_pre_rendered_mails_with_separator,
192+
path_mail_config,
193+
],
194+
input="y\nusername\npassword\n",
195+
)
196+
197+
targets = get_all_mail_names_from_path(all_mails_base_with_separator)
198+
199+
assert result.exit_code == 0
200+
assert compare_on_sending_mail_all(
201+
targets, target_prefix="/tmp/mail_handler/with-separator", separator=separator
202+
)
203+
204+
205+
def test_send_mail_with_separator_dash_with_attachment(all_mails_base_with_separator):
206+
separator = " - "
207+
208+
runner = CliRunner()
209+
result = runner.invoke(
210+
main,
211+
[
212+
"--debug",
213+
"--separator",
214+
separator,
215+
"--mails_path",
216+
path_pre_rendered_mails_with_separator,
217+
"--attachment_file",
218+
path_attachment,
219+
path_mail_config,
220+
],
221+
input="y\nusername\npassword\n",
222+
)
223+
224+
targets = get_all_mail_names_from_path(all_mails_base_with_separator)
225+
226+
assert result.exit_code == 0
227+
assert compare_on_sending_mail_all(
228+
targets, target_prefix="/tmp/mail_handler/with-separator", separator=separator
229+
)

0 commit comments

Comments
 (0)