Skip to content

Commit 425b35e

Browse files
Fred PhillipsFred Phillips
authored andcommitted
Add more appropriate unit tests
- 100% coverage - no lint errors from flake8 Signed-off-by: Fred Phillips <[email protected]>
1 parent 650f09d commit 425b35e

File tree

4 files changed

+128
-7
lines changed

4 files changed

+128
-7
lines changed

github_webhook/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
:license: Apache License, Version 2.0
99
"""
1010

11-
from github_webhook.webhook import Webhook
11+
from github_webhook.webhook import Webhook # noqa
1212

1313
# -----------------------------------------------------------------------------
1414
# Copyright 2015 Bloomberg Finance L.P.

github_webhook/webhook.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def _postreceive(self):
7474

7575
return '', 204
7676

77+
7778
def _get_header(key):
7879
"""Return message header"""
7980

@@ -82,6 +83,7 @@ def _get_header(key):
8283
except KeyError:
8384
abort(400, 'Missing header: ' + key)
8485

86+
8587
EVENT_DESCRIPTIONS = {
8688
'commit_comment': '{comment[user][login]} commented on '
8789
'{comment[commit_id]} in {repository[full_name]}',
@@ -110,7 +112,8 @@ def _get_header(key):
110112
'public': '{sender[login]} publicized {repository[full_name]}',
111113
'pull_request': '{sender[login]} {action} pull #{pull_request[number]} in '
112114
'{repository[full_name]}',
113-
'pull_request_review': '{sender[login]} {action} {review[state]} review on pull #{pull_request[number]} in '
115+
'pull_request_review': '{sender[login]} {action} {review[state]} '
116+
'review on pull #{pull_request[number]} in '
114117
'{repository[full_name]}',
115118
'pull_request_review_comment': '{comment[user][login]} {action} comment '
116119
'on pull #{pull_request[number]} in '
@@ -128,6 +131,7 @@ def _get_header(key):
128131
'{repository[full_name]}'
129132
}
130133

134+
131135
def _format_event(event_type, data):
132136
try:
133137
return EVENT_DESCRIPTIONS[event_type].format(**data)

tests/test_webhook.py

Lines changed: 113 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,51 @@
22

33
from __future__ import print_function
44

5+
import pytest
6+
import werkzeug
57
try:
6-
from unittest.mock import Mock
8+
from unittest import mock
79
except ImportError:
8-
from mock import Mock
10+
import mock
911

1012
from github_webhook.webhook import Webhook
1113

1214

15+
@pytest.fixture
16+
def mock_request():
17+
with mock.patch("github_webhook.webhook.request") as req:
18+
req.headers = {
19+
"X-Github-Delivery": ""
20+
}
21+
yield req
22+
23+
24+
@pytest.fixture
25+
def push_request(mock_request):
26+
mock_request.headers["X-Github-Event"] = "push"
27+
yield mock_request
28+
29+
30+
@pytest.fixture
31+
def app():
32+
yield mock.Mock()
33+
34+
35+
@pytest.fixture
36+
def webhook(app):
37+
yield Webhook(app)
38+
39+
40+
@pytest.fixture
41+
def handler(webhook):
42+
handler = mock.Mock()
43+
webhook.hook()(handler)
44+
yield handler
45+
46+
1347
def test_constructor():
1448
# GIVEN
15-
app = Mock()
49+
app = mock.Mock()
1650

1751
# WHEN
1852
webhook = Webhook(app)
@@ -24,6 +58,82 @@ def test_constructor():
2458
view_func=webhook._postreceive,
2559
methods=['POST'])
2660

61+
62+
def test_run_push_hook(webhook, handler, push_request):
63+
# WHEN
64+
webhook._postreceive()
65+
66+
# THEN
67+
handler.assert_called_once_with(push_request.get_json.return_value)
68+
69+
70+
def test_do_not_run_push_hook_on_ping(webhook, handler, mock_request):
71+
# GIVEN
72+
mock_request.headers["X-Github-Event"] = "ping"
73+
74+
# WHEN
75+
webhook._postreceive()
76+
77+
# THEN
78+
handler.assert_not_called()
79+
80+
81+
def test_can_handle_zero_events(webhook, push_request):
82+
# WHEN, THEN
83+
webhook._postreceive() # noop
84+
85+
86+
@pytest.mark.parametrize("secret", [
87+
u"secret",
88+
b"secret"
89+
])
90+
@mock.patch("github_webhook.webhook.hmac")
91+
def test_calls_if_signature_is_correct(mock_hmac, app, push_request, secret):
92+
# GIVEN
93+
webhook = Webhook(app, secret=secret)
94+
push_request.headers["X-Hub-Signature"] = "sha1=hash_of_something"
95+
push_request.data = b"something"
96+
handler = mock.Mock()
97+
mock_hmac.compare_digest.return_value = True
98+
99+
# WHEN
100+
webhook.hook()(handler)
101+
webhook._postreceive()
102+
103+
# THEN
104+
handler.assert_called_once_with(push_request.get_json.return_value)
105+
106+
107+
@mock.patch("github_webhook.webhook.hmac")
108+
def test_does_not_call_if_signature_is_incorrect(mock_hmac, app, push_request):
109+
# GIVEN
110+
webhook = Webhook(app, secret="super_secret")
111+
push_request.headers["X-Hub-Signature"] = "sha1=hash_of_something"
112+
push_request.data = b"something"
113+
handler = mock.Mock()
114+
mock_hmac.compare_digest.return_value = False
115+
116+
# WHEN, THEN
117+
webhook.hook()(handler)
118+
with pytest.raises(werkzeug.exceptions.BadRequest):
119+
webhook._postreceive()
120+
121+
122+
def test_request_has_no_data(webhook, handler, push_request):
123+
# GIVEN
124+
push_request.get_json.return_value = None
125+
126+
# WHEN, THEN
127+
with pytest.raises(werkzeug.exceptions.BadRequest):
128+
webhook._postreceive()
129+
130+
131+
def test_request_had_headers(webhook, handler, mock_request):
132+
# WHEN, THEN
133+
with pytest.raises(werkzeug.exceptions.BadRequest):
134+
webhook._postreceive()
135+
136+
27137
# -----------------------------------------------------------------------------
28138
# Copyright 2015 Bloomberg Finance L.P.
29139
#

tox.ini

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tox]
2-
envlist = py27,py36,pypy,pypy3
2+
envlist = py27,py36,pypy,pypy3,flake8
33

44
[testenv]
55
deps =
@@ -8,4 +8,11 @@ deps =
88
flask
99
six
1010
py{27,py}: mock
11-
commands = pytest -vl --cov=github_webhook --cov-report term-missing
11+
commands = pytest -vl --cov=github_webhook --cov-report term-missing --cov-fail-under 100
12+
13+
[testenv:flake8]
14+
deps = flake8
15+
commands = flake8 github_webhook
16+
17+
[flake8]
18+
max-line-length = 100

0 commit comments

Comments
 (0)