From: Kar Petrosyan Date: Thu, 27 Feb 2025 15:40:59 +0000 (+0400) Subject: Make all the tests from test_headers and test_properties to be async X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c3f1ee12039f84dfef80a4986971536bf7b19a48;p=thirdparty%2Fhttpx.git Make all the tests from test_headers and test_properties to be async --- diff --git a/tests/client/test_headers.py b/tests/client/test_headers.py index 47f5a4d7..3216043d 100755 --- a/tests/client/test_headers.py +++ b/tests/client/test_headers.py @@ -20,164 +20,181 @@ def echo_repeated_headers_items(request: httpx.Request) -> httpx.Response: return httpx.Response(200, json=data) -def test_client_header(): +@pytest.mark.anyio +async def test_client_header(): """ Set a header in the Client. """ url = "http://example.org/echo_headers" headers = {"Example-Header": "example-value"} - client = httpx.Client(transport=httpx.MockTransport(echo_headers), headers=headers) - response = client.get(url) - - assert response.status_code == 200 - assert response.json() == { - "headers": { - "accept": "*/*", - "accept-encoding": "gzip, deflate, br, zstd", - "connection": "keep-alive", - "example-header": "example-value", - "host": "example.org", - "user-agent": f"python-httpx/{httpx.__version__}", + async with httpx.AsyncClient( + transport=httpx.MockTransport(echo_headers), headers=headers + ) as client: + response = await client.get(url) + + assert response.status_code == 200 + assert response.json() == { + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "connection": "keep-alive", + "example-header": "example-value", + "host": "example.org", + "user-agent": f"python-httpx/{httpx.__version__}", + } } - } -def test_header_merge(): +@pytest.mark.anyio +async def test_header_merge(): url = "http://example.org/echo_headers" client_headers = {"User-Agent": "python-myclient/0.2.1"} request_headers = {"X-Auth-Token": "FooBarBazToken"} - client = httpx.Client( + async with httpx.AsyncClient( transport=httpx.MockTransport(echo_headers), headers=client_headers - ) - response = client.get(url, headers=request_headers) - - assert response.status_code == 200 - assert response.json() == { - "headers": { - "accept": "*/*", - "accept-encoding": "gzip, deflate, br, zstd", - "connection": "keep-alive", - "host": "example.org", - "user-agent": "python-myclient/0.2.1", - "x-auth-token": "FooBarBazToken", + ) as client: + response = await client.get(url, headers=request_headers) + + assert response.status_code == 200 + assert response.json() == { + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "connection": "keep-alive", + "host": "example.org", + "user-agent": "python-myclient/0.2.1", + "x-auth-token": "FooBarBazToken", + } } - } -def test_header_merge_conflicting_headers(): +@pytest.mark.anyio +async def test_header_merge_conflicting_headers(): url = "http://example.org/echo_headers" client_headers = {"X-Auth-Token": "FooBar"} request_headers = {"X-Auth-Token": "BazToken"} - client = httpx.Client( + async with httpx.AsyncClient( transport=httpx.MockTransport(echo_headers), headers=client_headers - ) - response = client.get(url, headers=request_headers) - - assert response.status_code == 200 - assert response.json() == { - "headers": { - "accept": "*/*", - "accept-encoding": "gzip, deflate, br, zstd", - "connection": "keep-alive", - "host": "example.org", - "user-agent": f"python-httpx/{httpx.__version__}", - "x-auth-token": "BazToken", + ) as client: + response = await client.get(url, headers=request_headers) + + assert response.status_code == 200 + assert response.json() == { + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "connection": "keep-alive", + "host": "example.org", + "user-agent": f"python-httpx/{httpx.__version__}", + "x-auth-token": "BazToken", + } } - } -def test_header_update(): +@pytest.mark.anyio +async def test_header_update(): url = "http://example.org/echo_headers" - client = httpx.Client(transport=httpx.MockTransport(echo_headers)) - first_response = client.get(url) - client.headers.update( - {"User-Agent": "python-myclient/0.2.1", "Another-Header": "AThing"} - ) - second_response = client.get(url) - - assert first_response.status_code == 200 - assert first_response.json() == { - "headers": { - "accept": "*/*", - "accept-encoding": "gzip, deflate, br, zstd", - "connection": "keep-alive", - "host": "example.org", - "user-agent": f"python-httpx/{httpx.__version__}", + async with httpx.AsyncClient(transport=httpx.MockTransport(echo_headers)) as client: + first_response = await client.get(url) + client.headers.update( + {"User-Agent": "python-myclient/0.2.1", "Another-Header": "AThing"} + ) + second_response = await client.get(url) + + assert first_response.status_code == 200 + assert first_response.json() == { + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "connection": "keep-alive", + "host": "example.org", + "user-agent": f"python-httpx/{httpx.__version__}", + } } - } - - assert second_response.status_code == 200 - assert second_response.json() == { - "headers": { - "accept": "*/*", - "accept-encoding": "gzip, deflate, br, zstd", - "another-header": "AThing", - "connection": "keep-alive", - "host": "example.org", - "user-agent": "python-myclient/0.2.1", + + assert second_response.status_code == 200 + assert second_response.json() == { + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "another-header": "AThing", + "connection": "keep-alive", + "host": "example.org", + "user-agent": "python-myclient/0.2.1", + } } - } -def test_header_repeated_items(): +@pytest.mark.anyio +async def test_header_repeated_items(): url = "http://example.org/echo_headers" - client = httpx.Client(transport=httpx.MockTransport(echo_repeated_headers_items)) - response = client.get(url, headers=[("x-header", "1"), ("x-header", "2,3")]) + async with httpx.AsyncClient( + transport=httpx.MockTransport(echo_repeated_headers_items) + ) as client: + response = await client.get( + url, headers=[("x-header", "1"), ("x-header", "2,3")] + ) - assert response.status_code == 200 + assert response.status_code == 200 - echoed_headers = response.json()["headers"] - # as per RFC 7230, the whitespace after a comma is insignificant - # so we split and strip here so that we can do a safe comparison - assert ["x-header", ["1", "2", "3"]] in [ - [k, [subv.lstrip() for subv in v.split(",")]] for k, v in echoed_headers - ] + echoed_headers = response.json()["headers"] + # as per RFC 7230, the whitespace after a comma is insignificant + # so we split and strip here so that we can do a safe comparison + assert ["x-header", ["1", "2", "3"]] in [ + [k, [subv.lstrip() for subv in v.split(",")]] for k, v in echoed_headers + ] -def test_header_repeated_multi_items(): +@pytest.mark.anyio +async def test_header_repeated_multi_items(): url = "http://example.org/echo_headers" - client = httpx.Client( + async with httpx.AsyncClient( transport=httpx.MockTransport(echo_repeated_headers_multi_items) - ) - response = client.get(url, headers=[("x-header", "1"), ("x-header", "2,3")]) + ) as client: + response = await client.get( + url, headers=[("x-header", "1"), ("x-header", "2,3")] + ) - assert response.status_code == 200 + assert response.status_code == 200 - echoed_headers = response.json()["headers"] - assert ["x-header", "1"] in echoed_headers - assert ["x-header", "2,3"] in echoed_headers + echoed_headers = response.json()["headers"] + assert ["x-header", "1"] in echoed_headers + assert ["x-header", "2,3"] in echoed_headers -def test_remove_default_header(): +@pytest.mark.anyio +async def test_remove_default_header(): """ Remove a default header from the Client. """ url = "http://example.org/echo_headers" - client = httpx.Client(transport=httpx.MockTransport(echo_headers)) - del client.headers["User-Agent"] + async with httpx.AsyncClient(transport=httpx.MockTransport(echo_headers)) as client: + del client.headers["User-Agent"] - response = client.get(url) + response = await client.get(url) - assert response.status_code == 200 - assert response.json() == { - "headers": { - "accept": "*/*", - "accept-encoding": "gzip, deflate, br, zstd", - "connection": "keep-alive", - "host": "example.org", + assert response.status_code == 200 + assert response.json() == { + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "connection": "keep-alive", + "host": "example.org", + } } - } -def test_header_does_not_exist(): +@pytest.mark.anyio +async def test_header_does_not_exist(): headers = httpx.Headers({"foo": "bar"}) with pytest.raises(KeyError): del headers["baz"] -def test_header_with_incorrect_value(): +@pytest.mark.anyio +async def test_header_with_incorrect_value(): with pytest.raises( TypeError, match=f"Header value must be str or bytes, not {type(None)}", @@ -185,7 +202,8 @@ def test_header_with_incorrect_value(): httpx.Headers({"foo": None}) # type: ignore -def test_host_with_auth_and_port_in_url(): +@pytest.mark.anyio +async def test_host_with_auth_and_port_in_url(): """ The Host header should only include the hostname, or hostname:port (for non-default ports only). Any userinfo or default port should not @@ -193,101 +211,108 @@ def test_host_with_auth_and_port_in_url(): """ url = "http://username:password@example.org:80/echo_headers" - client = httpx.Client(transport=httpx.MockTransport(echo_headers)) - response = client.get(url) - - assert response.status_code == 200 - assert response.json() == { - "headers": { - "accept": "*/*", - "accept-encoding": "gzip, deflate, br, zstd", - "connection": "keep-alive", - "host": "example.org", - "user-agent": f"python-httpx/{httpx.__version__}", - "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", + async with httpx.AsyncClient(transport=httpx.MockTransport(echo_headers)) as client: + response = await client.get(url) + + assert response.status_code == 200 + assert response.json() == { + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "connection": "keep-alive", + "host": "example.org", + "user-agent": f"python-httpx/{httpx.__version__}", + "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", + } } - } -def test_host_with_non_default_port_in_url(): +@pytest.mark.anyio +async def test_host_with_non_default_port_in_url(): """ If the URL includes a non-default port, then it should be included in the Host header. """ url = "http://username:password@example.org:123/echo_headers" - client = httpx.Client(transport=httpx.MockTransport(echo_headers)) - response = client.get(url) - - assert response.status_code == 200 - assert response.json() == { - "headers": { - "accept": "*/*", - "accept-encoding": "gzip, deflate, br, zstd", - "connection": "keep-alive", - "host": "example.org:123", - "user-agent": f"python-httpx/{httpx.__version__}", - "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", + async with httpx.AsyncClient(transport=httpx.MockTransport(echo_headers)) as client: + response = await client.get(url) + + assert response.status_code == 200 + assert response.json() == { + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br, zstd", + "connection": "keep-alive", + "host": "example.org:123", + "user-agent": f"python-httpx/{httpx.__version__}", + "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", + } } - } -def test_request_auto_headers(): +@pytest.mark.anyio +async def test_request_auto_headers(): request = httpx.Request("GET", "https://www.example.org/") assert "host" in request.headers -def test_same_origin(): +@pytest.mark.anyio +async def test_same_origin(): origin = httpx.URL("https://example.com") request = httpx.Request("GET", "HTTPS://EXAMPLE.COM:443") - client = httpx.Client() - headers = client._redirect_headers(request, origin, "GET") + async with httpx.AsyncClient() as client: + headers = client._redirect_headers(request, origin, "GET") assert headers["Host"] == request.url.netloc.decode("ascii") -def test_not_same_origin(): +@pytest.mark.anyio +async def test_not_same_origin(): origin = httpx.URL("https://example.com") request = httpx.Request("GET", "HTTP://EXAMPLE.COM:80") - client = httpx.Client() - headers = client._redirect_headers(request, origin, "GET") + async with httpx.AsyncClient() as client: + headers = client._redirect_headers(request, origin, "GET") - assert headers["Host"] == origin.netloc.decode("ascii") + assert headers["Host"] == origin.netloc.decode("ascii") -def test_is_https_redirect(): +@pytest.mark.anyio +async def test_is_https_redirect(): url = httpx.URL("https://example.com") request = httpx.Request( "GET", "http://example.com", headers={"Authorization": "empty"} ) - client = httpx.Client() - headers = client._redirect_headers(request, url, "GET") + async with httpx.AsyncClient() as client: + headers = client._redirect_headers(request, url, "GET") - assert "Authorization" in headers + assert "Authorization" in headers -def test_is_not_https_redirect(): +@pytest.mark.anyio +async def test_is_not_https_redirect(): url = httpx.URL("https://www.example.com") request = httpx.Request( "GET", "http://example.com", headers={"Authorization": "empty"} ) - client = httpx.Client() - headers = client._redirect_headers(request, url, "GET") + async with httpx.AsyncClient() as client: + headers = client._redirect_headers(request, url, "GET") - assert "Authorization" not in headers + assert "Authorization" not in headers -def test_is_not_https_redirect_if_not_default_ports(): +@pytest.mark.anyio +async def test_is_not_https_redirect_if_not_default_ports(): url = httpx.URL("https://example.com:1337") request = httpx.Request( "GET", "http://example.com:9999", headers={"Authorization": "empty"} ) - client = httpx.Client() - headers = client._redirect_headers(request, url, "GET") + async with httpx.AsyncClient() as client: + headers = client._redirect_headers(request, url, "GET") - assert "Authorization" not in headers + assert "Authorization" not in headers diff --git a/tests/client/test_properties.py b/tests/client/test_properties.py index eb870981..d5245d9d 100644 --- a/tests/client/test_properties.py +++ b/tests/client/test_properties.py @@ -1,68 +1,77 @@ +import pytest + import httpx -def test_client_base_url(): - client = httpx.Client() - client.base_url = "https://www.example.org/" # type: ignore - assert isinstance(client.base_url, httpx.URL) - assert client.base_url == "https://www.example.org/" +@pytest.mark.anyio +async def test_client_base_url(): + async with httpx.AsyncClient() as client: + client.base_url = "https://www.example.org/" # type: ignore + assert isinstance(client.base_url, httpx.URL) + assert client.base_url == "https://www.example.org/" -def test_client_base_url_without_trailing_slash(): - client = httpx.Client() - client.base_url = "https://www.example.org/path" # type: ignore - assert isinstance(client.base_url, httpx.URL) - assert client.base_url == "https://www.example.org/path/" +@pytest.mark.anyio +async def test_client_base_url_without_trailing_slash(): + async with httpx.AsyncClient() as client: + client.base_url = "https://www.example.org/path" # type: ignore + assert isinstance(client.base_url, httpx.URL) + assert client.base_url == "https://www.example.org/path/" -def test_client_base_url_with_trailing_slash(): +@pytest.mark.anyio +async def test_client_base_url_with_trailing_slash(): client = httpx.Client() client.base_url = "https://www.example.org/path/" # type: ignore assert isinstance(client.base_url, httpx.URL) assert client.base_url == "https://www.example.org/path/" -def test_client_headers(): - client = httpx.Client() - client.headers = {"a": "b"} # type: ignore - assert isinstance(client.headers, httpx.Headers) - assert client.headers["A"] == "b" +@pytest.mark.anyio +async def test_client_headers(): + async with httpx.AsyncClient() as client: + client.headers = {"a": "b"} # type: ignore + assert isinstance(client.headers, httpx.Headers) + assert client.headers["A"] == "b" -def test_client_cookies(): - client = httpx.Client() - client.cookies = {"a": "b"} # type: ignore - assert isinstance(client.cookies, httpx.Cookies) - mycookies = list(client.cookies.jar) - assert len(mycookies) == 1 - assert mycookies[0].name == "a" and mycookies[0].value == "b" +@pytest.mark.anyio +async def test_client_cookies(): + async with httpx.AsyncClient() as client: + client.cookies = {"a": "b"} # type: ignore + assert isinstance(client.cookies, httpx.Cookies) + mycookies = list(client.cookies.jar) + assert len(mycookies) == 1 + assert mycookies[0].name == "a" and mycookies[0].value == "b" -def test_client_timeout(): +@pytest.mark.anyio +async def test_client_timeout(): expected_timeout = 12.0 - client = httpx.Client() + async with httpx.AsyncClient() as client: + client.timeout = expected_timeout # type: ignore - client.timeout = expected_timeout # type: ignore + assert isinstance(client.timeout, httpx.Timeout) + assert client.timeout.connect == expected_timeout + assert client.timeout.read == expected_timeout + assert client.timeout.write == expected_timeout + assert client.timeout.pool == expected_timeout - assert isinstance(client.timeout, httpx.Timeout) - assert client.timeout.connect == expected_timeout - assert client.timeout.read == expected_timeout - assert client.timeout.write == expected_timeout - assert client.timeout.pool == expected_timeout - -def test_client_event_hooks(): +@pytest.mark.anyio +async def test_client_event_hooks(): def on_request(request): pass # pragma: no cover - client = httpx.Client() - client.event_hooks = {"request": [on_request]} - assert client.event_hooks == {"request": [on_request], "response": []} + async with httpx.AsyncClient() as client: + client.event_hooks = {"request": [on_request]} + assert client.event_hooks == {"request": [on_request], "response": []} -def test_client_trust_env(): - client = httpx.Client() - assert client.trust_env +@pytest.mark.anyio +async def test_client_trust_env(): + async with httpx.AsyncClient() as client: + assert client.trust_env - client = httpx.Client(trust_env=False) - assert not client.trust_env + async with httpx.AsyncClient(trust_env=False) as client: + assert not client.trust_env