22
33from __future__ import print_function
44
5+ import pytest
6+ import werkzeug
57try :
6- from unittest . mock import Mock
8+ from unittest import mock
79except ImportError :
8- from mock import Mock
10+ import mock
911
1012from 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+
1347def 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#
0 commit comments