Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pytest-httpx for 
openSUSE:Factory checked in at 2023-01-17 17:35:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-httpx (Old)
 and      /work/SRC/openSUSE:Factory/.python-pytest-httpx.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pytest-httpx"

Tue Jan 17 17:35:27 2023 rev:4 rq:1058836 version:0.21.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pytest-httpx/python-pytest-httpx.changes  
2022-08-08 10:02:33.362376869 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-pytest-httpx.new.32243/python-pytest-httpx.changes
       2023-01-17 17:35:41.517312709 +0100
@@ -1,0 +2,10 @@
+Mon Jan 16 16:21:19 UTC 2023 - Daniel Garcia <daniel.gar...@suse.com>
+
+- Update to 0.21.2
+  * URL containing non ASCII characters in query can now be matched.
+  * Requests are now cleared when calling httpx_mock.reset.
+- 0.21.1
+  * httpx_mock.add_callback now handles async callbacks.
+- Unpin httpx and pytest in python metadata
+
+-------------------------------------------------------------------

Old:
----
  pytest_httpx-0.21.0-gh.tar.gz

New:
----
  pytest_httpx-0.21.2-gh.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pytest-httpx.spec ++++++
--- /var/tmp/diff_new_pack.qiI9eS/_old  2023-01-17 17:35:42.069315911 +0100
+++ /var/tmp/diff_new_pack.qiI9eS/_new  2023-01-17 17:35:42.073315935 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-pytest-httpx
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           python-pytest-httpx
-Version:        0.21.0
+Version:        0.21.2
 Release:        0
 Summary:        Send responses to httpx
 License:        MIT
@@ -29,7 +29,7 @@
 # SECTION test requirements
 BuildRequires:  %{python_module httpx >= 0.23.0}
 BuildRequires:  %{python_module pytest >= 6.0}
-BuildRequires:  %{python_module pytest-asyncio >= 0.14.0}
+BuildRequires:  %{python_module pytest-asyncio >= 0.20.0}
 # /SECTION
 BuildRequires:  fdupes
 Requires:       python-httpx >= 0.23.0
@@ -43,7 +43,8 @@
 %prep
 %setup -q -n pytest_httpx-%{version}
 # unpin exact version
-sed -i '/install_requires/ s/httpx==0./httpx>=0./' setup.py
+sed -i '/install_requires/ s/httpx==0.23.\*/httpx/' setup.py
+sed -i '/install_requires/ s/pytest>=6.*,<8.\*/pytest/' setup.py
 
 %build
 %python_build

++++++ pytest_httpx-0.21.0-gh.tar.gz -> pytest_httpx-0.21.2-gh.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpx-0.21.0/.pre-commit-config.yaml 
new/pytest_httpx-0.21.2/.pre-commit-config.yaml
--- old/pytest_httpx-0.21.0/.pre-commit-config.yaml     2022-05-24 
18:29:06.000000000 +0200
+++ new/pytest_httpx-0.21.2/.pre-commit-config.yaml     2022-11-03 
22:03:01.000000000 +0100
@@ -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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpx-0.21.0/CHANGELOG.md 
new/pytest_httpx-0.21.2/CHANGELOG.md
--- old/pytest_httpx-0.21.0/CHANGELOG.md        2022-05-24 18:29:06.000000000 
+0200
+++ new/pytest_httpx-0.21.2/CHANGELOG.md        2022-11-03 22:03:01.000000000 
+0100
@@ -6,6 +6,15 @@
 
 ## [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.
+
 ## [0.21.0] - 2022-05-24
 ### Changed
 - Requires [`httpx`](https://www.python-httpx.org)==0.23.\*
@@ -223,7 +232,9 @@
 ### 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.0...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
 [0.19.0]: https://github.com/Colin-b/pytest_httpx/compare/v0.18.0...v0.19.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpx-0.21.0/CONTRIBUTING.md 
new/pytest_httpx-0.21.2/CONTRIBUTING.md
--- old/pytest_httpx-0.21.0/CONTRIBUTING.md     2022-05-24 18:29:06.000000000 
+0200
+++ new/pytest_httpx-0.21.2/CONTRIBUTING.md     2022-11-03 22:03:01.000000000 
+0100
@@ -56,7 +56,7 @@
 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpx-0.21.0/README.md 
new/pytest_httpx-0.21.2/README.md
--- old/pytest_httpx-0.21.0/README.md   2022-05-24 18:29:06.000000000 +0200
+++ new/pytest_httpx-0.21.2/README.md   2022-11-03 22:03:01.000000000 +0100
@@ -5,7 +5,7 @@
 <a href="https://github.com/Colin-b/pytest_httpx/actions";><img alt="Build 
status" 
src="https://github.com/Colin-b/pytest_httpx/workflows/Release/badge.svg";></a>
 <a href="https://github.com/Colin-b/pytest_httpx/actions";><img alt="Coverage" 
src="https://img.shields.io/badge/coverage-100%25-brightgreen";></a>
 <a href="https://github.com/psf/black";><img alt="Code style: black" 
src="https://img.shields.io/badge/code%20style-black-000000.svg";></a>
-<a href="https://github.com/Colin-b/pytest_httpx/actions";><img alt="Number of 
tests" src="https://img.shields.io/badge/tests-153 passed-blue"></a>
+<a href="https://github.com/Colin-b/pytest_httpx/actions";><img alt="Number of 
tests" src="https://img.shields.io/badge/tests-168 passed-blue"></a>
 <a href="https://pypi.org/project/pytest-httpx/";><img alt="Number of 
downloads" src="https://img.shields.io/pypi/dm/pytest_httpx";></a>
 </p>
 
@@ -444,6 +444,38 @@
 
 ```
 
+Alternatively, callbacks can also be asynchronous.
+
+As in the following sample simulating network latency on some responses only.
+
+```python
+import asyncio
+import httpx
+import pytest
+from pytest_httpx import HTTPXMock
+
+
+@pytest.mark.asyncio
+async def test_dynamic_async_response(httpx_mock: HTTPXMock):
+    async def simulate_network_latency(request: httpx.Request):
+        await asyncio.sleep(1)
+        return httpx.Response(
+            status_code=200, json={"url": str(request.url)},
+        )
+
+    httpx_mock.add_callback(simulate_network_latency)
+    httpx_mock.add_response()
+
+    async with httpx.AsyncClient() as client:
+        responses = await asyncio.gather(
+            # Response will be received after one second
+            client.get("https://test_url";),
+            # Response will instantly be received (1 second before the first 
request)
+            client.get("https://test_url";)
+        )
+
+```
+
 ### Raising exceptions
 
 You can simulate HTTPX exception throwing by raising an exception in your 
callback or use `httpx_mock.add_exception` with the exception instance.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpx-0.21.0/pytest_httpx/_httpx_mock.py 
new/pytest_httpx-0.21.2/pytest_httpx/_httpx_mock.py
--- old/pytest_httpx-0.21.0/pytest_httpx/_httpx_mock.py 2022-05-24 
18:29:06.000000000 +0200
+++ new/pytest_httpx-0.21.2/pytest_httpx/_httpx_mock.py 2022-11-03 
22:03:01.000000000 +0100
@@ -1,14 +1,11 @@
+import inspect
 import re
-from typing import List, Union, Optional, Callable, Tuple, Pattern, Any, Dict
-from urllib.parse import parse_qs
+from typing import List, Union, Optional, Callable, Tuple, Pattern, Any, Dict, 
Awaitable
 
 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__(
@@ -36,18 +33,18 @@
         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:
@@ -89,7 +86,12 @@
         self._callbacks: List[
             Tuple[
                 _RequestMatcher,
-                Callable[[httpx.Request], Optional[httpx.Response]],
+                Callable[
+                    [httpx.Request],
+                    Union[
+                        Optional[httpx.Response], 
Awaitable[Optional[httpx.Response]]
+                    ],
+                ],
             ]
         ] = []
 
@@ -135,7 +137,12 @@
         self.add_callback(lambda request: response, **matchers)
 
     def add_callback(
-        self, callback: Callable[[httpx.Request], Optional[httpx.Response]], 
**matchers
+        self,
+        callback: Callable[
+            [httpx.Request],
+            Union[Optional[httpx.Response], 
Awaitable[Optional[httpx.Response]]],
+        ],
+        **matchers,
     ) -> None:
         """
         Mock the action that will take place if a request match.
@@ -180,12 +187,26 @@
             response = callback(request)
 
             if response:
-                # Allow to read the response on client side
-                response.is_stream_consumed = False
-                response.is_closed = False
-                if hasattr(response, "_content"):
-                    del response._content
-                return response
+                return _unread(response)
+
+        raise httpx.TimeoutException(
+            self._explain_that_no_response_was_found(request), request=request
+        )
+
+    async def _handle_async_request(
+        self,
+        request: httpx.Request,
+    ) -> httpx.Response:
+        self._requests.append(request)
+
+        callback = self._get_callback(request)
+        if callback:
+            response = callback(request)
+
+            if response:
+                if inspect.isawaitable(response):
+                    response = await response
+                return _unread(response)
 
         raise httpx.TimeoutException(
             self._explain_that_no_response_was_found(request), request=request
@@ -221,7 +242,12 @@
 
     def _get_callback(
         self, request: httpx.Request
-    ) -> Optional[Callable[[httpx.Request], Optional[httpx.Response]]]:
+    ) -> Optional[
+        Callable[
+            [httpx.Request],
+            Union[Optional[httpx.Response], 
Awaitable[Optional[httpx.Response]]],
+        ]
+    ]:
         callbacks = [
             (matcher, callback)
             for matcher, callback in self._callbacks
@@ -274,6 +300,7 @@
         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:
@@ -304,4 +331,13 @@
         self.mock = mock
 
     async def handle_async_request(self, *args, **kwargs) -> httpx.Response:
-        return self.mock._handle_request(*args, **kwargs)
+        return await self.mock._handle_async_request(*args, **kwargs)
+
+
+def _unread(response: httpx.Response) -> httpx.Response:
+    # Allow to read the response on client side
+    response.is_stream_consumed = False
+    response.is_closed = False
+    if hasattr(response, "_content"):
+        del response._content
+    return response
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpx-0.21.0/pytest_httpx/version.py 
new/pytest_httpx-0.21.2/pytest_httpx/version.py
--- old/pytest_httpx-0.21.0/pytest_httpx/version.py     2022-05-24 
18:29:06.000000000 +0200
+++ new/pytest_httpx-0.21.2/pytest_httpx/version.py     2022-11-03 
22:03:01.000000000 +0100
@@ -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.0"
+__version__ = "0.21.2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpx-0.21.0/setup.py 
new/pytest_httpx-0.21.2/setup.py
--- old/pytest_httpx-0.21.0/setup.py    2022-05-24 18:29:06.000000000 +0200
+++ new/pytest_httpx-0.21.2/setup.py    2022-11-03 22:03:01.000000000 +0100
@@ -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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpx-0.21.0/tests/test_httpx_async.py 
new/pytest_httpx-0.21.2/tests/test_httpx_async.py
--- old/pytest_httpx-0.21.0/tests/test_httpx_async.py   2022-05-24 
18:29:06.000000000 +0200
+++ new/pytest_httpx-0.21.2/tests/test_httpx_async.py   2022-11-03 
22:03:01.000000000 +0100
@@ -1,4 +1,7 @@
+import asyncio
+import math
 import re
+import time
 
 import httpx
 import pytest
@@ -166,7 +169,7 @@
             # Assert that stream still behaves the proper way (can only be 
consumed once per request)
             with pytest.raises(httpx.StreamConsumed):
                 async for part in response.aiter_raw():
-                    pass
+                    pass  # pragma: no cover
 
         async with client.stream(method="GET", url="https://test_url";) as 
response:
             assert [part async for part in response.aiter_raw()] == [
@@ -176,7 +179,7 @@
             # Assert that stream still behaves the proper way (can only be 
consumed once per request)
             with pytest.raises(httpx.StreamConsumed):
                 async for part in response.aiter_raw():
-                    pass
+                    pass  # pragma: no cover
 
 
 @pytest.mark.asyncio
@@ -194,7 +197,7 @@
             # Assert that stream still behaves the proper way (can only be 
consumed once per request)
             with pytest.raises(httpx.StreamConsumed):
                 async for part in response.aiter_raw():
-                    pass
+                    pass  # pragma: no cover
 
         async with client.stream(method="GET", url="https://test_url";) as 
response:
             assert [part async for part in response.aiter_raw()] == [
@@ -203,7 +206,7 @@
             # Assert that stream still behaves the proper way (can only be 
consumed once per request)
             with pytest.raises(httpx.StreamConsumed):
                 async for part in response.aiter_raw():
-                    pass
+                    pass  # pragma: no cover
 
 
 @pytest.mark.asyncio
@@ -221,7 +224,7 @@
             # Assert that stream still behaves the proper way (can only be 
consumed once per request)
             with pytest.raises(httpx.StreamConsumed):
                 async for part in response.aiter_raw():
-                    pass
+                    pass  # pragma: no cover
 
         async with client.stream(method="GET", url="https://test_url";) as 
response:
             assert [part async for part in response.aiter_raw()] == [
@@ -230,7 +233,7 @@
             # Assert that stream still behaves the proper way (can only be 
consumed once per request)
             with pytest.raises(httpx.StreamConsumed):
                 async for part in response.aiter_raw():
-                    pass
+                    pass  # pragma: no cover
 
 
 @pytest.mark.asyncio
@@ -243,14 +246,14 @@
             # Assert that stream still behaves the proper way (can only be 
consumed once per request)
             with pytest.raises(httpx.StreamConsumed):
                 async for part in response.aiter_raw():
-                    pass
+                    pass  # pragma: no cover
 
         async with client.stream(method="GET", url="https://test_url";) as 
response:
             assert [part async for part in response.aiter_raw()] == []
             # Assert that stream still behaves the proper way (can only be 
consumed once per request)
             with pytest.raises(httpx.StreamConsumed):
                 async for part in response.aiter_raw():
-                    pass
+                    pass  # pragma: no cover
 
 
 @pytest.mark.asyncio
@@ -488,6 +491,66 @@
 
 
 @pytest.mark.asyncio
+async def test_async_callback_with_await_statement(httpx_mock: HTTPXMock) -> 
None:
+    async def simulate_network_latency(request: httpx.Request):
+        await asyncio.sleep(1)
+        return httpx.Response(
+            status_code=200,
+            json={"url": str(request.url), "time": time.time()},
+        )
+
+    def instant_response(request: httpx.Request) -> httpx.Response:
+        return httpx.Response(
+            status_code=200, json={"url": str(request.url), "time": 
time.time()}
+        )
+
+    httpx_mock.add_callback(simulate_network_latency)
+    httpx_mock.add_callback(instant_response)
+    httpx_mock.add_response(json={"url": "not a callback"})
+
+    async with httpx.AsyncClient() as client:
+        responses = await asyncio.gather(
+            client.get("https://slow";),
+            client.get("https://fast_with_callback";),
+            client.get("https://fast_with_response";),
+        )
+        slow_response = responses[0].json()
+        assert slow_response["url"] == "https://slow";
+
+        fast_callback_response = responses[1].json()
+        assert fast_callback_response["url"] == "https://fast_with_callback";
+
+        fast_response = responses[2].json()
+        assert fast_response["url"] == "not a callback"
+
+        # Ensure slow request was properly awaited (did not block subsequent 
async queries)
+        assert math.isclose(slow_response["time"], 
fast_callback_response["time"] + 1)
+
+
+@pytest.mark.asyncio
+async def test_async_callback_with_pattern_in_url(httpx_mock: HTTPXMock) -> 
None:
+    async def custom_response(request: httpx.Request) -> httpx.Response:
+        return httpx.Response(status_code=200, json={"url": str(request.url)})
+
+    async def custom_response2(request: httpx.Request) -> httpx.Response:
+        return httpx.Response(
+            status_code=200,
+            extensions={"http_version": b"HTTP/2.0"},
+            json={"url": str(request.url)},
+        )
+
+    httpx_mock.add_callback(custom_response, url=re.compile(".*test.*"))
+    httpx_mock.add_callback(custom_response2, url="https://unmatched";)
+
+    async with httpx.AsyncClient() as client:
+        response = await client.get("https://unmatched";)
+        assert response.http_version == "HTTP/2.0"
+
+        response = await client.get("https://test_url";)
+        assert response.http_version == "HTTP/1.1"
+
+
+@pytest.mark.asyncio
 async def test_with_many_responses_urls_instances(httpx_mock: HTTPXMock) -> 
None:
     httpx_mock.add_response(
         url=httpx.URL("https://test_url";, params={"param1": "test"}),
@@ -763,6 +826,22 @@
 
 
 @pytest.mark.asyncio
+async def test_async_callback_raising_exception(httpx_mock: HTTPXMock) -> None:
+    async def raise_timeout(request: httpx.Request) -> httpx.Response:
+        raise httpx.ReadTimeout(
+            f"Unable to read within {request.extensions['timeout']['read']}",
+            request=request,
+        )
+
+    httpx_mock.add_callback(raise_timeout, url="https://test_url";)
+
+    async with httpx.AsyncClient() as client:
+        with pytest.raises(httpx.ReadTimeout) as exception_info:
+            await client.get("https://test_url";)
+        assert str(exception_info.value) == "Unable to read within 5.0"
+
+
+@pytest.mark.asyncio
 async def test_request_exception_raising(httpx_mock: HTTPXMock) -> None:
     httpx_mock.add_exception(
         httpx.ReadTimeout("Unable to read within 5.0"), url="https://test_url";
@@ -801,6 +880,19 @@
 
 
 @pytest.mark.asyncio
+async def test_async_callback_returning_response(httpx_mock: HTTPXMock) -> 
None:
+    async def custom_response(request: httpx.Request) -> httpx.Response:
+        return httpx.Response(status_code=200, json={"url": str(request.url)})
+
+    httpx_mock.add_callback(custom_response, url="https://test_url";)
+
+    async with httpx.AsyncClient() as client:
+        response = await client.get("https://test_url";)
+        assert response.json() == {"url": "https://test_url"}
+        assert response.headers["content-type"] == "application/json"
+
+
+@pytest.mark.asyncio
 async def test_callback_executed_twice(httpx_mock: HTTPXMock) -> None:
     def custom_response(request: httpx.Request) -> httpx.Response:
         return httpx.Response(status_code=200, json=["content"])
@@ -818,6 +910,23 @@
 
 
 @pytest.mark.asyncio
+async def test_async_callback_executed_twice(httpx_mock: HTTPXMock) -> None:
+    async def custom_response(request: httpx.Request) -> httpx.Response:
+        return httpx.Response(status_code=200, json=["content"])
+
+    httpx_mock.add_callback(custom_response)
+
+    async with httpx.AsyncClient() as client:
+        response = await client.get("https://test_url";)
+        assert response.json() == ["content"]
+        assert response.headers["content-type"] == "application/json"
+
+        response = await client.post("https://test_url";)
+        assert response.json() == ["content"]
+        assert response.headers["content-type"] == "application/json"
+
+
+@pytest.mark.asyncio
 async def test_callback_registered_after_response(httpx_mock: HTTPXMock) -> 
None:
     def custom_response(request: httpx.Request) -> httpx.Response:
         return httpx.Response(status_code=200, json=["content2"])
@@ -841,6 +950,29 @@
 
 
 @pytest.mark.asyncio
+async def test_async_callback_registered_after_response(httpx_mock: HTTPXMock) 
-> None:
+    async def custom_response(request: httpx.Request) -> httpx.Response:
+        return httpx.Response(status_code=200, json=["content2"])
+
+    httpx_mock.add_response(json=["content1"])
+    httpx_mock.add_callback(custom_response)
+
+    async with httpx.AsyncClient() as client:
+        response = await client.get("https://test_url";)
+        assert response.json() == ["content1"]
+        assert response.headers["content-type"] == "application/json"
+
+        response = await client.post("https://test_url";)
+        assert response.json() == ["content2"]
+        assert response.headers["content-type"] == "application/json"
+
+        # Assert that the last registered callback is sent again even if there 
is a response
+        response = await client.post("https://test_url";)
+        assert response.json() == ["content2"]
+        assert response.headers["content-type"] == "application/json"
+
+
+@pytest.mark.asyncio
 async def test_response_registered_after_callback(httpx_mock: HTTPXMock) -> 
None:
     def custom_response(request: httpx.Request) -> httpx.Response:
         return httpx.Response(status_code=200, json=["content1"])
@@ -864,6 +996,29 @@
 
 
 @pytest.mark.asyncio
+async def test_response_registered_after_async_callback(httpx_mock: HTTPXMock) 
-> None:
+    async def custom_response(request: httpx.Request) -> httpx.Response:
+        return httpx.Response(status_code=200, json=["content1"])
+
+    httpx_mock.add_callback(custom_response)
+    httpx_mock.add_response(json=["content2"])
+
+    async with httpx.AsyncClient() as client:
+        response = await client.get("https://test_url";)
+        assert response.json() == ["content1"]
+        assert response.headers["content-type"] == "application/json"
+
+        response = await client.post("https://test_url";)
+        assert response.json() == ["content2"]
+        assert response.headers["content-type"] == "application/json"
+
+        # Assert that the last registered response is sent again even if there 
is a callback
+        response = await client.post("https://test_url";)
+        assert response.json() == ["content2"]
+        assert response.headers["content-type"] == "application/json"
+
+
+@pytest.mark.asyncio
 async def test_callback_matching_method(httpx_mock: HTTPXMock) -> None:
     def custom_response(request: httpx.Request) -> httpx.Response:
         return httpx.Response(status_code=200, json=["content"])
@@ -880,6 +1035,23 @@
         assert response.headers["content-type"] == "application/json"
 
 
+@pytest.mark.asyncio
+async def test_async_callback_matching_method(httpx_mock: HTTPXMock) -> None:
+    async def custom_response(request: httpx.Request) -> httpx.Response:
+        return httpx.Response(status_code=200, json=["content"])
+
+    httpx_mock.add_callback(custom_response, method="GET")
+
+    async with httpx.AsyncClient() as client:
+        response = await client.get("https://test_url";)
+        assert response.json() == ["content"]
+        assert response.headers["content-type"] == "application/json"
+
+        response = await client.get("https://test_url2";)
+        assert response.json() == ["content"]
+        assert response.headers["content-type"] == "application/json"
+
+
 def test_request_retrieval_with_more_than_one(testdir: Testdir) -> None:
     """
     Single request cannot be returned if there is more than one matching.
@@ -1485,3 +1657,45 @@
     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_elapsed_when_add_async_callback(httpx_mock: HTTPXMock) -> None:
+    async def custom_response(request: httpx.Request) -> httpx.Response:
+        return httpx.Response(status_code=200, json={"foo": "bar"})
+
+    httpx_mock.add_callback(custom_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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpx-0.21.0/tests/test_httpx_sync.py 
new/pytest_httpx-0.21.2/tests/test_httpx_sync.py
--- old/pytest_httpx-0.21.0/tests/test_httpx_sync.py    2022-05-24 
18:29:06.000000000 +0200
+++ new/pytest_httpx-0.21.2/tests/test_httpx_sync.py    2022-11-03 
22:03:01.000000000 +0100
@@ -1383,3 +1383,30 @@
     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

Reply via email to