Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Sending a non UTF8 body while having a `json` matcher registered will not raise a `UnicodeDecodeError` anymore.
- `match_params` is now handling `bool`, `int` and `float` values in addition to `str`. Only str values were previously expected.
- A meaningful error will now be returned when a callback that does not return an `httpx.Response` is called.
- Responses with a `Content-Encoding` (such as `gzip`) provided via `content` can now be read by the client. They previously failed with `httpx.DecodingError`.

### Removed
- python `3.10` is not supported anymore.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<a href="https://pypi.org/project/pytest-httpx/"><img alt="pypi version" src="https://img.shields.io/pypi/v/pytest_httpx"></a>
<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://codecov.io/gh/Colin-b/pytest_httpx" ><img alt="Coverage" src="https://codecov.io/gh/Colin-b/pytest_httpx/branch/master/graph/badge.svg?token=U2PJFVMCAL"/></a>
<a href="https://codecov.io/gh/Colin-b/pytest_httpx/tests"><img alt="Number of tests" src="https://img.shields.io/badge/tests-346 passed-blue"></a>
<a href="https://codecov.io/gh/Colin-b/pytest_httpx/tests"><img alt="Number of tests" src="https://img.shields.io/badge/tests-354 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>

Expand Down
2 changes: 2 additions & 0 deletions pytest_httpx/_httpx_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,4 +369,6 @@ def _unread(response: httpx.Response) -> httpx.Response:
response.is_closed = False
if hasattr(response, "_content"):
del response._content
if hasattr(response, "_decoder"):
del response._decoder
return response
46 changes: 46 additions & 0 deletions tests/test_httpx_async.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import gzip
import math
import os
import re
Expand Down Expand Up @@ -921,6 +922,51 @@ async def test_with_headers(httpx_mock: HTTPXMock) -> None:
)


@pytest.mark.asyncio
async def test_with_gzip_content_encoding(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
url="https://test_url",
content=gzip.compress(b"test content 1"),
headers={"Content-Encoding": "gzip"},
)

async with httpx.AsyncClient() as client:
response = await client.get("https://test_url")
assert response.content == b"test content 1"


@pytest.mark.asyncio
async def test_stream_with_gzip_content_encoding(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
url="https://test_url",
content=gzip.compress(b"test content 1"),
headers={"Content-Encoding": "gzip"},
)

async with (
httpx.AsyncClient() as client,
client.stream(method="GET", url="https://test_url") as response,
):
chunks = [chunk async for chunk in response.aiter_bytes()]
assert b"".join(chunks) == b"test content 1"


@pytest.mark.asyncio
async def test_callback_with_gzip_content_encoding(httpx_mock: HTTPXMock) -> None:
def custom_response(request: httpx.Request) -> httpx.Response:
return httpx.Response(
status_code=200,
content=gzip.compress(b"test content 1"),
headers={"Content-Encoding": "gzip"},
)

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.content == b"test content 1"


@pytest.mark.asyncio
async def test_requests_retrieval(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
Expand Down
42 changes: 42 additions & 0 deletions tests/test_httpx_sync.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import gzip
import os
import re
from collections.abc import Iterable
Expand Down Expand Up @@ -834,6 +835,47 @@ def test_with_headers(httpx_mock: HTTPXMock) -> None:
)


def test_with_gzip_content_encoding(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
url="https://test_url",
content=gzip.compress(b"test content 1"),
headers={"Content-Encoding": "gzip"},
)

with httpx.Client() as client:
response = client.get("https://test_url")
assert response.content == b"test content 1"


def test_stream_with_gzip_content_encoding(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
url="https://test_url",
content=gzip.compress(b"test content 1"),
headers={"Content-Encoding": "gzip"},
)

with (
httpx.Client() as client,
client.stream(method="GET", url="https://test_url") as response,
):
assert b"".join(response.iter_bytes()) == b"test content 1"


def test_callback_with_gzip_content_encoding(httpx_mock: HTTPXMock) -> None:
def custom_response(request: httpx.Request) -> httpx.Response:
return httpx.Response(
status_code=200,
content=gzip.compress(b"test content 1"),
headers={"Content-Encoding": "gzip"},
)

httpx_mock.add_callback(custom_response, url="https://test_url")

with httpx.Client() as client:
response = client.get("https://test_url")
assert response.content == b"test content 1"


def test_requests_retrieval(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
url="https://test_url", method="GET", content=b"test content 1"
Expand Down
Loading