1
1
import asyncio
2
+ from collections .abc import Sequence
2
3
import json
3
- from typing import Optional , Tuple , Union
4
+ from typing import Mapping , Optional , Tuple
4
5
5
6
import pytest
6
7
@@ -12,18 +13,26 @@ class StandardTests:
12
13
loop : asyncio .AbstractEventLoop
13
14
14
15
async def amake_request (
15
- self , method : str , url : str , content : Union [bytes , None ] = None
16
- ) -> Tuple [int , Optional [bytes ]]:
16
+ self ,
17
+ method : str ,
18
+ url : str ,
19
+ content : Optional [bytes ] = None ,
20
+ headers : Optional [Sequence [tuple [str , str ]]] = None ,
21
+ ) -> Tuple [int , Optional [bytes ], Mapping [str , str ]]:
17
22
raise NotImplementedError (
18
23
"Sub-classes for async transports must implement `amake_request`"
19
24
)
20
25
21
26
def make_request (
22
- self , method : str , url : str , content : Union [bytes , None ] = None
23
- ) -> Tuple [int , Optional [bytes ]]:
27
+ self ,
28
+ method : str ,
29
+ url : str ,
30
+ content : Optional [bytes ] = None ,
31
+ headers : Optional [Sequence [tuple [str , str ]]] = None ,
32
+ ) -> Tuple [int , Optional [bytes ], Mapping [str , str ]]:
24
33
if self .is_async :
25
34
return self .loop .run_until_complete (
26
- self .amake_request (method , url , content )
35
+ self .amake_request (method , url , content , headers )
27
36
)
28
37
29
38
raise NotImplementedError ("Sub-classes must implement `make_request`" )
@@ -37,68 +46,127 @@ def _loop(self, request):
37
46
else :
38
47
yield
39
48
49
+ @pytest .fixture
50
+ def url_404 (self , httpbin ):
51
+ """404 httpbin URL.
52
+
53
+ Useful in tests if pook is configured to reply 200, and the status is checked.
54
+ If pook does not match the request (and if that was the intended behaviour)
55
+ then the 404 status code makes that obvious!"""
56
+ return f"{ httpbin .url } /status/404"
57
+
58
+ @pytest .fixture
59
+ def url_500 (self , httpbin ):
60
+ return f"{ httpbin .url } /status/500"
61
+
40
62
@pytest .mark .pook
41
- def test_activate_deactivate (self , httpbin ):
42
- url = f" { httpbin . url } /status/404 "
43
- pook .get (url ).reply (200 ).body ("hello from pook" )
63
+ def test_activate_deactivate (self , url_404 ):
64
+ """Deactivating pook allows requests to go through."" "
65
+ pook .get (url_404 ).reply (200 ).body ("hello from pook" )
44
66
45
- status , body = self .make_request ("GET" , url )
67
+ status , body , * _ = self .make_request ("GET" , url_404 )
46
68
47
69
assert status == 200
48
70
assert body == b"hello from pook"
49
71
50
72
pook .disable ()
51
73
52
- status , body = self .make_request ("GET" , url )
74
+ status , body , * _ = self .make_request ("GET" , url_404 )
53
75
54
76
assert status == 404
55
77
56
78
@pytest .mark .pook (allow_pending_mocks = True )
57
- def test_network_mode (self , httpbin ):
58
- upstream_url = f"{ httpbin .url } /status/500"
59
- mocked_url = f"{ httpbin .url } /status/404"
60
- pook .get (mocked_url ).reply (200 ).body ("hello from pook" )
79
+ def test_network_mode (self , url_404 , url_500 ):
80
+ """Enabling network mode allows requests to pass through even if no mock is matched."""
81
+ pook .get (url_404 ).reply (200 ).body ("hello from pook" )
61
82
pook .enable_network ()
62
83
63
84
# Avoid matching the mocks
64
- status , body = self .make_request ("POST" , upstream_url )
85
+ status , * _ = self .make_request ("POST" , url_500 )
65
86
66
87
assert status == 500
67
88
68
89
@pytest .mark .pook
69
- def test_json_request (self , httpbin ):
70
- url = f" { httpbin . url } /status/404 "
90
+ def test_json_request (self , url_404 ):
91
+ """JSON request bodies are correctly matched."" "
71
92
json_request = {"hello" : "json-request" }
72
- pook .get (url ).json (json_request ).reply (200 ).body ("hello from pook" )
93
+ pook .get (url_404 ).json (json_request ).reply (200 ).body ("hello from pook" )
73
94
74
- status , body = self .make_request ("GET" , url , json .dumps (json_request ).encode ())
95
+ status , body , * _ = self .make_request (
96
+ "GET" , url_404 , json .dumps (json_request ).encode ()
97
+ )
75
98
76
99
assert status == 200
77
100
assert body == b"hello from pook"
78
101
79
102
@pytest .mark .pook
80
- def test_json_response (self , httpbin ):
81
- url = f" { httpbin . url } /status/404 "
103
+ def test_json_response (self , url_404 ):
104
+ """JSON responses are correctly mocked."" "
82
105
json_response = {"hello" : "json-request" }
83
- pook .get (url ).reply (200 ).json (json_response )
106
+ pook .get (url_404 ).reply (200 ).json (json_response )
84
107
85
- status , body = self .make_request ("GET" , url )
108
+ status , body , * _ = self .make_request ("GET" , url_404 )
86
109
87
110
assert status == 200
88
111
assert body
89
112
assert json .loads (body ) == json_response
90
113
91
114
@pytest .mark .pook
92
- def test_json_request_and_response (self , httpbin ):
93
- url = f" { httpbin . url } /status/404 "
115
+ def test_json_request_and_response (self , url_404 ):
116
+ """JSON requests and responses do not interfere with each other."" "
94
117
json_request = {"id" : "123abc" }
95
118
json_response = {"title" : "123abc title" }
96
- pook .get (url ).json (json_request ).reply (200 ).json (json_response )
119
+ pook .get (url_404 ).json (json_request ).reply (200 ).json (json_response )
97
120
98
- status , body = self .make_request (
99
- "GET" , url , content = json .dumps (json_request ).encode ()
121
+ status , body , * _ = self .make_request (
122
+ "GET" , url_404 , content = json .dumps (json_request ).encode ()
100
123
)
101
124
102
125
assert status == 200
103
126
assert body
104
127
assert json .loads (body ) == json_response
128
+
129
+ @pytest .mark .pook
130
+ def test_header_sent (self , url_404 ):
131
+ """Sent headers can be matched."""
132
+ headers = [("x-hello" , "from pook" )]
133
+ pook .get (url_404 ).header ("x-hello" , "from pook" ).reply (200 ).body (
134
+ "hello from pook"
135
+ )
136
+
137
+ status , body , _ = self .make_request ("GET" , url_404 , headers = headers )
138
+
139
+ assert status == 200
140
+ assert body == b"hello from pook"
141
+
142
+ @pytest .mark .pook
143
+ def test_mocked_resposne_headers (self , url_404 ):
144
+ """Mocked response headers are appropriately returned."""
145
+ pook .get (url_404 ).reply (200 ).header ("x-hello" , "from pook" )
146
+
147
+ status , _ , headers = self .make_request ("GET" , url_404 )
148
+
149
+ assert status == 200
150
+ assert headers ["x-hello" ] == "from pook"
151
+
152
+ @pytest .mark .pook
153
+ def test_mutli_value_headers (self , url_404 ):
154
+ """Multi-value headers can be matched."""
155
+ match_headers = [("x-hello" , "from pook" ), ("x-hello" , "another time" )]
156
+ pook .get (url_404 ).header ("x-hello" , "from pook, another time" ).reply (200 )
157
+
158
+ status , * _ = self .make_request ("GET" , url_404 , headers = match_headers )
159
+
160
+ assert status == 200
161
+
162
+ @pytest .mark .pook
163
+ def test_mutli_value_response_headers (self , url_404 ):
164
+ """Multi-value response headers can be mocked."""
165
+ pook .get (url_404 ).reply (200 ).header ("x-hello" , "from pook" ).header (
166
+ "x-hello" , "another time"
167
+ )
168
+
169
+ status , _ , headers = self .make_request ("GET" , url_404 )
170
+
171
+ assert status == 200
172
+ assert headers ["x-hello" ] == "from pook, another time"
0 commit comments