Skip to content

Commit

Permalink
ci: added more tests and code coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
jfayot committed Aug 4, 2024
1 parent 855a45e commit c14280f
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Debug
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

jobs:
build:
Expand Down Expand Up @@ -40,3 +41,7 @@ jobs:
run: |
cd build
ctest --test-dir ${{github.workspace}}/build/tests --build-config ${{env.BUILD_TYPE}} --output-on-failure
- name: Codecov
run: bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"

25 changes: 25 additions & 0 deletions include/Http/HttpBody.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,31 @@ namespace Http
template <typename ContentType>
ContentType get() const { return json().get<ContentType>(); }

constexpr bool isEmpty() const
{
return std::holds_alternative<TEmpty>(m_content);
}

constexpr bool isText() const
{
return std::holds_alternative<std::string>(m_content);
}

constexpr bool isJson() const
{
return std::holds_alternative<nlohmann::json>(m_content);
}

constexpr bool isPath() const
{
return std::holds_alternative<fs::path>(m_content);
}

constexpr bool isFormData() const
{
return std::holds_alternative<FormData>(m_content);
}

bool save(const fs::path &path) const
{
auto visitor = overloaded{
Expand Down
38 changes: 22 additions & 16 deletions tests/EchoServer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,37 @@ class EchoServer
return res;
};

// Make sure we can handle the method
if (req.method() != http::verb::get)
return send(bad_request("Unknown HTTP-method"));

// Request path must be absolute and not contain "..".
if (req.target().empty() ||
req.target()[0] != '/' ||
req.target().find("..") != beast::string_view::npos)
return send(bad_request("Illegal request-target"));

http::string_body::value_type body = req.body();

// Cache the size since we need it after the move
auto const size = body.size();
auto const size = req.body().size();

// Respond to GET request
http::response<http::string_body> res{
std::piecewise_construct,
std::make_tuple(std::move(body)),
std::make_tuple(http::status::ok, req.version())};
res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
res.set(http::field::content_type, req[http::field::content_type]);
res.content_length(size);
res.keep_alive(req.keep_alive());
return send(std::move(res));
if (size == 0)
{
http::response<http::empty_body> res;
res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
res.content_length(0);
res.keep_alive(req.keep_alive());
return send(std::move(res));
}
else
{
http::string_body::value_type body = req.body();
http::response<http::string_body> res{
std::piecewise_construct,
std::make_tuple(std::move(body)),
std::make_tuple(http::status::ok, req.version())};
res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
res.set(http::field::content_type, req[http::field::content_type]);
res.content_length(size);
res.keep_alive(req.keep_alive());
return send(std::move(res));
}
}

// Report a failure
Expand Down
71 changes: 69 additions & 2 deletions tests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,77 @@ class HttpFixture : public ::testing::Test
std::unique_ptr<Http::Client> client;
};

TEST_F(HttpFixture, test_send_json)
TEST_F(HttpFixture, test_get_empty)
{
auto res = client->get("/").send().get();
ASSERT_TRUE(res.ok());
ASSERT_TRUE(res.body().isEmpty());
}

TEST_F(HttpFixture, test_get_string)
{
std::string body("hello world");
auto res = client->get("/").body(body).send().get();
ASSERT_TRUE(res.ok());
ASSERT_TRUE(res.body().isText());
auto content = res.body().text();
ASSERT_EQ(content, body);
}

TEST_F(HttpFixture, test_get_json)
{
nlohmann::json body = {
{"name", "captain"},
{"age", 42}
};
auto res = client->get("/").body(body).send().get();
ASSERT_TRUE(res.ok());
ASSERT_TRUE(res.body().isJson());
auto content = res.body().json();
ASSERT_EQ(content, body);
}

TEST_F(HttpFixture, test_get_struct)
{
Person body{"captain", 42};
auto res = client->get("/").body(body).send().get();
ASSERT_TRUE(res.ok());
ASSERT_TRUE(res.body().isJson());
auto content = res.body().get<Person>();
ASSERT_EQ(content, body);
}

TEST_F(HttpFixture, test_post_struct)
{
Person person{"captain", 42};
auto res = client->post("/").body(person).send().get();
ASSERT_TRUE(res.ok());
auto content = res.body().get<Person>();
ASSERT_EQ(content, person);
}

TEST_F(HttpFixture, test_put_struct)
{
Person person{"captain", 42};
auto res = client->put("/").body(person).send().get();
ASSERT_TRUE(res.ok());
auto content = res.body().get<Person>();
ASSERT_EQ(content, person);
}

TEST_F(HttpFixture, test_patch_struct)
{
Person person{"captain", 42};
auto res = client->patch("/").body(person).send().get();
ASSERT_TRUE(res.ok());
auto content = res.body().get<Person>();
ASSERT_EQ(content, person);
}

TEST_F(HttpFixture, test_delete_struct)
{
Person person{"captain", 42};
auto res = client->get("/").body(person).send().get();
auto res = client->delete_("/").body(person).send().get();
ASSERT_TRUE(res.ok());
auto content = res.body().get<Person>();
ASSERT_EQ(content, person);
Expand Down

0 comments on commit c14280f

Please sign in to comment.