diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4edd2b6..9eb1eca 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: forbid-crlf - id: remove-crlf - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -15,7 +15,7 @@ repos: exclude: helm/ args: [ --unsafe ] - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: "v0.11.11" + rev: "v0.12.10" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/Makefile b/Makefile index 3452a46..445a345 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ publish: clean install-test-requirements uv publish clean: - rm -rf *.egg-info dist/ requirements.txt uv.lock || true + rm -rf *.egg-info dist/ requirements.txt uv.lock coverage.xml || true find . -type d -name __pycache__ -exec rm -rf {} \; || true .PHONY: clean publish safetest test setup develop lint-python test-python _services-up diff --git a/mocket/mocks/mockhttp.py b/mocket/mocks/mockhttp.py index 3db6a65..da1163b 100644 --- a/mocket/mocks/mockhttp.py +++ b/mocket/mocks/mockhttp.py @@ -142,7 +142,9 @@ class Entry(MocketEntry): request_cls = Request response_cls = Response - def __init__(self, uri, method, responses, match_querystring=True): + default_config = {"match_querystring": True} + + def __init__(self, uri, method, responses, match_querystring: bool = True): uri = urlsplit(uri) port = uri.port @@ -151,7 +153,7 @@ def __init__(self, uri, method, responses, match_querystring=True): super().__init__((uri.hostname, port), responses) self.schema = uri.scheme - self.path = uri.path + self.path = uri.path or "/" self.query = uri.query self.method = method.upper() self._sent_data = b"" @@ -227,16 +229,15 @@ def register(cls, method, uri, *responses, **config): if "body" in config or "status" in config: raise AttributeError("Did you mean `Entry.single_register(...)`?") - default_config = dict(match_querystring=True, add_trailing_slash=True) - default_config.update(config) - config = default_config + if config.keys() - cls.default_config.keys(): + raise KeyError( + f"Invalid config keys: {config.keys() - cls.default_config.keys()}" + ) - if config["add_trailing_slash"] and not urlsplit(uri).path: - uri += "/" + _config = cls.default_config.copy() + _config.update({k: v for k, v in config.items() if k in _config}) - Mocket.register( - cls(uri, method, responses, match_querystring=config["match_querystring"]) - ) + Mocket.register(cls(uri, method, responses, **_config)) @classmethod def single_register( @@ -246,8 +247,9 @@ def single_register( body="", status=200, headers=None, - match_querystring=True, exception=None, + match_querystring=True, + **config, ): response = ( exception @@ -260,4 +262,5 @@ def single_register( uri, response, match_querystring=match_querystring, + **config, ) diff --git a/tests/test_http.py b/tests/test_http.py index afa3118..ab4057e 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -12,7 +12,7 @@ import requests from mocket import Mocket, Mocketizer, mocketize -from mocket.mockhttp import Entry, Response +from mocket.mocks.mockhttp import Entry, Response class HttpTestCase(TestCase): @@ -433,3 +433,25 @@ def test_suggestion_for_register_and_status(self): url, status=201, ) + + def test_invalid_config_key(self): + url = "http://foobar.com/path" + with self.assertRaises(KeyError): + Entry.register( + Entry.POST, + url, + Response(body='{"foo":"bar0"}', status=200), + invalid_key=True, + ) + + def test_add_trailing_slash(self): + url = "http://testme.org" + entry = Entry(url, "GET", [Response(body='{"foo":"bar0"}', status=200)]) + self.assertEqual(entry.path, "/") + + @mocketize + def test_mocket_with_no_path(self): + Entry.register(Entry.GET, "http://httpbin.local", Response(status=202)) + response = urlopen("http://httpbin.local/") + self.assertEqual(response.code, 202) + self.assertEqual(Mocket._entries[("httpbin.local", 80)][0].path, "/") diff --git a/tests/test_https.py b/tests/test_https.py index f8c8549..83bd38c 100644 --- a/tests/test_https.py +++ b/tests/test_https.py @@ -7,7 +7,7 @@ import requests from mocket import Mocket, Mocketizer, mocketize -from mocket.mockhttp import Entry +from mocket.mockhttp import Entry # noqa - test retrocompatibility @pytest.fixture @@ -43,6 +43,7 @@ def test_json(response): @pytest.mark.skipif('os.getenv("SKIP_TRUE_HTTP", False)') +@pytest.mark.xfail(reason="Service down or blocking GitHub actions IPs") def test_truesendall_with_recording_https(url_to_mock): with tempfile.TemporaryDirectory() as temp_dir, Mocketizer( truesocket_recording_dir=temp_dir @@ -62,6 +63,7 @@ def test_truesendall_with_recording_https(url_to_mock): @pytest.mark.skipif('os.getenv("SKIP_TRUE_HTTP", False)') +@pytest.mark.xfail(reason="Service down or blocking GitHub actions IPs") def test_truesendall_after_mocket_session(url_to_mock): Mocket.enable() Mocket.disable() @@ -71,6 +73,7 @@ def test_truesendall_after_mocket_session(url_to_mock): @pytest.mark.skipif('os.getenv("SKIP_TRUE_HTTP", False)') +@pytest.mark.xfail(reason="Service down or blocking GitHub actions IPs") def test_real_request_session(url_to_mock): session = requests.Session()