Skip to content
This repository has been archived by the owner on Feb 14, 2024. It is now read-only.

Commit

Permalink
Merge pull request #69 from cisagov/wip-pe-mailer-tests
Browse files Browse the repository at this point in the history
Add P&E Mailer tests for pe-mailer
  • Loading branch information
schmelz21 committed Oct 12, 2021
2 parents 9fc29ef + dc78243 commit 4eee505
Show file tree
Hide file tree
Showing 7 changed files with 633 additions and 7 deletions.
5 changes: 5 additions & 0 deletions src/pe_mailer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""The pe_mailer library."""
# We disable a Flake8 check for "Module imported but unused (F401)" here because
# although this import is not directly used, it populates the value
# package_name.__version__, which is used to get version information about this
# Python package.
from ._version import __version__ # noqa: F401

__all__ = ["email_reports", "message", "pe_message", "report_message", "stats_message"]
Binary file added tests/data/pdf-sample.pdf
Binary file not shown.
101 changes: 101 additions & 0 deletions tests/test_pe_mailer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""Tests for the pe-mailer module."""

# Standard Python Libraries
import logging
import sys
from unittest.mock import patch

# Third-Party Libraries
import pytest

# cisagov Libraries
import pe_mailer.email_reports

log_levels = (
"debug",
"info",
"warning",
"error",
"critical",
)

PROJECT_VERSION = pe_mailer.__version__


def test_mailer_stdout_version(capsys):
"""Verify that version string sent to stdout agrees with the module version."""
with pytest.raises(SystemExit):
with patch.object(sys, "argv", ["bogus", "--version"]):
pe_mailer.email_reports.main()
captured = capsys.readouterr()
assert (
captured.out == f"{PROJECT_VERSION}\n"
), "standard output by '--version' should agree with module.__version__"


def test_mailer_running_as_module(capsys):
"""Verify that the __main__.py file loads correctly."""
with pytest.raises(SystemExit):
with patch.object(sys, "argv", ["bogus", "--version"]):
# F401 is a "Module imported but unused" warning. This import
# emulates how this project would be run as a module. The only thing
# being done by __main__ is importing the main entrypoint of the
# package and running it, so there is nothing to use from this
# import. As a result, we can safely ignore this warning.
# cisagov Libraries
import pe_mailer.__main__ # noqa: F401
captured = capsys.readouterr()
assert (
captured.out == f"{PROJECT_VERSION}\n"
), "standard output by '--version' should agree with module.__version__"


@pytest.mark.parametrize("level", log_levels)
def test_mailer_log_levels(level):
"""Validate commandline log-level arguments."""
with patch.object(
sys,
"argv",
[
"pe-mailer",
"--pe-report-dir=/input",
"--db-creds-file=/creds",
f"--log-level={level}",
],
):
with patch.object(logging.root, "handlers", []):
assert (
logging.root.hasHandlers() is False
), "root logger should not have handlers yet"
return_code = None
try:
pe_mailer.email_reports.main()
except SystemExit as sys_exit:
return_code = sys_exit.code
assert (
logging.root.hasHandlers() is True
), "root logger should now have a handler"
assert (
logging.getLevelName(logging.root.getEffectiveLevel()) == level.upper()
), f"root logger level should be set to {level.upper()}"
assert return_code is None, "main() should return success"


def test_bad_log_level():
"""Validate bad log-level argument returns error."""
with patch.object(
sys,
"argv",
[
"pe_mailer",
"--pe-report-dir=/input",
"--db-creds-file=/creds",
"--log-level=emergency",
],
):
return_code = None
try:
pe_mailer.email_reports.main()
except SystemExit as sys_exit:
return_code = sys_exit.code
assert return_code == 1, "main() should exit with error"
97 changes: 97 additions & 0 deletions tests/test_pe_mailer_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
"""This module contains the tests for the Message class."""

# Standard Python Libraries
import unittest

# cisagov Libraries
from pe_mailer.pe_message import Message


class Test(unittest.TestCase):
"""The tests for the Message class."""

def test_one_param_single_recipient(self):
"""Test the 1-parameter version of the constructor."""
to = ["recipient@example.com"]

message = Message(to)

self.assertEqual(message["From"], "reports@cyber.dhs.gov")
self.assertEqual(message.get("CC"), None)
self.assertEqual(
message["BCC"], "cyhy_reports@hq.dhs.gov,reports@cyber.dhs.gov"
)
self.assertEqual(message["To"], "recipient@example.com")

def test_one_param_multiple_recipients(self):
"""Test the 1-parameter version of the constructor."""
to = ["recipient@example.com", "recipient2@example.com"]

message = Message(to)

self.assertEqual(message["From"], "reports@cyber.dhs.gov")
self.assertEqual(message.get("CC"), None)
self.assertEqual(
message["BCC"], "cyhy_reports@hq.dhs.gov,reports@cyber.dhs.gov"
)
self.assertEqual(message["To"], "recipient@example.com,recipient2@example.com")

def test_six_params_single_cc(self):
"""Test the 6-parameter version of the constructor."""
to = ["recipient@example.com", "recipient2@example.com"]
fm = "sender@example.com"
cc = ["cc@example.com"]
bcc = ["bcc@example.com"]
subject = "The subject"
text_body = "The plain-text body"
html_body = "<p>The HTML body</p>"

message = Message(
to, subject, text_body, html_body, from_addr=fm, cc_addrs=cc, bcc_addrs=bcc
)

self.assertEqual(message["From"], fm)
self.assertEqual(message["Subject"], subject)
self.assertEqual(message["CC"], "cc@example.com")
self.assertEqual(message["BCC"], "bcc@example.com")
self.assertEqual(message["To"], "recipient@example.com,recipient2@example.com")

# Make sure the correct body attachments were added
for part in message.walk():
# multipart/* are just containers
if part.get_content_type() == "text/plain":
self.assertEqual(part.get_payload(), text_body)
elif part.get_content_type() == "text/html":
self.assertEqual(part.get_payload(), html_body)

def test_six_params_multiple_cc(self):
"""Test the 6-parameter version of the constructor."""
to = ["recipient@example.com", "recipient2@example.com"]
fm = "sender@example.com"
cc = ["cc@example.com", "cc2@example.com"]
bcc = ["bcc@example.com", "bcc2@example.com"]
subject = "The subject"
text_body = "The plain-text body"
html_body = "<p>The HTML body</p>"

message = Message(
to, subject, text_body, html_body, from_addr=fm, cc_addrs=cc, bcc_addrs=bcc
)

self.assertEqual(message["From"], fm)
self.assertEqual(message["Subject"], subject)
self.assertEqual(message["CC"], "cc@example.com,cc2@example.com")
self.assertEqual(message["BCC"], "bcc@example.com,bcc2@example.com")
self.assertEqual(message["To"], "recipient@example.com,recipient2@example.com")

# Make sure the correct body attachments were added
for part in message.walk():
# multipart/* are just containers
if part.get_content_type() == "text/plain":
self.assertEqual(part.get_payload(), text_body)
elif part.get_content_type() == "text/html":
self.assertEqual(part.get_payload(), html_body)


if __name__ == "__main__":
unittest.main()

0 comments on commit 4eee505

Please sign in to comment.