Skip to content

Commit a03bbcd

Browse files
authored
Merge pull request #50 from cloudblue/improve_mocker
Add body match feature, fix responses version
2 parents e181205 + 451b656 commit a03bbcd

File tree

7 files changed

+163
-34
lines changed

7 files changed

+163
-34
lines changed

connect/client/testing/fluent.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
#
44
# Copyright (c) 2021 Ingram Micro. All Rights Reserved.
55
#
6+
import json
7+
68
import httpx
79

810
import responses
11+
from responses import matchers
912

1013
from pytest import MonkeyPatch
1114

@@ -16,6 +19,22 @@
1619
from connect.client.testing.models import CollectionMock, NSMock
1720

1821

22+
def body_matcher(body):
23+
def match(request):
24+
request_body = request.body
25+
valid = (
26+
body is None
27+
if request_body is None
28+
else body == request_body
29+
)
30+
if not valid:
31+
return False, "%s doesn't match %s" % (request_body, body)
32+
33+
return valid, ""
34+
35+
return match
36+
37+
1938
class ConnectClientMocker(_ConnectClientBase):
2039
def __init__(self, base_url):
2140
super().__init__('api_key', endpoint=base_url)
@@ -42,6 +61,7 @@ def create(
4261
status_code=201,
4362
return_value=None,
4463
headers=None,
64+
match_body=None,
4565
):
4666

4767
return self.mock(
@@ -50,6 +70,7 @@ def create(
5070
status_code=status_code,
5171
return_value=return_value,
5272
headers=headers,
73+
match_body=match_body,
5374
)
5475

5576
def update(
@@ -58,6 +79,7 @@ def update(
5879
status_code=201,
5980
return_value=None,
6081
headers=None,
82+
match_body=None,
6183
):
6284

6385
return self.mock(
@@ -66,6 +88,7 @@ def update(
6688
status_code=status_code,
6789
return_value=return_value,
6890
headers=headers,
91+
match_body=match_body,
6992
)
7093

7194
def delete(
@@ -74,6 +97,7 @@ def delete(
7497
status_code=204,
7598
return_value=None,
7699
headers=None,
100+
match_body=None,
77101
):
78102

79103
return self.mock(
@@ -82,6 +106,7 @@ def delete(
82106
status_code=status_code,
83107
return_value=return_value,
84108
headers=headers,
109+
match_body=match_body,
85110
)
86111

87112
def mock(
@@ -91,6 +116,7 @@ def mock(
91116
status_code=200,
92117
return_value=None,
93118
headers=None,
119+
match_body=None,
94120
):
95121
url = f'{self.endpoint}/{path}'
96122

@@ -106,6 +132,16 @@ def mock(
106132
else:
107133
kwargs['body'] = return_value
108134

135+
if match_body:
136+
if isinstance(match_body, (dict, list, tuple)):
137+
kwargs['match'] = [
138+
matchers.json_params_matcher(match_body),
139+
]
140+
else:
141+
kwargs['match'] = [
142+
body_matcher(match_body),
143+
]
144+
109145
self._mocker.add(**kwargs)
110146

111147
def start(self):
@@ -160,6 +196,7 @@ def mock(
160196
status_code=200,
161197
return_value=None,
162198
headers=None,
199+
match_body=None,
163200
):
164201
url = f'{self.endpoint}/{path}'
165202

@@ -175,4 +212,10 @@ def mock(
175212
else:
176213
kwargs['content'] = return_value.encode() if return_value else None
177214

215+
if match_body:
216+
if isinstance(match_body, (dict, list, tuple)):
217+
kwargs['match_content'] = json.dumps(match_body).encode('utf-8')
218+
else:
219+
kwargs['match_content'] = match_body
220+
178221
self._mocker.add_response(**kwargs)

connect/client/testing/models/mixins.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,55 +11,63 @@ def create(
1111
status_code=201,
1212
return_value=None,
1313
headers=None,
14+
match_body=None,
1415
):
1516

1617
return self._client.create(
1718
self._path,
1819
status_code=status_code,
1920
return_value=return_value,
2021
headers=headers,
22+
match_body=match_body,
2123
)
2224

2325
def bulk_create(
2426
self,
2527
status_code=201,
2628
return_value=None,
2729
headers=None,
30+
match_body=None,
2831
):
2932

3033
return self._client.create(
3134
self._path,
3235
status_code=status_code,
3336
return_value=return_value,
3437
headers=headers,
38+
match_body=match_body,
3539
)
3640

3741
def bulk_update(
3842
self,
3943
status_code=200,
4044
return_value=None,
4145
headers=None,
46+
match_body=None,
4247
):
4348

4449
return self._client.update(
4550
self._path,
4651
status_code=status_code,
4752
return_value=return_value,
4853
headers=headers,
54+
match_body=match_body,
4955
)
5056

5157
def bulk_delete(
5258
self,
5359
status_code=204,
5460
return_value=None,
5561
headers=None,
62+
match_body=None,
5663
):
5764

5865
return self._client.delete(
5966
self._path,
6067
status_code=status_code,
6168
return_value=return_value,
6269
headers=headers,
70+
match_body=match_body,
6371
)
6472

6573

@@ -85,13 +93,15 @@ def update(
8593
status_code=200,
8694
return_value=None,
8795
headers=None,
96+
match_body=None,
8897
):
8998

9099
return self._client.update(
91100
self._path,
92101
status_code=status_code,
93102
return_value=return_value,
94103
headers=headers,
104+
match_body=match_body,
95105
)
96106

97107
def delete(
@@ -141,25 +151,29 @@ def post(
141151
status_code=200,
142152
return_value=None,
143153
headers=None,
154+
match_body=None,
144155
):
145156
return self._client.create(
146157
self._path,
147158
status_code=status_code,
148159
return_value=return_value,
149160
headers=headers,
161+
match_body=match_body,
150162
)
151163

152164
def put(
153165
self,
154166
status_code=200,
155167
return_value=None,
156168
headers=None,
169+
match_body=None,
157170
):
158171
return self._client.update(
159172
self._path,
160173
status_code=status_code,
161174
return_value=return_value,
162175
headers=headers,
176+
match_body=match_body,
163177
)
164178

165179
def delete(

connect/client/testing/models/resourceset.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ def __getitem__(self, key): # noqa: CCR001
2424

2525
return copy
2626

27-
def count(self, return_value=0, status_code=200):
27+
def count(self, return_value=0, status_code=200, headers=None):
28+
headers = headers or {}
2829
if self._count is None:
2930
request_kwargs = self._get_request_kwargs()
3031
url = self._build_full_url(
@@ -35,21 +36,19 @@ def count(self, return_value=0, status_code=200):
3536
if status_code == 200:
3637
if not isinstance(return_value, int):
3738
raise TypeError('return_value must be an integer')
39+
headers['Content-Range'] = f'items 0-0/{return_value}'
3840
self._client.get(
3941
url,
4042
return_value=[],
41-
headers={
42-
'Content-Range': f'items 0-0/{return_value}',
43-
},
43+
headers=headers,
4444
)
4545
self._count = return_value
4646
else:
47+
headers['Content-Range'] = f'items 0-0/{return_value}'
4748
self._client.get(
4849
url,
4950
status_code=status_code,
50-
headers={
51-
'Content-Range': f'items 0-0/{return_value}',
52-
},
51+
headers=headers,
5352
)
5453

5554
def first(self):
@@ -64,7 +63,6 @@ def mock(
6463
return_value=None,
6564
headers=None,
6665
):
67-
6866
if status_code != 200:
6967
request_kwargs = self._get_request_kwargs()
7068
url = self._build_full_url(
@@ -84,11 +82,11 @@ def mock(
8482
raise TypeError('return_value must be a list of objects')
8583

8684
if not self._slice:
87-
self._mock_iteration(return_value)
85+
self._mock_iteration(return_value, headers)
8886
else:
89-
self._mock_slicing(return_value)
87+
self._mock_slicing(return_value, headers)
9088

91-
def _mock_iteration(self, return_value):
89+
def _mock_iteration(self, return_value, extra_headers):
9290
request_kwargs = self._get_request_kwargs()
9391
total = len(return_value)
9492
self._count = 0
@@ -103,16 +101,17 @@ def pages_iterator():
103101
offset,
104102
request_kwargs['params'].get('search'),
105103
)
104+
headers = {'Content-Range': f'items {offset}-{offset + len(page) - 1}/{total}'}
105+
if extra_headers:
106+
headers.update(extra_headers)
106107
self._client.get(
107108
url,
108109
return_value=page,
109-
headers={
110-
'Content-Range': f'items {offset}-{offset + len(page) - 1}/{total}',
111-
},
110+
headers=headers,
112111
)
113112
self._count += len(page)
114113

115-
def _mock_slicing(self, return_value):
114+
def _mock_slicing(self, return_value, extra_headers):
116115
request_kwargs = self._get_request_kwargs()
117116
total = len(return_value)
118117
self._count = 0
@@ -139,12 +138,13 @@ def pages_iterator():
139138
offset,
140139
request_kwargs['params'].get('search'),
141140
)
141+
headers = {'Content-Range': f'items {offset}-{offset + len(page) - 1}/{total}'}
142+
if extra_headers:
143+
headers.update(extra_headers)
142144
self._client.get(
143145
url,
144146
return_value=page,
145-
headers={
146-
'Content-Range': f'items {offset}-{offset + len(page) - 1}/{total}',
147-
},
147+
headers=headers,
148148
)
149149
self._count += len(page)
150150

0 commit comments

Comments
 (0)