async def test_pass_through(client, using, route, expected): async with MockRouter(using=using) as respx_mock: request = respx_mock.add(route) 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 MockRouter(using=using) as respx_mock: request = respx_mock.add(route) 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
async def test_list_services_with_details( mock_catalog_background_task, director_mockup: MockRouter, client: TestClient, user_id: int, products_names: List[str], service_catalog_faker: Callable, services_db_tables_injector: Callable, benchmark, ): target_product = products_names[-1] # create some fake services NUM_SERVICES = 1000 fake_services = [ service_catalog_faker( "simcore/services/dynamic/jupyterlab", f"1.0.{s}", team_access=None, everyone_access=None, product=target_product, ) for s in range(NUM_SERVICES) ] # injects fake data in db await services_db_tables_injector(fake_services) url = URL("/v0/services").with_query({ "user_id": user_id, "details": "true" }) # now fake the director such that it returns half the services fake_registry_service_data = ServiceDockerData.Config.schema_extra[ "examples"][0] director_mockup.get("/services", name="list_services").respond( 200, json={ "data": [{ **fake_registry_service_data, **{ "key": s[0]["key"], "version": s[0]["version"] }, } for s in fake_services[::2]] }, ) response = benchmark(client.get, f"{url}", headers={"x-simcore-products-name": target_product}) assert response.status_code == 200 data = response.json() assert len(data) == round(NUM_SERVICES / 2)
async def test_assert_all_mocked(client, assert_all_mocked, raises): with raises: with MockRouter(assert_all_mocked=assert_all_mocked) as respx_mock: response = httpx.get("https://foo.bar/") assert respx_mock.calls.call_count == 1 assert response.status_code == 200 with raises: async with MockRouter(assert_all_mocked=assert_all_mocked) as respx_mock: response = await client.get("https://foo.bar/") assert respx_mock.calls.call_count == 1 assert response.status_code == 200 assert respx_mock.calls.call_count == 0
async def test_url_match(client, url, pattern): async with MockRouter(assert_all_mocked=False) as respx_mock: request = respx_mock.get(pattern) % dict(content="baz") response = await client.get(url) assert request.called is True assert response.status_code == 200 assert response.text == "baz"
async def test_named_route(): async with MockRouter(assert_all_called=False) as respx_mock: request = respx_mock.get("https://foo.bar/", name="foobar") assert "foobar" not in respx.routes assert "foobar" in respx_mock.routes assert respx_mock.routes["foobar"] is request assert respx_mock["foobar"] is request
async def test_text_encoding(client, content, expected): async with MockRouter() as respx_mock: url = "https://foo.bar/" request = respx_mock.post(url) % dict(content=content) response = await client.post(url) assert request.called is True assert response.text == expected
async def test_headers(client, headers, content_type, expected): async with MockRouter() as respx_mock: url = "https://foo.bar/" request = respx_mock.get(url).respond(headers=headers, content_type=content_type) response = await client.get(url) assert request.called is True assert response.headers == httpx.Headers(expected)
async def test_status_code(client): async with MockRouter() as respx_mock: url = "https://foo.bar/" request = respx_mock.get(url) % 404 response = await client.get(url) assert request.called is True assert response.status_code == 404
async def test_method_case(client, method_str, client_method_attr): url = "https://example.org/" content = {"spam": "lots", "ham": "no, only spam"} async with MockRouter() as respx_mock: request = respx_mock.route(method=method_str, url=url) % dict(json=content) response = await getattr(client, client_method_attr)(url) assert request.called is True assert response.json() == content
async def test_assert_all_called(client, assert_all_called, do_post, raises): with raises: async with MockRouter(assert_all_called=assert_all_called) as respx_mock: request1 = respx_mock.get("https://foo.bar/1/") % 404 request2 = respx_mock.post("https://foo.bar/") % 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
async def test_json_content(client, content, headers, expected_headers): async with MockRouter() as respx_mock: url = "https://foo.bar/" request = respx_mock.get(url) % dict(json=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
async def test_content_variants(client, key, value, expected_content_type): async with MockRouter() 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
async def test_httpcore_request(url, port): async with MockRouter(using="httpcore") as router: router.get(url) % dict(text="foobar") request = httpcore.Request( b"GET", httpcore.URL(scheme=b"https", host=b"foo.bar", port=port, target=b"/"), ) with httpcore.ConnectionPool() as http: response = http.handle_request(request) body = response.read() assert body == b"foobar" async with httpcore.AsyncConnectionPool() as http: response = await http.handle_async_request(request) body = await response.aread() assert body == b"foobar"
async def test_request_callback(client): def callback(request, name): if request.url.host == "foo.bar" and request.content == b'{"foo": "bar"}': return respx.MockResponse( 202, headers={"X-Foo": "bar"}, text=f"hello {name}", http_version="HTTP/2", ) return httpx.Response(404) async with MockRouter(assert_all_called=False) as respx_mock: request = respx_mock.post(host="foo.bar", path__regex=r"/(?P<name>\w+)/") request.side_effect = callback response = await client.post("https://foo.bar/lundberg/") assert response.status_code == 404 response = await client.post("https://foo.bar/lundberg/", json={"foo": "bar"}) assert request.called is True assert not request.is_pass_through 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-Foo": "bar", }) assert response.text == "hello lundberg" with pytest.raises(TypeError): respx_mock.get("https://ham.spam/").mock( side_effect=lambda req: "invalid") await client.get("https://ham.spam/") with pytest.raises(httpx.NetworkError): def _callback(request): raise httpcore.NetworkError() respx_mock.get("https://egg.plant").mock(side_effect=_callback) await client.get("https://egg.plant/")
async def test_httpcore_request(url, port): async with MockRouter(using="httpcore") as router: router.get(url) % dict(text="foobar") with httpcore.SyncConnectionPool() as http: (status_code, headers, stream, ext) = http.handle_request( method=b"GET", url=(b"https", b"foo.bar", port, b"/") ) body = b"".join([chunk for chunk in stream]) assert body == b"foobar" async with httpcore.AsyncConnectionPool() as http: (status_code, headers, stream, ext) = await http.handle_async_request( method=b"GET", url=(b"https", b"foo.bar", port, b"/") ) body = b"".join([chunk async for chunk in stream]) assert body == b"foobar"
async def test_raising_content(client): async with MockRouter() as respx_mock: url = "https://foo.bar/" request = respx_mock.get(url) request.side_effect = 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).mock(side_effect=httpx.ConnectError) with pytest.raises(httpx.ConnectError): await client.get(url) assert route.call_count == 2 assert route.calls.last.request is not None assert route.calls.last.response is None
async def test_repeated_pattern(client): async with MockRouter() as respx_mock: url = "https://foo/bar/baz/" route = respx_mock.post(url) route.side_effect = [ httpx.Response(201), httpx.Response(409), ] response1 = await client.post(url, json={}) response2 = await client.post(url, json={}) with pytest.raises(RuntimeError): await client.post(url, json={}) assert response1.status_code == 201 assert response2.status_code == 409 assert respx_mock.calls.call_count == 2 assert route.called is True assert route.call_count == 2 statuses = [call.response.status_code for call in route.calls] assert statuses == [201, 409]
async def test_callable_content(client): async with MockRouter() as respx_mock: url_pattern = re.compile(r"https://foo.bar/(?P<slug>\w+)/") def content_callback(request, slug): content = jsonlib.loads(request.content) return respx.MockResponse(text=f"hello {slug}{content['x']}") request = respx_mock.post(url_pattern) request.side_effect = 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": "!"}'
async def test_invalid_url_pattern(): async with MockRouter() as respx_mock: with pytest.raises(TypeError): respx_mock.get(["invalid"])