Skip to content

Commit

Permalink
Merge pull request #175 from Colin-b/develop
Browse files Browse the repository at this point in the history
Release 0.35.0
  • Loading branch information
Colin-b authored Nov 28, 2024
2 parents c91c327 + 1571050 commit 4477806
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 36 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.35.0] - 2024-11-28
### Changed
- Requires [`httpx`](https://www.python-httpx.org)==0.28.\*

## [0.34.0] - 2024-11-18
### Added
- `is_optional` parameter is now available on responses and callbacks registration. Allowing to add optional responses while keeping other responses as mandatory. Refer to documentation for more details.
Expand Down Expand Up @@ -404,7 +408,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.34.0...HEAD
[Unreleased]: https://github.com/Colin-b/pytest_httpx/compare/v0.35.0...HEAD
[0.35.0]: https://github.com/Colin-b/pytest_httpx/compare/v0.34.0...v0.35.0
[0.34.0]: https://github.com/Colin-b/pytest_httpx/compare/v0.33.0...v0.34.0
[0.33.0]: https://github.com/Colin-b/pytest_httpx/compare/v0.32.0...v0.33.0
[0.32.0]: https://github.com/Colin-b/pytest_httpx/compare/v0.31.2...v0.32.0
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ classifiers = [
"Typing :: Typed",
]
dependencies = [
"httpx==0.27.*",
"httpx==0.28.*",
"pytest==8.*",
]
dynamic = ["version"]
Expand All @@ -51,7 +51,7 @@ issues = "https://github.com/Colin-b/pytest_httpx/issues"
[project.optional-dependencies]
testing = [
# Used to check coverage
"pytest-cov==5.*",
"pytest-cov==6.*",
# Used to run async tests
"pytest-asyncio==0.24.*",
]
Expand Down
2 changes: 1 addition & 1 deletion pytest_httpx/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.34.0"
__version__ = "0.35.0"
55 changes: 35 additions & 20 deletions tests/test_httpx_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ async def test_method_not_matching(httpx_mock: HTTPXMock) -> None:

@pytest.mark.asyncio
async def test_reusing_one_response(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(url="https://test_url", content=b"test content", is_reusable=True)
httpx_mock.add_response(
url="https://test_url", content=b"test content", is_reusable=True
)

async with httpx.AsyncClient() as client:
response = await client.get("https://test_url")
Expand Down Expand Up @@ -286,7 +288,9 @@ async def test_with_many_responses(httpx_mock: HTTPXMock) -> None:
@pytest.mark.asyncio
async def test_with_many_reused_responses(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(url="https://test_url", content=b"test content 1")
httpx_mock.add_response(url="https://test_url", content=b"test content 2", is_reusable=True)
httpx_mock.add_response(
url="https://test_url", content=b"test content 2", is_reusable=True
)

async with httpx.AsyncClient() as client:
response = await client.get("https://test_url")
Expand Down Expand Up @@ -1137,7 +1141,9 @@ async def test_multi_value_headers_matching(httpx_mock: HTTPXMock) -> None:
async def test_multi_value_headers_not_matching_single_value_issued(
httpx_mock: HTTPXMock,
) -> None:
httpx_mock.add_response(match_headers={"my-custom-header": "value1"}, is_optional=True)
httpx_mock.add_response(
match_headers={"my-custom-header": "value1"}, is_optional=True
)

async with httpx.AsyncClient() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand All @@ -1160,7 +1166,9 @@ async def test_multi_value_headers_not_matching_single_value_issued(
async def test_multi_value_headers_not_matching_multi_value_issued(
httpx_mock: HTTPXMock,
) -> None:
httpx_mock.add_response(match_headers={"my-custom-header": "value1, value2"}, is_optional=True)
httpx_mock.add_response(
match_headers={"my-custom-header": "value1, value2"}, is_optional=True
)

async with httpx.AsyncClient() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand All @@ -1182,7 +1190,8 @@ async def test_multi_value_headers_not_matching_multi_value_issued(
@pytest.mark.httpx_mock(assert_all_requests_were_expected=False)
async def test_headers_matching_respect_case(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
match_headers={"user-agent": f"python-httpx/{httpx.__version__}"}, is_optional=True
match_headers={"user-agent": f"python-httpx/{httpx.__version__}"},
is_optional=True,
)

async with httpx.AsyncClient() as client:
Expand All @@ -1204,7 +1213,7 @@ async def test_headers_not_matching(httpx_mock: HTTPXMock) -> None:
"Host": "test_url2",
"Host2": "test_url",
},
is_optional=True
is_optional=True,
)

async with httpx.AsyncClient() as client:
Expand Down Expand Up @@ -1480,7 +1489,7 @@ async def test_json_not_matching(httpx_mock: HTTPXMock) -> None:
await client.post("https://test_url", json={"c": 3, "b": 2, "a": 1})
assert (
str(exception_info.value)
== """No response can be found for POST request on https://test_url with b'{"c": 3, "b": 2, "a": 1}' body amongst:
== """No response can be found for POST request on https://test_url with b'{"c":3,"b":2,"a":1}' body amongst:
- Match any request with {'a': 1, 'b': 2} json body"""
)

Expand All @@ -1490,7 +1499,7 @@ async def test_json_not_matching(httpx_mock: HTTPXMock) -> None:
async def test_headers_and_json_not_matching(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
match_json={"a": 1, "b": 2},
match_headers={"foo": "bar"},
match_headers={"foo": "bar"},
is_optional=True,
)

Expand All @@ -1499,7 +1508,7 @@ async def test_headers_and_json_not_matching(httpx_mock: HTTPXMock) -> None:
await client.post("https://test_url", json={"c": 3, "b": 2, "a": 1})
assert (
str(exception_info.value)
== """No response can be found for POST request on https://test_url with {} headers and b'{"c": 3, "b": 2, "a": 1}' body amongst:
== """No response can be found for POST request on https://test_url with {} headers and b'{"c":3,"b":2,"a":1}' body amongst:
- Match any request with {'foo': 'bar'} headers and {'a': 1, 'b': 2} json body"""
)

Expand Down Expand Up @@ -1539,7 +1548,7 @@ async def test_headers_not_matching_and_content_matching(httpx_mock: HTTPXMock)
"User-Agent": f"python-httpx/{httpx.__version__}",
"Host": "test_url2",
},
match_content=b"This is the body",
match_content=b"This is the body",
is_optional=True,
)

Expand All @@ -1561,7 +1570,7 @@ async def test_headers_matching_and_content_not_matching(httpx_mock: HTTPXMock)
"User-Agent": f"python-httpx/{httpx.__version__}",
"Host": "test_url",
},
match_content=b"This is the body2",
match_content=b"This is the body2",
is_optional=True,
)

Expand All @@ -1583,7 +1592,7 @@ async def test_headers_and_content_not_matching(httpx_mock: HTTPXMock) -> None:
"User-Agent": f"python-httpx/{httpx.__version__}",
"Host": "test_url2",
},
match_content=b"This is the body2",
match_content=b"This is the body2",
is_optional=True,
)

Expand Down Expand Up @@ -1621,7 +1630,7 @@ async def test_headers_not_matching_and_url_and_content_matching(
"User-Agent": f"python-httpx/{httpx.__version__}",
"Host": "test_url2",
},
match_content=b"This is the body",
match_content=b"This is the body",
is_optional=True,
)

Expand All @@ -1646,7 +1655,7 @@ async def test_url_and_headers_not_matching_and_content_matching(
"User-Agent": f"python-httpx/{httpx.__version__}",
"Host": "test_url2",
},
match_content=b"This is the body",
match_content=b"This is the body",
is_optional=True,
)

Expand All @@ -1671,7 +1680,7 @@ async def test_url_and_headers_matching_and_content_not_matching(
"User-Agent": f"python-httpx/{httpx.__version__}",
"Host": "test_url",
},
match_content=b"This is the body2",
match_content=b"This is the body2",
is_optional=True,
)

Expand All @@ -1696,7 +1705,7 @@ async def test_headers_matching_and_url_and_content_not_matching(
"User-Agent": f"python-httpx/{httpx.__version__}",
"Host": "test_url",
},
match_content=b"This is the body2",
match_content=b"This is the body2",
is_optional=True,
)

Expand All @@ -1721,7 +1730,7 @@ async def test_url_matching_and_headers_and_content_not_matching(
"User-Agent": f"python-httpx/{httpx.__version__}",
"Host": "test_url2",
},
match_content=b"This is the body2",
match_content=b"This is the body2",
is_optional=True,
)

Expand Down Expand Up @@ -2207,7 +2216,9 @@ async def test_files_not_matching_name(httpx_mock: HTTPXMock, monkeypatch) -> No
lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18",
)

httpx_mock.add_response(match_files={"name2": ("file_name", b"File content")}, is_optional=True)
httpx_mock.add_response(
match_files={"name2": ("file_name", b"File content")}, is_optional=True
)

async with httpx.AsyncClient() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand All @@ -2231,7 +2242,9 @@ async def test_files_not_matching_file_name(httpx_mock: HTTPXMock, monkeypatch)
lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18",
)

httpx_mock.add_response(match_files={"name": ("file_name2", b"File content")}, is_optional=True)
httpx_mock.add_response(
match_files={"name": ("file_name2", b"File content")}, is_optional=True
)

async with httpx.AsyncClient() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand All @@ -2255,7 +2268,9 @@ async def test_files_not_matching_content(httpx_mock: HTTPXMock, monkeypatch) ->
lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18",
)

httpx_mock.add_response(match_files={"name": ("file_name", b"File content2")}, is_optional=True)
httpx_mock.add_response(
match_files={"name": ("file_name", b"File content2")}, is_optional=True
)

async with httpx.AsyncClient() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand Down
40 changes: 28 additions & 12 deletions tests/test_httpx_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ def test_method_not_matching(httpx_mock: HTTPXMock) -> None:


def test_reusing_one_response(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(url="https://test_url", content=b"test content", is_reusable=True)
httpx_mock.add_response(
url="https://test_url", content=b"test content", is_reusable=True
)

with httpx.Client() as client:
response = client.get("https://test_url")
Expand Down Expand Up @@ -265,7 +267,9 @@ def test_with_many_responses(httpx_mock: HTTPXMock) -> None:

def test_with_many_reused_responses(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(url="https://test_url", content=b"test content 1")
httpx_mock.add_response(url="https://test_url", content=b"test content 2", is_reusable=True)
httpx_mock.add_response(
url="https://test_url", content=b"test content 2", is_reusable=True
)

with httpx.Client() as client:
response = client.get("https://test_url")
Expand Down Expand Up @@ -907,7 +911,9 @@ def test_multi_value_headers_matching(httpx_mock: HTTPXMock) -> None:
def test_multi_value_headers_not_matching_single_value_issued(
httpx_mock: HTTPXMock,
) -> None:
httpx_mock.add_response(match_headers={"my-custom-header": "value1"}, is_optional=True)
httpx_mock.add_response(
match_headers={"my-custom-header": "value1"}, is_optional=True
)

with httpx.Client() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand All @@ -929,7 +935,9 @@ def test_multi_value_headers_not_matching_single_value_issued(
def test_multi_value_headers_not_matching_multi_value_issued(
httpx_mock: HTTPXMock,
) -> None:
httpx_mock.add_response(match_headers={"my-custom-header": "value1, value2"}, is_optional=True)
httpx_mock.add_response(
match_headers={"my-custom-header": "value1, value2"}, is_optional=True
)

with httpx.Client() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand All @@ -950,7 +958,8 @@ def test_multi_value_headers_not_matching_multi_value_issued(
@pytest.mark.httpx_mock(assert_all_requests_were_expected=False)
def test_headers_matching_respect_case(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
match_headers={"user-agent": f"python-httpx/{httpx.__version__}"}, is_optional=True
match_headers={"user-agent": f"python-httpx/{httpx.__version__}"},
is_optional=True,
)

with httpx.Client() as client:
Expand All @@ -971,7 +980,7 @@ def test_headers_not_matching(httpx_mock: HTTPXMock) -> None:
"Host": "test_url2",
"Host2": "test_url",
},
is_optional=True
is_optional=True,
)

with httpx.Client() as client:
Expand Down Expand Up @@ -1239,7 +1248,7 @@ def test_json_not_matching(httpx_mock: HTTPXMock) -> None:
client.post("https://test_url", json={"c": 3, "b": 2, "a": 1})
assert (
str(exception_info.value)
== """No response can be found for POST request on https://test_url with b'{"c": 3, "b": 2, "a": 1}' body amongst:
== """No response can be found for POST request on https://test_url with b'{"c":3,"b":2,"a":1}' body amongst:
- Match any request with {'a': 1, 'b': 2} json body"""
)

Expand All @@ -1257,7 +1266,7 @@ def test_headers_and_json_not_matching(httpx_mock: HTTPXMock) -> None:
client.post("https://test_url", json={"c": 3, "b": 2, "a": 1})
assert (
str(exception_info.value)
== """No response can be found for POST request on https://test_url with {} headers and b'{"c": 3, "b": 2, "a": 1}' body amongst:
== """No response can be found for POST request on https://test_url with {} headers and b'{"c":3,"b":2,"a":1}' body amongst:
- Match any request with {'foo': 'bar'} headers and {'a': 1, 'b': 2} json body"""
)

Expand Down Expand Up @@ -1904,7 +1913,9 @@ def test_files_not_matching_name(httpx_mock: HTTPXMock, monkeypatch) -> None:
lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18",
)

httpx_mock.add_response(match_files={"name2": ("file_name", b"File content")}, is_optional=True)
httpx_mock.add_response(
match_files={"name2": ("file_name", b"File content")}, is_optional=True
)

with httpx.Client() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand All @@ -1927,7 +1938,9 @@ def test_files_not_matching_file_name(httpx_mock: HTTPXMock, monkeypatch) -> Non
lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18",
)

httpx_mock.add_response(match_files={"name": ("file_name2", b"File content")}, is_optional=True)
httpx_mock.add_response(
match_files={"name": ("file_name2", b"File content")}, is_optional=True
)

with httpx.Client() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand All @@ -1950,7 +1963,9 @@ def test_files_not_matching_content(httpx_mock: HTTPXMock, monkeypatch) -> None:
lambda length: b"\xfb\xe4\x95\xef\xe4\xcdA\xb9A\xca\x13\xe2T\xd6\xb0\x18",
)

httpx_mock.add_response(match_files={"name": ("file_name", b"File content2")}, is_optional=True)
httpx_mock.add_response(
match_files={"name": ("file_name", b"File content2")}, is_optional=True
)

with httpx.Client() as client:
with pytest.raises(httpx.TimeoutException) as exception_info:
Expand Down Expand Up @@ -2016,7 +2031,8 @@ def test_timeout_matching(httpx_mock: HTTPXMock) -> None:
@pytest.mark.httpx_mock(assert_all_requests_were_expected=False)
def test_timeout_not_matching(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
match_extensions={"timeout": {"connect": 5, "read": 5, "write": 10, "pool": 5}}, is_optional=True
match_extensions={"timeout": {"connect": 5, "read": 5, "write": 10, "pool": 5}},
is_optional=True,
)

with httpx.Client() as client:
Expand Down

0 comments on commit 4477806

Please sign in to comment.