-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtest_unsilencer.py
117 lines (85 loc) · 4.28 KB
/
test_unsilencer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import pytest # type: ignore
import requests
import responses # type: ignore
import unsilencer
# There is likely a better way to use mocker to supply return values
class MockSuccessResponse(requests.Response):
def __init__(self):
self.status_code = 200
def test_validate_email_valid():
assert unsilencer.validate_email("[email protected]") is True
def test_validate_required_settings_succeeds_when_set():
# The defaults we use with pytest-env and setup.cfg set the
# environment variables for all test suites
assert unsilencer.validate_settings() is True
def test_validate_required_settings_fails_when_unset(monkeypatch):
# As the constants are resolved during module import, reset them to None,
# which is the same as if the env var wasn't set in the first place.
monkeypatch.setattr("unsilencer.MAILGUN_API_KEY", None)
monkeypatch.setattr("unsilencer.MAILGUN_DOMAIN_NAME", None)
assert unsilencer.validate_settings() is False
def test_validate_email_invalid():
assert unsilencer.validate_email("foo") is False
assert unsilencer.validate_email("foo@bar") is False
assert unsilencer.validate_email("bar.com") is False
def test_check_if_listed_returns_empty_list_when_not_found(mocker):
mocked_check = mocker.patch("unsilencer._check_suppression_list")
lists = unsilencer.check_if_listed("[email protected]")
assert lists == []
assert mocked_check.call_count == 3
def test_check_if_listed_returns_populated_list_when_found(mocker):
mocked_check = mocker.patch(
"unsilencer._check_suppression_list", return_value=MockSuccessResponse()
)
lists = unsilencer.check_if_listed("[email protected]")
assert sorted(lists) == ["bounces", "complaints", "unsubscribes"]
assert mocked_check.call_count == 3
def test_remove_from_list_reports_failure(mocker, capsys):
mocked_remove = mocker.patch("unsilencer._remove_email_from_list")
unsilencer.remove_from_list("a-list", "[email protected]")
assert mocked_remove.call_count == 1
captured = capsys.readouterr()
assert captured.out == "Had trouble removing [email protected] from a-list\n"
def test_remove_from_list_reports_success(mocker, capsys):
mocked_remove = mocker.patch(
"unsilencer._remove_email_from_list", return_value=MockSuccessResponse()
)
unsilencer.remove_from_list("a-list", "[email protected]")
assert mocked_remove.call_count == 1
captured = capsys.readouterr()
assert captured.out == "[email protected] removed from a-list\n"
def test_unsilencer_exits_when_email_is_invalid(mocker, capsys):
mocker.patch("unsilencer.validate_email", return_value=False)
with pytest.raises(SystemExit) as pytest_wrapped_e:
unsilencer.unsilence("invalid-email")
captured = capsys.readouterr()
assert (
captured.out == "The input does not appear to be a valid email address, bye!\n"
)
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
def test_unsilencer_reports_when_not_found(mocker, capsys):
mocker.patch("unsilencer.validate_email", return_value=True)
mocker.patch("unsilencer.check_if_listed", return_value=[])
unsilencer.unsilence("[email protected]")
captured = capsys.readouterr()
assert captured.out == "[email protected] does not appear on any suppression list.\n"
def test_unsilencer_reports_when_found(mocker, capsys):
mocker.patch("unsilencer.validate_email", return_value=True)
mocker.patch("unsilencer.check_if_listed", return_value=["bounces", "complaints"])
mocker.patch("unsilencer.remove_from_list")
unsilencer.unsilence("[email protected]")
captured = capsys.readouterr()
assert (
captured.out == "Email address: [email protected] is listed on these lists:\n"
"\tbounces,complaints\n"
"Removing user from list now!!\n"
)
# I know it's an antipattern to test private methods, but wanted to leave this
# example here to demonstrate the ability of testing a remote API without
# making a network call, and if the method ever changes the return value,
# this test case should also be changed or removed.
def test_check_suppression_list_for_complaint_exists():
responses.add(responses.GET, f"{unsilencer.MAILGUN_API_URL}/complaints/[email protected]")
resp = unsilencer._check_suppression_list("complaints", "[email protected]")
assert resp.status_code == 200