Пример #1
0
async def test_mounted_transport():
    transport = MockTransport(unmounted)
    mounts = {"custom://": MockTransport(mounted)}

    async with httpx.AsyncClient(transport=transport, mounts=mounts) as client:
        response = await client.get("https://www.example.com")
        assert response.status_code == 200
        assert response.json() == {"app": "unmounted"}

        response = await client.get("custom://www.example.com")
        assert response.status_code == 200
        assert response.json() == {"app": "mounted"}
Пример #2
0
async def test_auth_invalid_type() -> None:
    app = App()

    with pytest.raises(TypeError):
        client = httpx.AsyncClient(
            transport=MockTransport(app),
            auth="not a tuple, not a callable",  # type: ignore
        )

    async with httpx.AsyncClient(transport=MockTransport(app)) as client:
        with pytest.raises(TypeError):
            await client.get(auth="not a tuple, not a callable")  # type: ignore

        with pytest.raises(TypeError):
            client.auth = "not a tuple, not a callable"  # type: ignore
Пример #3
0
def test_same_domain_redirect():
    client = httpx.Client(transport=MockTransport(redirects))
    url = "https://example.org/cross_domain"
    headers = {"Authorization": "abc"}
    response = client.get(url, headers=headers)
    assert response.url == "https://example.org/cross_domain_target"
    assert response.json()["headers"]["authorization"] == "abc"
Пример #4
0
async def test_digest_auth_no_specified_qop() -> None:
    url = "https://example.org/"
    auth = DigestAuth(username="******", password="******")
    app = DigestApp(qop="")

    async with httpx.AsyncClient(transport=MockTransport(app)) as client:
        response = await client.get(url, auth=auth)

    assert response.status_code == 200
    assert len(response.history) == 1

    authorization = typing.cast(dict, response.json())["auth"]
    scheme, _, fields = authorization.partition(" ")
    assert scheme == "Digest"

    response_fields = [field.strip() for field in fields.split(",")]
    digest_data = dict(field.split("=") for field in response_fields)

    assert "qop" not in digest_data
    assert "nc" not in digest_data
    assert "cnonce" not in digest_data
    assert digest_data["username"] == '"tomchristie"'
    assert digest_data["realm"] == '"*****@*****.**"'
    assert len(digest_data["nonce"]) == 64 + 2  # extra quotes
    assert digest_data["uri"] == '"/"'
    assert len(digest_data["response"]) == 64 + 2
    assert len(digest_data["opaque"]) == 64 + 2
    assert digest_data["algorithm"] == "SHA-256"
Пример #5
0
async def test_async_too_many_redirects_calling_next():
    async with httpx.AsyncClient(transport=MockTransport(redirects)) as client:
        url = "https://example.org/multiple_redirects?count=21"
        response = await client.get(url, allow_redirects=False)
        with pytest.raises(httpx.TooManyRedirects):
            while response.is_redirect:
                response = await response.anext()
Пример #6
0
def test_can_stream_if_no_redirect():
    client = httpx.Client(transport=MockTransport(redirects))
    url = "https://example.org/redirect_301"
    with client.stream("GET", url, allow_redirects=False) as response:
        assert not response.is_closed
    assert response.status_code == httpx.codes.MOVED_PERMANENTLY
    assert response.headers["location"] == "https://example.org/"
Пример #7
0
def test_setting_client_cookies_to_cookiejar() -> None:
    """
    Send a request including a cookie, using a `CookieJar` instance.
    """

    url = "http://example.org/echo_cookies"
    cookies = CookieJar()
    cookie = Cookie(
        version=0,
        name="example-name",
        value="example-value",
        port=None,
        port_specified=False,
        domain="",
        domain_specified=False,
        domain_initial_dot=False,
        path="/",
        path_specified=True,
        secure=False,
        expires=None,
        discard=True,
        comment=None,
        comment_url=None,
        rest={"HttpOnly": ""},
        rfc2109=False,
    )
    cookies.set_cookie(cookie)

    client = httpx.Client(transport=MockTransport(get_and_set_cookies))
    client.cookies = cookies  # type: ignore
    response = client.get(url)

    assert response.status_code == 200
    assert response.json() == {"cookies": "example-name=example-value"}
Пример #8
0
def test_no_redirect():
    client = httpx.Client(transport=MockTransport(redirects))
    url = "https://example.com/no_redirect"
    response = client.get(url)
    assert response.status_code == 200
    with pytest.raises(httpx.NotRedirectResponse):
        response.next()
Пример #9
0
def test_redirect_cookie_behavior():
    client = httpx.Client(transport=MockTransport(cookie_sessions))

    # The client is not logged in.
    response = client.get("https://example.com/")
    assert response.url == "https://example.com/"
    assert response.text == "Not logged in"

    # Login redirects to the homepage, setting a session cookie.
    response = client.post("https://example.com/login")
    assert response.url == "https://example.com/"
    assert response.text == "Logged in"

    # The client is logged in.
    response = client.get("https://example.com/")
    assert response.url == "https://example.com/"
    assert response.text == "Logged in"

    # Logout redirects to the homepage, expiring the session cookie.
    response = client.post("https://example.com/logout")
    assert response.url == "https://example.com/"
    assert response.text == "Not logged in"

    # The client is not logged in.
    response = client.get("https://example.com/")
    assert response.url == "https://example.com/"
    assert response.text == "Not logged in"
Пример #10
0
def test_header_update():
    url = "http://example.org/echo_headers"
    client = httpx.Client(transport=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",
            "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",
            "another-header": "AThing",
            "connection": "keep-alive",
            "host": "example.org",
            "user-agent": "python-myclient/0.2.1",
        }
    }
Пример #11
0
async def test_async_event_hooks():
    events = []

    async def on_request(request):
        events.append({"event": "request", "headers": dict(request.headers)})

    async def on_response(response):
        events.append({"event": "response", "headers": dict(response.headers)})

    event_hooks = {"request": [on_request], "response": [on_response]}

    async with httpx.AsyncClient(event_hooks=event_hooks,
                                 transport=MockTransport(app)) as http:
        await http.get("http://127.0.0.1:8000/", auth=("username", "password"))

    assert events == [
        {
            "event": "request",
            "headers": {
                "host": "127.0.0.1:8000",
                "user-agent": f"python-httpx/{httpx.__version__}",
                "accept": "*/*",
                "accept-encoding": "gzip, deflate, br",
                "connection": "keep-alive",
                "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
            },
        },
        {
            "event": "response",
            "headers": {
                "server": "testserver"
            },
        },
    ]
Пример #12
0
def test_sync_too_many_redirects_calling_next():
    client = httpx.Client(transport=MockTransport(redirects))
    url = "https://example.org/multiple_redirects?count=21"
    response = client.get(url, allow_redirects=False)
    with pytest.raises(httpx.TooManyRedirects):
        while response.is_redirect:
            response = response.next()
Пример #13
0
def test_malformed_redirect():
    # https://github.com/encode/httpx/issues/771
    client = httpx.Client(transport=MockTransport(redirects))
    response = client.get("http://example.org/malformed_redirect")
    assert response.status_code == httpx.codes.OK
    assert response.url == "https://example.org:443/"
    assert len(response.history) == 1
Пример #14
0
async def test_digest_auth_qop_must_be_auth_or_auth_int() -> None:
    url = "https://example.org/"
    auth = DigestAuth(username="******", password="******")
    app = DigestApp(qop="not-auth")

    async with httpx.AsyncClient(transport=MockTransport(app)) as client:
        with pytest.raises(ProtocolError):
            await client.get(url, auth=auth)
Пример #15
0
async def test_digest_auth_qop_auth_int_not_implemented() -> None:
    url = "https://example.org/"
    auth = DigestAuth(username="******", password="******")
    app = DigestApp(qop="auth-int")

    async with httpx.AsyncClient(transport=MockTransport(app)) as client:
        with pytest.raises(NotImplementedError):
            await client.get(url, auth=auth)
Пример #16
0
def test_client_closed_state_using_with_block():
    with httpx.Client(transport=MockTransport(hello_world)) as client:
        assert not client.is_closed
        client.get("http://example.com")

    assert client.is_closed
    with pytest.raises(RuntimeError):
        client.get("http://example.com")
Пример #17
0
def test_all_mounted_transport():
    mounts = {"all://": MockTransport(mounted)}

    client = httpx.Client(mounts=mounts)

    response = client.get("https://www.example.com")
    assert response.status_code == 200
    assert response.json() == {"app": "mounted"}
Пример #18
0
def test_multipart_invalid_value(value):
    client = httpx.Client(transport=MockTransport(echo_request_content))

    data = {"text": value}
    files = {"file": io.BytesIO(b"<file content>")}
    with pytest.raises(TypeError) as e:
        client.post("http://127.0.0.1:8000/", data=data, files=files)
    assert "Invalid type for value" in str(e.value)
Пример #19
0
async def test_auth_hidden_header() -> None:
    url = "https://example.org/"
    auth = ("example-username", "example-password")
    app = App()

    async with httpx.AsyncClient(transport=MockTransport(app)) as client:
        response = await client.get(url, auth=auth)

    assert "'authorization': '[secure]'" in str(response.request.headers)
Пример #20
0
def test_get_cookie() -> None:
    url = "http://example.org/set_cookie"

    client = httpx.Client(transport=MockTransport(get_and_set_cookies))
    response = client.get(url)

    assert response.status_code == 200
    assert response.cookies["example-name"] == "example-value"
    assert client.cookies["example-name"] == "example-value"
Пример #21
0
def test_cannot_redirect_streaming_body():
    client = httpx.Client(transport=MockTransport(redirects))
    url = "https://example.org/redirect_body"

    def streaming_body():
        yield b"Example request body"  # pragma: nocover

    with pytest.raises(httpx.RequestBodyUnavailable):
        client.post(url, data=streaming_body())
Пример #22
0
def test_sync_digest_auth_raises_protocol_error_on_malformed_header(
    auth_header: str, ) -> None:
    url = "https://example.org/"
    auth = DigestAuth(username="******", password="******")
    app = App(auth_header=auth_header, status_code=401)

    with httpx.Client(transport=MockTransport(app)) as client:
        with pytest.raises(ProtocolError):
            client.get(url, auth=auth)
Пример #23
0
async def test_basic_auth_in_url() -> None:
    url = "https://*****:*****@example.org/"
    app = App()

    async with httpx.AsyncClient(transport=MockTransport(app)) as client:
        response = await client.get(url)

    assert response.status_code == 200
    assert response.json() == {"auth": "Basic dG9tY2hyaXN0aWU6cGFzc3dvcmQxMjM="}
Пример #24
0
def test_cannot_redirect_streaming_body():
    client = httpx.Client(transport=MockTransport(redirects))
    url = "https://example.org/redirect_body"

    def streaming_body():
        yield b"Example request body"  # pragma: nocover

    with pytest.raises(httpx.StreamConsumed):
        client.post(url, content=streaming_body())
Пример #25
0
async def test_digest_auth_incorrect_credentials() -> None:
    url = "https://example.org/"
    auth = DigestAuth(username="******", password="******")
    app = DigestApp(send_response_after_attempt=2)

    async with httpx.AsyncClient(transport=MockTransport(app)) as client:
        response = await client.get(url, auth=auth)

    assert response.status_code == 401
    assert len(response.history) == 1
Пример #26
0
async def test_digest_auth_qop_including_spaces_and_auth_returns_auth(qop: str) -> None:
    url = "https://example.org/"
    auth = DigestAuth(username="******", password="******")
    app = DigestApp(qop=qop)

    async with httpx.AsyncClient(transport=MockTransport(app)) as client:
        response = await client.get(url, auth=auth)

    assert response.status_code == 200
    assert len(response.history) == 1
Пример #27
0
def test_multiple_redirects():
    client = httpx.Client(transport=MockTransport(redirects))
    response = client.get("https://example.org/multiple_redirects?count=20")
    assert response.status_code == httpx.codes.OK
    assert response.url == "https://example.org/multiple_redirects"
    assert len(response.history) == 20
    assert response.history[0].url == "https://example.org/multiple_redirects?count=20"
    assert response.history[1].url == "https://example.org/multiple_redirects?count=19"
    assert len(response.history[0].history) == 0
    assert len(response.history[1].history) == 1
Пример #28
0
async def test_auth_header_has_priority_over_netrc() -> None:
    os.environ["NETRC"] = str(FIXTURES_DIR / ".netrc")
    url = "http://netrcexample.org"
    app = App()

    async with httpx.AsyncClient(transport=MockTransport(app)) as client:
        response = await client.get(url, headers={"Authorization": "Override"})

    assert response.status_code == 200
    assert response.json() == {"auth": "Override"}
Пример #29
0
async def test_auth_disable_per_request() -> None:
    url = "https://example.org/"
    auth = ("tomchristie", "password123")
    app = App()

    async with httpx.AsyncClient(transport=MockTransport(app), auth=auth) as client:
        response = await client.get(url, auth=None)

    assert response.status_code == 200
    assert response.json() == {"auth": None}
Пример #30
0
def test_client_queryparams_echo():
    url = "http://example.org/echo_queryparams"
    client_queryparams = "first=str"
    request_queryparams = {"second": "dict"}
    client = httpx.Client(transport=MockTransport(hello_world),
                          params=client_queryparams)
    response = client.get(url, params=request_queryparams)

    assert response.status_code == 200
    assert response.url == "http://example.org/echo_queryparams?first=str&second=dict"