mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-20 11:45:53 +00:00
@@ -35,6 +35,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
using namespace util::requests;
|
||||
@@ -48,11 +49,13 @@ struct RequestBuilderTestBundle {
|
||||
std::string target;
|
||||
};
|
||||
|
||||
struct RequestBuilderTest : SyncAsioContextTest, testing::WithParamInterface<RequestBuilderTestBundle> {
|
||||
struct RequestBuilderTestBase : SyncAsioContextTest {
|
||||
TestHttpServer server{ctx, "0.0.0.0", 11111};
|
||||
RequestBuilder builder{"localhost", "11111"};
|
||||
};
|
||||
|
||||
struct RequestBuilderTest : RequestBuilderTestBase, testing::WithParamInterface<RequestBuilderTestBundle> {};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
RequestBuilderTest,
|
||||
RequestBuilderTest,
|
||||
@@ -61,7 +64,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||
RequestBuilderTestBundle{
|
||||
"GetWithHeaders",
|
||||
http::verb::get,
|
||||
{{http::field::accept, "text/html"}, {http::field::authorization, "password"}},
|
||||
{{http::field::accept, "text/html"},
|
||||
{http::field::authorization, "password"},
|
||||
{"Custom_header", "some_value"}},
|
||||
"/"
|
||||
},
|
||||
RequestBuilderTestBundle{"GetWithTarget", http::verb::get, {}, "/test"},
|
||||
@@ -69,7 +74,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||
RequestBuilderTestBundle{
|
||||
"PostWithHeaders",
|
||||
http::verb::post,
|
||||
{{http::field::accept, "text/html"}, {http::field::authorization, "password"}},
|
||||
{{http::field::accept, "text/html"},
|
||||
{http::field::authorization, "password"},
|
||||
{"Custom_header", "some_value"}},
|
||||
"/"
|
||||
},
|
||||
RequestBuilderTestBundle{"PostWithTarget", http::verb::post, {}, "/test"}
|
||||
@@ -86,8 +93,18 @@ TEST_P(RequestBuilderTest, SimpleRequest)
|
||||
server.handleRequest(
|
||||
[&replyBody](http::request<http::string_body> request) -> std::optional<http::response<http::string_body>> {
|
||||
[&]() {
|
||||
ASSERT_TRUE(request.target() == GetParam().target);
|
||||
ASSERT_TRUE(request.method() == GetParam().method);
|
||||
EXPECT_TRUE(request.target() == GetParam().target);
|
||||
EXPECT_TRUE(request.method() == GetParam().method);
|
||||
for (auto const& header : GetParam().headers) {
|
||||
std::visit(
|
||||
[&](auto const& name) {
|
||||
auto it = request.find(name);
|
||||
ASSERT_NE(it, request.end());
|
||||
EXPECT_EQ(it->value(), header.value);
|
||||
},
|
||||
header.name
|
||||
);
|
||||
}
|
||||
}();
|
||||
return http::response<http::string_body>{http::status::ok, 11, replyBody};
|
||||
}
|
||||
@@ -97,14 +114,14 @@ TEST_P(RequestBuilderTest, SimpleRequest)
|
||||
auto const response = [&]() -> util::Expected<std::string, RequestError> {
|
||||
switch (GetParam().method) {
|
||||
case http::verb::get:
|
||||
return builder.get(yield);
|
||||
return builder.getPlain(yield);
|
||||
case http::verb::post:
|
||||
return builder.post(yield);
|
||||
return builder.postPlain(yield);
|
||||
default:
|
||||
return util::Unexpected{RequestError{"Invalid HTTP verb"}};
|
||||
}
|
||||
}();
|
||||
ASSERT_TRUE(response) << response.error().message;
|
||||
ASSERT_TRUE(response) << response.error().message();
|
||||
EXPECT_EQ(response.value(), replyBody);
|
||||
});
|
||||
}
|
||||
@@ -123,7 +140,7 @@ TEST_F(RequestBuilderTest, Timeout)
|
||||
}
|
||||
);
|
||||
runSpawn([this](asio::yield_context yield) {
|
||||
auto response = builder.get(yield);
|
||||
auto response = builder.getPlain(yield);
|
||||
EXPECT_FALSE(response);
|
||||
});
|
||||
}
|
||||
@@ -147,8 +164,8 @@ TEST_F(RequestBuilderTest, RequestWithBody)
|
||||
);
|
||||
|
||||
runSpawn([&](asio::yield_context yield) {
|
||||
auto const response = builder.get(yield);
|
||||
ASSERT_TRUE(response) << response.error().message;
|
||||
auto const response = builder.getPlain(yield);
|
||||
ASSERT_TRUE(response) << response.error().message();
|
||||
EXPECT_EQ(response.value(), replyBody) << response.value();
|
||||
});
|
||||
}
|
||||
@@ -157,9 +174,9 @@ TEST_F(RequestBuilderTest, ResolveError)
|
||||
{
|
||||
builder = RequestBuilder{"wrong_host", "11111"};
|
||||
runSpawn([this](asio::yield_context yield) {
|
||||
auto const response = builder.get(yield);
|
||||
auto const response = builder.getPlain(yield);
|
||||
ASSERT_FALSE(response);
|
||||
EXPECT_TRUE(response.error().message.starts_with("Resolve error")) << response.error().message;
|
||||
EXPECT_TRUE(response.error().message().starts_with("Resolve error")) << response.error().message();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -168,21 +185,75 @@ TEST_F(RequestBuilderTest, ConnectionError)
|
||||
builder = RequestBuilder{"localhost", "11112"};
|
||||
builder.setTimeout(std::chrono::milliseconds{1});
|
||||
runSpawn([this](asio::yield_context yield) {
|
||||
auto const response = builder.get(yield);
|
||||
auto const response = builder.getPlain(yield);
|
||||
ASSERT_FALSE(response);
|
||||
EXPECT_TRUE(response.error().message.starts_with("Connection error")) << response.error().message;
|
||||
EXPECT_TRUE(response.error().message().starts_with("Connection error")) << response.error().message();
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RequestBuilderTest, WritingError)
|
||||
TEST_F(RequestBuilderTest, ResponseStatusIsNotOk)
|
||||
{
|
||||
server.handleRequest([](auto&&) -> std::optional<http::response<http::string_body>> {
|
||||
return http::response<http::string_body>{http::status::not_found, 11, "Not found"};
|
||||
});
|
||||
|
||||
runSpawn([this](asio::yield_context yield) {
|
||||
auto const response = builder.getPlain(yield);
|
||||
ASSERT_FALSE(response);
|
||||
EXPECT_TRUE(response.error().message().starts_with("Response status is not OK")) << response.error().message();
|
||||
});
|
||||
}
|
||||
|
||||
struct RequestBuilderSslTestBundle {
|
||||
std::string testName;
|
||||
boost::beast::http::verb method;
|
||||
};
|
||||
|
||||
struct RequestBuilderSslTest : RequestBuilderTestBase, testing::WithParamInterface<RequestBuilderSslTestBundle> {};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
RequestBuilderSslTest,
|
||||
RequestBuilderSslTest,
|
||||
testing::Values(
|
||||
RequestBuilderSslTestBundle{"Get", http::verb::get},
|
||||
RequestBuilderSslTestBundle{"Post", http::verb::post}
|
||||
),
|
||||
[](auto const& info) { return info.param.testName; }
|
||||
);
|
||||
|
||||
TEST_P(RequestBuilderSslTest, TrySslUsePlain)
|
||||
{
|
||||
// First try will be SSL, but the server can't handle SSL requests
|
||||
server.handleRequest(
|
||||
[](http::request<http::string_body> request) -> std::optional<http::response<http::string_body>> {
|
||||
[](auto&&) -> std::optional<http::response<http::string_body>> {
|
||||
[]() { FAIL(); }();
|
||||
return std::nullopt;
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
server.handleRequest(
|
||||
[&](http::request<http::string_body> request) -> std::optional<http::response<http::string_body>> {
|
||||
[&]() {
|
||||
EXPECT_EQ(request.target(), "/");
|
||||
EXPECT_EQ(request.method(), http::verb::get);
|
||||
EXPECT_EQ(request.method(), GetParam().method);
|
||||
}();
|
||||
return std::nullopt;
|
||||
return http::response<http::string_body>{http::status::ok, 11, "Hello, world!"};
|
||||
}
|
||||
);
|
||||
|
||||
runSpawn([this](asio::yield_context yield) {
|
||||
auto const response = [&]() -> util::Expected<std::string, RequestError> {
|
||||
switch (GetParam().method) {
|
||||
case http::verb::get:
|
||||
return builder.get(yield);
|
||||
case http::verb::post:
|
||||
return builder.post(yield);
|
||||
default:
|
||||
return util::Unexpected{RequestError{"Invalid HTTP verb"}};
|
||||
}
|
||||
}();
|
||||
ASSERT_TRUE(response) << response.error().message();
|
||||
EXPECT_EQ(response.value(), "Hello, world!");
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user