diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2e19564..ee9075b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ repos: - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 22.10.0 hooks: - id: black \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cd98be..453c2e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.21.2] - 2022-11-03 +### Fixed +- URL containing non ASCII characters in query can now be matched. +- Requests are now cleared when calling `httpx_mock.reset`. + ## [0.21.1] - 2022-10-20 ### Fixed - `httpx_mock.add_callback` now handles async callbacks. @@ -227,7 +232,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - First release, should be considered as unstable for now as design might change. -[Unreleased]: https://github.com/Colin-b/pytest_httpx/compare/v0.21.1...HEAD +[Unreleased]: https://github.com/Colin-b/pytest_httpx/compare/v0.21.2...HEAD +[0.21.2]: https://github.com/Colin-b/pytest_httpx/compare/v0.21.1...v0.21.2 [0.21.1]: https://github.com/Colin-b/pytest_httpx/compare/v0.21.0...v0.21.1 [0.21.0]: https://github.com/Colin-b/pytest_httpx/compare/v0.20.0...v0.21.0 [0.20.0]: https://github.com/Colin-b/pytest_httpx/compare/v0.19.0...v0.20.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8d27041..6dabc47 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,7 +56,7 @@ Before creating an issue please make sure that it was not already reported. 1) Go to the *Pull requests* tab and click on the *New pull request* button. 2) *base* should always be set to `develop` and it should be compared to your branch. 3) Title should be a small sentence describing the request. -3) The comment should contain as much information as possible +4) The comment should contain as much information as possible * Actual behavior (before the new code) * Expected behavior (with the new code) * Steps to reproduce (with and without the new code to see the difference) diff --git a/README.md b/README.md index 6921a5d..20d81c3 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Build status Coverage Code style: black -Number of tests +Number of tests Number of downloads

diff --git a/pytest_httpx/_httpx_mock.py b/pytest_httpx/_httpx_mock.py index 7f3c5c7..115f8d3 100644 --- a/pytest_httpx/_httpx_mock.py +++ b/pytest_httpx/_httpx_mock.py @@ -1,15 +1,11 @@ import inspect import re from typing import List, Union, Optional, Callable, Tuple, Pattern, Any, Dict, Awaitable -from urllib.parse import parse_qs import httpx from pytest_httpx import _httpx_internals -# re.Pattern was introduced in Python 3.7 -pattern_type = re._pattern_type if hasattr(re, "_pattern_type") else re.Pattern - class _RequestMatcher: def __init__( @@ -37,18 +33,18 @@ def _url_match(self, request: httpx.Request) -> bool: if not self.url: return True - if isinstance(self.url, pattern_type): + if isinstance(self.url, re.Pattern): return self.url.match(str(request.url)) is not None # Compare query parameters apart as order of parameters should not matter - request_qs = parse_qs(request.url.query) - qs = parse_qs(self.url.query) + request_params = dict(request.url.params) + params = dict(self.url.params) # Remove the query parameters from the original URL to compare everything besides query parameters request_url = request.url.copy_with(query=None) url = self.url.copy_with(query=None) - return (request_qs == qs) and (url == request_url) + return (request_params == params) and (url == request_url) def _method_match(self, request: httpx.Request) -> bool: if not self.method: @@ -304,6 +300,7 @@ def get_request(self, **matchers) -> Optional[httpx.Request]: return requests[0] if requests else None def reset(self, assert_all_responses_were_requested: bool) -> None: + self._requests.clear() not_called = self._reset_callbacks() if assert_all_responses_were_requested: diff --git a/pytest_httpx/version.py b/pytest_httpx/version.py index 5e3dfb3..10972d9 100644 --- a/pytest_httpx/version.py +++ b/pytest_httpx/version.py @@ -3,4 +3,4 @@ # Major should be incremented in case there is a breaking change. (eg: 2.5.8 -> 3.0.0) # Minor should be incremented in case there is an enhancement. (eg: 2.5.8 -> 2.6.0) # Patch should be incremented in case there is a bug fix. (eg: 2.5.8 -> 2.5.9) -__version__ = "0.21.1" +__version__ = "0.21.2" diff --git a/setup.py b/setup.py index 24d780e..c1d523e 100644 --- a/setup.py +++ b/setup.py @@ -44,9 +44,9 @@ extras_require={ "testing": [ # Used to run async test functions - "pytest-asyncio==0.17.*", + "pytest-asyncio==0.20.*", # Used to check coverage - "pytest-cov==3.*", + "pytest-cov==4.*", ] }, python_requires=">=3.7", diff --git a/tests/test_httpx_async.py b/tests/test_httpx_async.py index ef5d0cb..5f9f8a4 100644 --- a/tests/test_httpx_async.py +++ b/tests/test_httpx_async.py @@ -1669,3 +1669,33 @@ async def custom_response(request: httpx.Request) -> httpx.Response: async with httpx.AsyncClient() as client: response = await client.get("https://test_url") assert response.elapsed is not None + + +@pytest.mark.asyncio +async def test_non_ascii_url_response(httpx_mock: HTTPXMock) -> None: + httpx_mock.add_response(url="https://test_url?query_type=数据") + + async with httpx.AsyncClient() as client: + response = await client.get("https://test_url?query_type=数据") + assert response.content == b"" + + +@pytest.mark.asyncio +async def test_url_encoded_matching_response(httpx_mock: HTTPXMock) -> None: + httpx_mock.add_response(url="https://test_url?a=%E6%95%B0%E6%8D%AE") + + async with httpx.AsyncClient() as client: + response = await client.get("https://test_url?a=数据") + assert response.content == b"" + + +@pytest.mark.asyncio +async def test_reset_is_removing_requests(httpx_mock: HTTPXMock) -> None: + httpx_mock.add_response() + async with httpx.AsyncClient() as client: + await client.get("https://test_url") + + assert len(httpx_mock.get_requests()) == 1 + + httpx_mock.reset(assert_all_responses_were_requested=False) + assert len(httpx_mock.get_requests()) == 0 diff --git a/tests/test_httpx_sync.py b/tests/test_httpx_sync.py index 1d59919..87661ce 100644 --- a/tests/test_httpx_sync.py +++ b/tests/test_httpx_sync.py @@ -1383,3 +1383,30 @@ def test_elapsed_when_add_callback(httpx_mock: HTTPXMock) -> None: with httpx.Client() as client: response = client.get("https://test_url") assert response.elapsed is not None + + +def test_non_ascii_url_response(httpx_mock: HTTPXMock) -> None: + httpx_mock.add_response(url="https://test_url?query_type=数据") + + with httpx.Client() as client: + response = client.get("https://test_url?query_type=数据") + assert response.content == b"" + + +def test_url_encoded_matching_response(httpx_mock: HTTPXMock) -> None: + httpx_mock.add_response(url="https://test_url?a=%E6%95%B0%E6%8D%AE") + + with httpx.Client() as client: + response = client.get("https://test_url?a=数据") + assert response.content == b"" + + +def test_reset_is_removing_requests(httpx_mock: HTTPXMock) -> None: + httpx_mock.add_response() + with httpx.Client() as client: + client.get("https://test_url") + + assert len(httpx_mock.get_requests()) == 1 + + httpx_mock.reset(assert_all_responses_were_requested=False) + assert len(httpx_mock.get_requests()) == 0