Skip to content

Commit 19a37fe

Browse files
committed
Remove mocket
1 parent d9cbc28 commit 19a37fe

File tree

4 files changed

+63
-57
lines changed

4 files changed

+63
-57
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ jobs:
1111

1212
strategy:
1313
matrix:
14-
# We don't test on Windows currently as it appears mocket may not
15-
# work there.
14+
# TODO: add windows-latest
1615
platform: [ubuntu-latest, macos-latest]
1716
python-version: [3.8, 3.9, "3.10", 3.11, 3.12]
1817

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ classifiers = [
3535

3636
[project.optional-dependencies]
3737
test = [
38-
"mocket>=3.12.8",
38+
"pytest-httpserver>=1.0.10",
3939
]
4040

4141
[tool.setuptools.package-data]

setup.cfg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ python =
1515

1616
[testenv:{py38,py39,py310,py311,py312}-test]
1717
deps =
18-
mocket
18+
pytest-httpserver
1919
pytest
2020

2121
commands = pytest tests
@@ -35,6 +35,8 @@ commands = flake8 minfraud
3535
[testenv:py312-mypy]
3636
deps =
3737
mypy
38+
pytest_httpserver
39+
pytest
3840
types-requests
3941
voluptuous-stubs
4042
commands = mypy minfraud tests

tests/test_webservice.py

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
import os
44
from io import open
55
from typing import Type, Union
6-
7-
# httpretty currently doesn't work, but mocket with the compat interface
8-
# does. See, e.g., https://github.com/gabrielfalcao/HTTPretty/issues/220
9-
from mocket.plugins.httpretty import httpretty, httprettified # type: ignore
6+
import pytest_httpserver
7+
import pytest
108

119
from minfraud.errors import (
1210
HTTPError,
@@ -25,8 +23,24 @@
2523
class BaseTest(unittest.TestCase):
2624
client_class: Union[Type[AsyncClient], Type[Client]] = Client
2725

26+
@pytest.fixture(autouse=True)
27+
def setup_httpserver(self, httpserver: pytest_httpserver.HTTPServer):
28+
self.httpserver = httpserver
29+
2830
def setUp(self):
2931
self.client = self.client_class(42, "abcdef123456")
32+
self.client._base_uri = self.httpserver.url_for("/") + "minfraud/v2.0"
33+
self.client._factors_uri = (
34+
self.httpserver.url_for("/") + "minfraud/v2.0/factors"
35+
)
36+
self.client._insights_uri = (
37+
self.httpserver.url_for("/") + "minfraud/v2.0/insights"
38+
)
39+
self.client._score_uri = self.httpserver.url_for("/") + "minfraud/v2.0/score"
40+
self.client._report_uri = (
41+
self.httpserver.url_for("/") + "minfraud/v2.0/transactions/report"
42+
)
43+
self.base_uri = self.client._base_uri
3044

3145
test_dir = os.path.join(os.path.dirname(__file__), "data")
3246
with open(os.path.join(test_dir, self.request_file), encoding="utf-8") as file:
@@ -36,9 +50,6 @@ def setUp(self):
3650
with open(os.path.join(test_dir, self.response_file), encoding="utf-8") as file:
3751
self.response = file.read()
3852

39-
base_uri = "https://minfraud.maxmind.com/minfraud/v2.0"
40-
41-
@httprettified
4253
def test_invalid_auth(self):
4354
for error in (
4455
"ACCOUNT_ID_REQUIRED",
@@ -52,27 +63,23 @@ def test_invalid_auth(self):
5263
status_code=401,
5364
)
5465

55-
@httprettified
5666
def test_invalid_request(self):
5767
with self.assertRaisesRegex(InvalidRequestError, "IP invalid"):
5868
self.create_error(text='{"code":"IP_ADDRESS_INVALID","error":"IP invalid"}')
5969

60-
@httprettified
6170
def test_300_error(self):
6271
with self.assertRaisesRegex(
6372
HTTPError, r"Received an unexpected HTTP status \(300\) for"
6473
):
6574
self.create_error(status_code=300)
6675

67-
@httprettified
6876
def test_permission_required(self):
6977
with self.assertRaisesRegex(PermissionRequiredError, "permission"):
7078
self.create_error(
7179
text='{"code":"PERMISSION_REQUIRED","error":"permission required"}',
7280
status_code=403,
7381
)
7482

75-
@httprettified
7683
def test_400_with_invalid_json(self):
7784
with self.assertRaisesRegex(
7885
HTTPError,
@@ -81,19 +88,16 @@ def test_400_with_invalid_json(self):
8188
):
8289
self.create_error(text="{blah}")
8390

84-
@httprettified
8591
def test_400_with_no_body(self):
8692
with self.assertRaisesRegex(HTTPError, "Received a 400 error with no body"):
8793
self.create_error()
8894

89-
@httprettified
9095
def test_400_with_unexpected_content_type(self):
9196
with self.assertRaisesRegex(
9297
HTTPError, "Received a 400 with the following body: b?'?plain'?"
9398
):
9499
self.create_error(content_type="text/plain", text="plain")
95100

96-
@httprettified
97101
def test_400_without_json_body(self):
98102
with self.assertRaisesRegex(
99103
HTTPError,
@@ -102,7 +106,6 @@ def test_400_without_json_body(self):
102106
):
103107
self.create_error(text="plain")
104108

105-
@httprettified
106109
def test_400_with_unexpected_json(self):
107110
with self.assertRaisesRegex(
108111
HTTPError,
@@ -111,55 +114,53 @@ def test_400_with_unexpected_json(self):
111114
):
112115
self.create_error(text='{"not":"expected"}')
113116

114-
@httprettified
115117
def test_500_error(self):
116118
with self.assertRaisesRegex(HTTPError, r"Received a server error \(500\) for"):
117119
self.create_error(status_code=500)
118120

119121
def create_error(self, status_code=400, text="", content_type=None):
120122
uri = "/".join(
121-
[self.base_uri, "transactions", "report"]
123+
["/minfraud/v2.0", "transactions", "report"]
122124
if self.type == "report"
123-
else [self.base_uri, self.type]
125+
else ["/minfraud/v2.0", self.type]
124126
)
125127
if content_type is None:
126128
content_type = (
127129
"application/json"
128130
if self.type == "report"
129131
else "application/vnd.maxmind.com-error+json; charset=UTF-8; version=2.0"
130132
)
131-
httpretty.register_uri(
132-
httpretty.POST,
133-
uri=uri,
134-
status=status_code,
135-
body=text,
133+
self.httpserver.expect_request(uri, method="POST").respond_with_data(
134+
text,
136135
content_type=content_type,
136+
status=status_code,
137137
)
138138
return self.run_client(getattr(self.client, self.type)(self.full_request))
139139

140140
def create_success(self, text=None, client=None, request=None):
141141
uri = "/".join(
142-
[self.base_uri, "transactions", "report"]
142+
["/minfraud/v2.0", "transactions", "report"]
143143
if self.type == "report"
144-
else [self.base_uri, self.type]
144+
else ["/minfraud/v2.0", self.type]
145145
)
146-
httpretty.register_uri(
147-
httpretty.POST,
148-
uri=uri,
149-
status=204 if self.type == "report" else 200,
150-
body=self.response if text is None else text,
146+
if request is None:
147+
request = self.full_request
148+
149+
response = self.response if text is None else text
150+
status = 204 if self.type == "report" else 200
151+
self.httpserver.expect_request(uri, method="POST").respond_with_data(
152+
response,
151153
content_type=f"application/vnd.maxmind.com-minfraud-{self.type}+json; charset=UTF-8; version=2.0",
154+
status=status,
152155
)
153156
if client is None:
154157
client = self.client
155-
if request is None:
156-
request = self.full_request
158+
157159
return self.run_client(getattr(client, self.type)(request))
158160

159161
def run_client(self, v):
160162
return v
161163

162-
@httprettified
163164
def test_named_constructor_args(self):
164165
id = "47"
165166
key = "1234567890ab"
@@ -170,7 +171,6 @@ def test_named_constructor_args(self):
170171
self.assertEqual(client._account_id, id)
171172
self.assertEqual(client._license_key, key)
172173

173-
@httprettified
174174
def test_missing_constructor_args(self):
175175
with self.assertRaises(TypeError):
176176
self.client_class(license_key="1234567890ab")
@@ -180,10 +180,10 @@ def test_missing_constructor_args(self):
180180

181181

182182
class BaseTransactionTest(BaseTest):
183+
183184
def has_ip_location(self):
184185
return self.type in ["factors", "insights"]
185186

186-
@httprettified
187187
def test_200(self):
188188
model = self.create_success()
189189
response = json.loads(self.response)
@@ -197,7 +197,6 @@ def test_200(self):
197197
self.assertEqual("004", model.ip_address.traits.mobile_network_code)
198198
self.assertEqual("ANONYMOUS_IP", model.ip_address.risk_reasons[0].code)
199199

200-
@httprettified
201200
def test_200_on_request_with_nones(self):
202201
model = self.create_success(
203202
request={
@@ -215,20 +214,25 @@ def test_200_on_request_with_nones(self):
215214
response = self.response
216215
self.assertEqual(0.01, model.risk_score)
217216

218-
@httprettified
219217
def test_200_with_email_hashing(self):
220-
uri = "/".join([self.base_uri, self.type])
218+
uri = "/".join(["/minfraud/v2.0", self.type])
221219

222-
httpretty.register_uri(
223-
httpretty.POST,
224-
uri=uri,
225-
status=200,
226-
body=self.response,
227-
content_type=f"application/vnd.maxmind.com-minfraud-{self.type}+json; charset=UTF-8; version=2.0",
220+
last = None
221+
222+
def custom_handler(r):
223+
nonlocal last
224+
last = r
225+
return "hello world"
226+
227+
self.httpserver.expect_request(uri, method="POST").respond_with_handler(
228+
custom_handler
228229
)
229230

230231
request = {"email": {"address": "[email protected]"}}
231-
self.run_client(getattr(self.client, self.type)(request, hash_email=True))
232+
try:
233+
self.run_client(getattr(self.client, self.type)(request, hash_email=True))
234+
except Exception as e:
235+
pass
232236

233237
self.assertEqual(
234238
{
@@ -237,14 +241,21 @@ def test_200_with_email_hashing(self):
237241
"domain": "maxmind.com",
238242
}
239243
},
240-
json.loads(httpretty.last_request.body),
244+
json.loads(last.data.decode("utf-8")),
241245
)
242246

243247
# This was fixed in https://github.com/maxmind/minfraud-api-python/pull/78
244-
@httprettified
248+
245249
def test_200_with_locales(self):
246250
locales = ("fr",)
247251
client = self.client_class(42, "abcdef123456", locales=locales)
252+
client._base_uri = self.httpserver.url_for("/") + "minfraud/v2.0"
253+
client._factors_uri = self.httpserver.url_for("/") + "minfraud/v2.0/factors"
254+
client._insights_uri = self.httpserver.url_for("/") + "minfraud/v2.0/insights"
255+
client._score_uri = self.httpserver.url_for("/") + "minfraud/v2.0/score"
256+
client._report_uri = (
257+
self.httpserver.url_for("/") + "minfraud/v2.0/transactions/report"
258+
)
248259
model = self.create_success(client=client)
249260
response = json.loads(self.response)
250261
if self.has_ip_location():
@@ -254,7 +265,6 @@ def test_200_with_locales(self):
254265
self.assertEqual("Royaume-Uni", model.ip_address.country.name)
255266
self.assertEqual("Londres", model.ip_address.city.name)
256267

257-
@httprettified
258268
def test_200_with_reserved_ip_warning(self):
259269
model = self.create_success(
260270
"""
@@ -275,7 +285,6 @@ def test_200_with_reserved_ip_warning(self):
275285

276286
self.assertEqual(12, model.risk_score)
277287

278-
@httprettified
279288
def test_200_with_no_body(self):
280289
with self.assertRaisesRegex(
281290
MinFraudError,
@@ -284,7 +293,6 @@ def test_200_with_no_body(self):
284293
):
285294
self.create_success(text="")
286295

287-
@httprettified
288296
def test_200_with_invalid_json(self):
289297
with self.assertRaisesRegex(
290298
MinFraudError,
@@ -293,7 +301,6 @@ def test_200_with_invalid_json(self):
293301
):
294302
self.create_success(text="{")
295303

296-
@httprettified
297304
def test_insufficient_funds(self):
298305
with self.assertRaisesRegex(InsufficientFundsError, "out of funds"):
299306
self.create_error(
@@ -328,11 +335,9 @@ class TestReportTransaction(BaseTest):
328335
request_file = "full-report-request.json"
329336
response_file = "report-response.json"
330337

331-
@httprettified
332338
def test_204(self):
333339
self.create_success()
334340

335-
@httprettified
336341
def test_204_on_request_with_nones(self):
337342
self.create_success(
338343
request={

0 commit comments

Comments
 (0)