예제 #1
0
async def test_pass_through(client, args, kwargs, expected):
    async with MockTransport() as respx_mock:
        request = respx_mock.add(*args, **kwargs)

        with mock.patch(
                "asyncio.open_connection",
                side_effect=ConnectionRefusedError("test request blocked"),
        ) as open_connection:
            with pytest.raises(httpx.NetworkError):
                await client.get("https://example.org/")

        assert open_connection.called is True
        assert request.called is True
        assert request.is_pass_through is expected

    with MockTransport() as respx_mock:
        request = respx_mock.add(*args, **kwargs)

        with mock.patch(
                "socket.socket.connect",
                side_effect=socket.error("test request blocked")) as connect:
            with pytest.raises(httpx.NetworkError):
                httpx.get("https://example.org/")

        assert connect.called is True
        assert request.called is True
        assert request.is_pass_through is expected
예제 #2
0
async def test_assert_all_mocked(client, assert_all_mocked, raises):
    with raises:
        with MockTransport(assert_all_mocked=assert_all_mocked) as respx_mock:
            response = httpx.get("https://foo.bar/")
            assert respx_mock.stats.call_count == 1
            assert response.status_code == 200
    with raises:
        async with MockTransport(assert_all_mocked=assert_all_mocked) as respx_mock:
            response = await client.get("https://foo.bar/")
            assert respx_mock.stats.call_count == 1
            assert response.status_code == 200
    assert respx_mock.stats.call_count == 0
예제 #3
0
async def test_callable_content(client):
    async with MockTransport() as respx_mock:
        url_pattern = re.compile(r"https://foo.bar/(?P<slug>\w+)/")

        def content_callback(request, slug):
            request.read(
            )  # TODO: Make this not needed, might affect pass-through
            content = jsonlib.loads(request.content)
            return f"hello {slug}{content['x']}"

        request = respx_mock.post(url_pattern, content=content_callback)

        async_response = await client.post("https://foo.bar/world/",
                                           json={"x": "."})
        assert request.called is True
        assert async_response.status_code == 200
        assert async_response.text == "hello world."
        assert request.calls[-1][0].content == b'{"x": "."}'

        respx_mock.reset()
        sync_response = httpx.post("https://foo.bar/jonas/", json={"x": "!"})
        assert request.called is True
        assert sync_response.status_code == 200
        assert sync_response.text == "hello jonas!"
        assert request.calls[-1][0].content == b'{"x": "!"}'
예제 #4
0
async def test_url_match(client, url, pattern):
    async with MockTransport(assert_all_mocked=False) as respx_mock:
        request = respx_mock.get(pattern, content="baz")
        response = await client.get(url)
        assert request.called is True
        assert response.status_code == 200
        assert response.text == "baz"
예제 #5
0
async def test_headers(client, headers, content_type, expected):
    async with MockTransport() as respx_mock:
        url = "https://foo.bar/"
        request = respx_mock.get(url, content_type=content_type, headers=headers)
        response = await client.get(url)
        assert request.called is True
        assert response.headers == httpx.Headers(expected)
예제 #6
0
async def test_text_encoding(client, content, expected):
    async with MockTransport() as respx_mock:
        url = "https://foo.bar/"
        request = respx_mock.post(url, content=content)
        response = await client.post(url)
        assert request.called is True
        assert response.text == expected
예제 #7
0
async def test_httpcore_request():
    async with MockTransport() as transport:
        transport.add("GET", "https://foo.bar/", content="foobar")
        with httpcore.SyncConnectionPool() as http:
            (http_version, status_code, reason_phrase, headers, stream,) = http.request(
                method=b"GET", url=(b"https", b"foo.bar", 443, b"/"),
            )

            body = b"".join([chunk for chunk in stream])
            stream.close()
            assert body == b"foobar"

        async with httpcore.AsyncConnectionPool() as http:
            (
                http_version,
                status_code,
                reason_phrase,
                headers,
                stream,
            ) = await http.request(
                method=b"GET", url=(b"https", b"foo.bar", 443, b"/"),
            )

            body = b"".join([chunk async for chunk in stream])
            await stream.aclose()
            assert body == b"foobar"
예제 #8
0
async def test_request_callback(client):
    def callback(request, response):
        request.read()
        if request.url.host == "foo.bar" and request.content == b'{"foo": "bar"}':
            response.headers["X-Foo"] = "bar"
            response.content = lambda request, name: f"hello {name}"
            response.context["name"] = "lundberg"
            response.http_version = "HTTP/2"
            return response

    async with MockTransport(assert_all_called=False) as respx_mock:
        request = respx_mock.add(callback,
                                 status_code=202,
                                 headers={"X-Ham": "spam"})
        response = await client.post("https://foo.bar/", json={"foo": "bar"})

        assert request.called is True
        assert request.pass_through is None
        assert response.status_code == 202
        assert response.http_version == "HTTP/2"
        assert response.headers == httpx.Headers({
            "Content-Type": "text/plain; charset=utf-8",
            "Content-Length": "14",
            "X-Ham": "spam",
            "X-Foo": "bar",
        })
        assert response.text == "hello lundberg"

        with pytest.raises(ValueError):
            respx_mock.add(lambda req, res: "invalid")
            await client.get("https://ham.spam/")
예제 #9
0
async def test_status_code(client):
    async with MockTransport() as respx_mock:
        url = "https://foo.bar/"
        request = respx_mock.get(url, status_code=404)
        response = await client.get(url)

    assert request.called is True
    assert response.status_code == 404
예제 #10
0
async def test_alias():
    async with MockTransport(assert_all_called=False) as respx_mock:
        url = "https://foo.bar/"
        request = respx_mock.get(url, alias="foobar")
        assert "foobar" not in respx.aliases
        assert "foobar" in respx_mock.aliases
        assert respx_mock.aliases["foobar"].url == request.url
        assert respx_mock["foobar"].url == request.url
예제 #11
0
async def test_text_content(client, content, expected):
    async with MockTransport() as respx_mock:
        url = "https://foo.bar/"
        content_type = "text/plain; charset=utf-8"  # TODO: Remove once respected
        request = respx_mock.post(url, content=content, content_type=content_type)
        response = await client.post(url)
        assert request.called is True
        assert response.text == expected
예제 #12
0
async def test_add(client, method_str, client_method_attr):
    url = "https://example.org/"
    content = {"spam": "lots", "ham": "no, only spam"}
    async with MockTransport() as respx_mock:
        request = respx_mock.add(method_str, url, content=content)
        response = await getattr(client, client_method_attr)(url)
        assert request.called is True
        assert response.json() == content
예제 #13
0
async def test_alias():
    async with MockTransport(assert_all_called=False) as respx_mock:
        request = respx_mock.get("https://foo.bar/",
                                 content="foo bar",
                                 name="foobar")
        assert "foobar" not in respx.aliases
        assert "foobar" in respx_mock.aliases
        assert respx_mock.aliases["foobar"] is request
        assert respx_mock["foobar"] is request
예제 #14
0
async def test_raising_content(client):
    async with MockTransport() as respx_mock:
        url = "https://foo.bar/"
        request = respx_mock.get(url, content=httpx.ConnectTimeout())
        with pytest.raises(httpx.ConnectTimeout):
            await client.get(url)

        assert request.called is True
        _request, _response = request.calls[-1]
        assert _request is not None
        assert _response is None
예제 #15
0
async def test_assert_all_called(client, assert_all_called, do_post, raises):
    with raises:
        async with MockTransport(assert_all_called=assert_all_called) as respx_mock:
            request1 = respx_mock.get("https://foo.bar/1/", status_code=404)
            request2 = respx_mock.post("https://foo.bar/", status_code=201)

            await client.get("https://foo.bar/1/")
            if do_post:
                await client.post("https://foo.bar/")

            assert request1.called is True
            assert request2.called is do_post
예제 #16
0
async def test_json_content(client, content, headers, expected_headers):
    async with MockTransport() as respx_mock:
        url = "https://foo.bar/"
        request = respx_mock.get(url, content=content, headers=headers)

        async_response = await client.get(url)
        assert request.called is True
        assert async_response.headers == httpx.Headers(expected_headers)
        assert async_response.json() == content

        respx_mock.reset()
        sync_response = httpx.get(url)
        assert request.called is True
        assert sync_response.headers == httpx.Headers(expected_headers)
        assert sync_response.json() == content
예제 #17
0
async def test_callable_content(client):
    async with MockTransport() as respx_mock:
        url_pattern = re.compile(r"https://foo.bar/(?P<slug>\w+)/")
        content = lambda request, slug: f"hello {slug}"
        request = respx_mock.get(url_pattern, content=content)

        async_response = await client.get("https://foo.bar/world/")
        assert request.called is True
        assert async_response.status_code == 200
        assert async_response.text == "hello world"

        respx_mock.reset()
        sync_response = httpx.get("https://foo.bar/world/")
        assert request.called is True
        assert sync_response.status_code == 200
        assert sync_response.text == "hello world"
예제 #18
0
async def test_httpx_exception_handling(client):  # pragma: no cover
    async with MockTransport() as respx_mock:
        with mock.patch(
                "httpx._client.AsyncClient.dispatcher_for_url",
                side_effect=ValueError("mock"),
        ):
            url = "https://foo.bar/"
            request = respx_mock.get(url)
            with pytest.raises(ValueError):
                await client.get(url)

        assert request.called is True
        assert respx_mock.stats.call_count == 1
        _request, _response = respx_mock.calls[-1]
        assert _request is not None
        assert _response is None
예제 #19
0
async def test_content_variants(client, key, value, expected_content_type):
    async with MockTransport() as respx_mock:
        url = "https://foo.bar/"
        request = respx_mock.get(url, **{key: value})

        async_response = await client.get(url)
        assert request.called is True
        assert async_response.headers.get(
            "Content-Type") == expected_content_type
        assert async_response.content is not None

        respx_mock.reset()
        sync_response = httpx.get(url)
        assert request.called is True
        assert sync_response.headers.get(
            "Content-Type") == expected_content_type
        assert sync_response.content is not None
예제 #20
0
async def test_repeated_pattern(client):
    async with MockTransport() as respx_mock:
        url = "https://foo/bar/baz/"
        one = respx_mock.post(url, status_code=201)
        two = respx_mock.post(url, status_code=409)

        assert one is two
        assert len(one._responses) == 2

        response1 = await client.post(url, json={})
        response2 = await client.post(url, json={})
        response3 = await client.post(url, json={})

        assert response1.status_code == 201
        assert response2.status_code == 409
        assert response3.status_code == 409
        assert respx_mock.calls.call_count == 3

        assert one.called is True
        assert one.call_count == 3
        statuses = [call.response.status_code for call in one.calls]
        assert statuses == [201, 409, 409]
예제 #21
0
async def test_raising_content(client):
    async with MockTransport() as respx_mock:
        url = "https://foo.bar/"
        request = respx_mock.get(url,
                                 content=httpx.ConnectTimeout("X-P",
                                                              request=None))
        with pytest.raises(httpx.ConnectTimeout):
            await client.get(url)

        assert request.called is True
        _request, _response = request.calls[-1]
        assert _request is not None
        assert _response is None

        # Test httpx exception class get instantiated
        route = respx_mock.get(url).side_effect(httpx.ConnectError)
        with pytest.raises(httpx.ConnectError):
            await client.get(url)

        assert route.called is True
        assert route.calls.last.request is not None
        assert route.calls.last.response is None
예제 #22
0
async def test_repeated_pattern(client):
    async with MockTransport() as respx_mock:
        url = "https://foo/bar/baz/"
        one = respx_mock.post(url, status_code=201)
        two = respx_mock.post(url, status_code=409)
        response1 = await client.post(url, json={})
        response2 = await client.post(url, json={})
        response3 = await client.post(url, json={})

        assert response1.status_code == 201
        assert response2.status_code == 409
        assert response3.status_code == 409
        assert respx_mock.stats.call_count == 3

        assert one.called is True
        assert one.call_count == 1
        statuses = [response.status_code for _, response in one.calls]
        assert statuses == [201]

        assert two.called is True
        assert two.call_count == 2
        statuses = [response.status_code for _, response in two.calls]
        assert statuses == [409, 409]
예제 #23
0
async def test_invalid_url_pattern():
    async with MockTransport() as respx_mock:
        with pytest.raises(AssertionError):
            respx_mock.get(["invalid"])