Skip to content

Commit

Permalink
test(send_mail.py): add test cases for send_mail.py
Browse files Browse the repository at this point in the history
issue pycontw#7
  • Loading branch information
tai271828 committed May 26, 2020
1 parent 3f7b212 commit 3b0a1f3
Show file tree
Hide file tree
Showing 3 changed files with 256 additions and 3 deletions.
27 changes: 24 additions & 3 deletions send_mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import logging
import os
import smtplib
import pickle
from pathlib import Path
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
Expand Down Expand Up @@ -69,6 +71,19 @@ def send_mail(mail, user, password, server_config=None):
server.quit()


def dump_mail(mail, suffix):
if suffix:
dump_path = "/tmp/mail_handler/with-separator"
Path(dump_path).mkdir(parents=True, exist_ok=True)
with open(f"{dump_path}/{mail['To']}", "wb") as dumpf:
pickle.dump(mail, dumpf)
else:
dump_path = "/tmp/mail_handler/no-separator"
Path(dump_path).mkdir(parents=True, exist_ok=True)
with open(f"{dump_path}/{mail['To']}", "wb") as dumpf:
pickle.dump(mail, dumpf)


@click.command()
@click.argument("config_path", type=click.Path(exists=True))
@click.option(
Expand All @@ -77,14 +92,15 @@ def send_mail(mail, user, password, server_config=None):
default="mails_to_sent",
show_default=True,
)
@click.option("--debug", is_flag=True)
@click.option(
"--separator",
default="",
default=" - ",
show_default=True,
help="Separator used for subject suffix",
)
@click.option("--attachment_file", type=click.Path(exists=False))
def main(mails_path, config_path, separator, attachment_file=None):
def main(mails_path, config_path, debug, separator, attachment_file=None):
if click.confirm(
f'You are about to send the mails under "{mails_path}". Do you want to continue?',
abort=True,
Expand All @@ -110,7 +126,12 @@ def main(mails_path, config_path, separator, attachment_file=None):
attachment_file=attachment_file,
suffix=mail_suffix,
)
send_mail(mail, user, password)

if debug:
print("Debug mode is on. Dump mails instead of sending them.")
dump_mail(mail, mail_suffix)
else:
send_mail(mail, user, password)


# pylint: disable=no-value-for-parameter
Expand Down
3 changes: 3 additions & 0 deletions tests/data/attachment-file/attachment01.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
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.

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.
229 changes: 229 additions & 0 deletions tests/test_send_mail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
import pickle
import glob
import json
import os
import pytest

from click.testing import CliRunner
from send_mail import main


path_mail_config = "./examples/sponsorship/spam_sponsors_2020_mail_config.json"
path_receivers = "./examples/sponsorship/spam_sponsors_2020.json"
path_pre_rendered_mails_no_separator = "./tests/data/no-separator"
path_pre_rendered_mails_with_separator = "./tests/data/with-separator"
path_attachment = "./tests/data/attachment-file/attachment01.txt"


@pytest.fixture
def all_mails_base_no_separator():
return get_all_mail_names_from_path(
glob.glob("/".join((path_pre_rendered_mails_no_separator, "*@*")))
)


@pytest.fixture
def all_mails_base_with_separator():
return get_all_mail_names_from_path(
glob.glob("/".join((path_pre_rendered_mails_with_separator, "*@*")))
)


def get_mail_config():
with open(path_mail_config, "rb") as f:
return json.load(f)


def get_receivers():
with open(path_receivers, "rb") as f:
return json.load(f)


def get_all_mail_names_from_path(mails):
all_mail_names = []
for mail in mails:
all_mail_names.append(os.path.basename(mail))

return all_mail_names


def compare_on_sending_mail_all(
targets, target_prefix="../examples", separator=" - ",
):
receivers = get_receivers()
receiver_emails = []
for mail_name in targets:
for receiver in receivers["unique_data"]:
mail_addr, *mail_suffix_and_more = mail_name.split(separator, maxsplit=1)
mail_suffix = mail_suffix_and_more[0] if mail_suffix_and_more else None
print(f"Mail suffix is {mail_suffix}")
if receiver["receiver_email"] == mail_addr:
receiver_emails.append(mail_name)

# Not all target emails could have the corresponding answers
if len(receiver_emails) != len(targets):
return False

for mail_name in targets:
for receiver in receivers["unique_data"]:
if receiver["receiver_email"] == mail_name:
if not compare_on_sending_mail(
"/".join((target_prefix, mail_name)), receivers
):
return False

return True


def compare_on_sending_mail(target, receivers):
mail_name = os.path.basename(target)
mail_config = get_mail_config()

with open(target, "rb") as f:
target_content = pickle.load(f)
if target_content["From"] != mail_config["From"]:
return False

if mail_name != target_content["To"]:
return False

if target_content["CC"] != mail_config["CC"]:
return False

for receiver in receivers["unique_data"]:
if receiver["receiver_email"] == target_content["To"]:
receiver_name = receiver["receiver_name"]

if (
"no-separator" in target
and mail_config["Subject"] != target_content["Subject"]
):
return False

if "with-separator" in target:
subject = " - ".join((mail_config["Subject"], receiver_name))
if subject != target_content["Subject"]:
return False

if not is_attachment_expected(target_content):
return False

return True


def is_attachment_expected(target_content):
for part in target_content.walk():
content_disposition = part.get("Content-Disposition", None)
if content_disposition:
dispositions = content_disposition.strip().split(";")
if bool(content_disposition and dispositions[0].lower() == "attachment"):
target_data = part.get_payload(decode=True)
with open(path_attachment, "rb") as fattachment:
base_data = fattachment.readlines()
data_str_target = target_data.decode("utf-8")
base_data_tmp = []

for line in base_data:
base_data_tmp.append(line.decode("utf-8"))
data_str_base = "".join(base_data_tmp)

if data_str_base != data_str_target:
return False

return True


def test_send_mail_no_separator_no_attachment(all_mails_base_no_separator):
runner = CliRunner()
result = runner.invoke(
main,
[
"--debug",
"--mails_path",
path_pre_rendered_mails_no_separator,
path_mail_config,
],
input="y\nusername\npassword\n",
)

targets = get_all_mail_names_from_path(all_mails_base_no_separator)

assert result.exit_code == 0
assert compare_on_sending_mail_all(
targets, target_prefix="/tmp/mail_handler/no-separator"
)


def test_send_mail_no_separator_with_attachment(all_mails_base_no_separator):
runner = CliRunner()
result = runner.invoke(
main,
[
"--debug",
"--mails_path",
path_pre_rendered_mails_no_separator,
"--attachment_file",
path_attachment,
path_mail_config,
],
input="y\nusername\npassword\n",
)

targets = get_all_mail_names_from_path(all_mails_base_no_separator)

assert result.exit_code == 0
assert compare_on_sending_mail_all(
targets, target_prefix="/tmp/mail_handler/no-separator"
)


def test_send_mail_with_separator_dash_no_attachment(all_mails_base_with_separator):
separator = " - "

runner = CliRunner()
result = runner.invoke(
main,
[
"--debug",
"--separator",
separator,
"--mails_path",
path_pre_rendered_mails_with_separator,
path_mail_config,
],
input="y\nusername\npassword\n",
)

targets = get_all_mail_names_from_path(all_mails_base_with_separator)

assert result.exit_code == 0
assert compare_on_sending_mail_all(
targets, target_prefix="/tmp/mail_handler/with-separator", separator=separator
)


def test_send_mail_with_separator_dash_with_attachment(all_mails_base_with_separator):
separator = " - "

runner = CliRunner()
result = runner.invoke(
main,
[
"--debug",
"--separator",
separator,
"--mails_path",
path_pre_rendered_mails_with_separator,
"--attachment_file",
path_attachment,
path_mail_config,
],
input="y\nusername\npassword\n",
)

targets = get_all_mail_names_from_path(all_mails_base_with_separator)

assert result.exit_code == 0
assert compare_on_sending_mail_all(
targets, target_prefix="/tmp/mail_handler/with-separator", separator=separator
)

0 comments on commit 3b0a1f3

Please sign in to comment.