Skip to content

Commit

Permalink
Replace httpmockserver with cpp-httplib
Browse files Browse the repository at this point in the history
  • Loading branch information
Kicer86 committed Dec 4, 2023
1 parent 28f9a9a commit 4e0d1d7
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 66 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linux-build-qt5.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
libgmock-dev \
qtbase5-dev \
libcurl4-openssl-dev \
libmicrohttpd-dev \
libcpp-httplib-dev \
libjsoncpp-dev
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/linux-build-qt6.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
libgmock-dev \
qt6-base-dev \
libcurl4-openssl-dev \
libmicrohttpd-dev \
libcpp-httplib-dev \
libjsoncpp-dev
- name: Build
Expand Down
1 change: 1 addition & 0 deletions src/qt_backend/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ namespace cpp_restapi::QtBackend
result.first = rawData.data();
result.second = header.toStdString();

reply->close();
reply->deleteLater();

loop.exit();
Expand Down
20 changes: 2 additions & 18 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@

find_package(GTest REQUIRED CONFIG)

include(FetchContent)

FetchContent_Declare(httpmockserver
GIT_REPOSITORY https://github.com/seznam/httpmockserver.git
GIT_TAG 38d4425470aaed56a9d2a4c736500d405e74d2e1
)

set(USE_SYSTEM_CPR FALSE)
set(USE_SYSTEM_GTEST TRUE)
FetchContent_MakeAvailable(httpmockserver)
find_package(httplib REQUIRED)

add_executable(api_tests
api_tests.cpp
Expand All @@ -21,15 +11,9 @@ target_link_libraries(api_tests
PRIVATE
GTest::gtest
GTest::gmock
httpmockserver
microhttpd
httplib::httplib

github_api
)

target_include_directories(api_tests
PRIVATE
${httpmockserver_SOURCE_DIR}/include
)

add_test(NAME api_tests COMMAND api_tests)
45 changes: 16 additions & 29 deletions tests/api_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@

#include <QNetworkAccessManager>
#include <gmock/gmock.h>
#include <httpmockserver/mock_server.h>
#include <httpmockserver/test_environment.h>
#include <httplib.h>

#include "cpp_restapi/curl_connection.hpp"
#include "cpp_restapi/qt_connection.hpp"
Expand Down Expand Up @@ -50,7 +49,7 @@ namespace
}

template<>
std::shared_ptr<IConnection>buildNewApi<GitHub::QtBackend::Api>()
std::shared_ptr<IConnection> buildNewApi<GitHub::QtBackend::Api>()
{
static QNetworkAccessManager networkmanager;
return GitHub::ConnectionBuilder().setAddress(std::string("http://localhost:") + std::to_string(port)).build<QtBackend::Connection>(networkmanager);
Expand All @@ -64,11 +63,11 @@ class ApiTest: public testing::Test
public:
ApiTest(): server(port)
{
server.start();

}

protected:
NiceMock<GithubServerMock> server;
GithubServerMock server;
};

template<typename>
Expand All @@ -92,8 +91,8 @@ TYPED_TEST_SUITE(ApiTest, Backends);

TYPED_TEST(ApiTest, fetchRegularUser)
{
GithubServerMock::Response response(200, R"({"login":"userName1234","id":1234"})");
ON_CALL(this->server, responseHandler).WillByDefault(Return(response));
this->server.responseHandler(".*", 200, R"({"login":"userName1234","id":1234"})");
this->server.listen();

auto api = buildApi<TypeParam>();
auto connection = api.connect();
Expand All @@ -107,8 +106,8 @@ TYPED_TEST(ApiTest, fetchRegularUser)

TYPED_TEST(ApiTest, newInterface)
{
GithubServerMock::Response response(200, R"({"login":"userName1234","id":1234"})");
ON_CALL(this->server, responseHandler).WillByDefault(Return(response));
this->server.responseHandler(".*", 200, R"({"login":"userName1234","id":1234"})");
this->server.listen();

using Connection = typename BackendTraits<TypeParam>::Connection;
auto connection = buildNewApi<TypeParam>();
Expand All @@ -125,19 +124,13 @@ TYPED_TEST(ApiTest, pagination)
auto api = buildApi<TypeParam>();
auto connection = api.connect();

GithubServerMock::Response response1(200, R"({"login":"userName1234","id":1234})");
const std::string secondPage = api.address() + "/url/to/second/page&page=2";
response1.addHeader( {"link", "<" + secondPage + ">; rel=\"next\""} );

GithubServerMock::Response response2(200, R"({"someotherfield":"value"})");
const std::string thirdPage = api.address() + "/url/to/last/page&page=3";
response2.addHeader( {"Link", "<some_previous_page>; rel=\"prev\", <" + thirdPage + ">; rel=\"next\""} );

GithubServerMock::Response response3(200, R"({"more_fields":"value234"})");

ON_CALL(this->server, responseHandler("/users/userName1234", _, _, _, _)).WillByDefault(Return(response1));
ON_CALL(this->server, responseHandler("/url/to/second/page&page=2", _, _, _, _)).WillByDefault(Return(response2));
ON_CALL(this->server, responseHandler("/url/to/last/page&page=3", _, _, _, _)).WillByDefault(Return(response3));
this->server.responseHandler("/users/userName1234", 200, R"({"login":"userName1234","id":1234})", { {"Link", "<" + secondPage + ">; rel=\"next\""} } );
this->server.responseHandler("/url/to/second/page&page=2", 200, R"({"someotherfield":"value"}))", { {"Link", "<some_previous_page>; rel=\"prev\", <" + thirdPage + ">; rel=\"next\""} } );
this->server.responseHandler("/url/to/last/page&page=3", 200, R"({"more_fields":"value234"})");
this->server.listen();

GitHub::Request request(std::move(connection));
const auto info = request.getUserInfo("userName1234");
Expand All @@ -151,19 +144,13 @@ TYPED_TEST(ApiTest, arraysPagination)
auto api = buildApi<TypeParam>();
auto connection = api.connect();

GithubServerMock::Response response1(200, R"([{"login":"userName1234","id":1234}])");
const std::string secondPage = api.address() + "/url/to/second/page&page=2";
response1.addHeader( {"Link", "<" + secondPage + ">; rel=\"next\""} );

GithubServerMock::Response response2(200, R"([{"someotherfield":"value"}])");
const std::string thirdPage = api.address() + "/url/to/last/page&page=3";
response2.addHeader( {"link", "<" + thirdPage + ">; rel=\"next\""} );

GithubServerMock::Response response3(200, R"([{"more_fields":"value234"}])");

ON_CALL(this->server, responseHandler("/users/userName1234", _, _, _, _)).WillByDefault(Return(response1));
ON_CALL(this->server, responseHandler("/url/to/second/page&page=2", _, _, _, _)).WillByDefault(Return(response2));
ON_CALL(this->server, responseHandler("/url/to/last/page&page=3", _, _, _, _)).WillByDefault(Return(response3));
this->server.responseHandler("/users/userName1234", 200, R"([{"login":"userName1234","id":1234}])", { {"Link", "<" + secondPage + ">; rel=\"next\""} } );
this->server.responseHandler("/url/to/second/page&page=2", 200, R"([{"someotherfield":"value"}]))", { {"Link", "<some_previous_page>; rel=\"prev\", <" + thirdPage + ">; rel=\"next\""} } );
this->server.responseHandler("/url/to/last/page&page=3", 200, R"([{"more_fields":"value234"}])");
this->server.listen();

GitHub::Request request(std::move(connection));
const auto info = request.getUserInfo("userName1234");
Expand Down
63 changes: 47 additions & 16 deletions tests/github_server_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,56 @@
#ifndef GITHUB_SERVER_MOCK_HPP_INCLUDED
#define GITHUB_SERVER_MOCK_HPP_INCLUDED


#include <thread>
#include <gmock/gmock.h>
#include <httpmockserver/mock_server.h>
#include <httplib.h>

class GithubServerMock: public httpmock::MockServer {
class GithubServerMock
{
public:
explicit GithubServerMock(int port = 9200): MockServer(port) {}

using httpmock::MockServer::Response;

MOCK_METHOD(Response,
responseHandler,
(const std::string &,
const std::string &,
const std::string &,
const std::vector<UrlArg> &,
const std::vector<Header> &),
(override)
);
explicit GithubServerMock(int port = 9200)
: m_port(port)
{

}

~GithubServerMock()
{
httplib::Client cli("localhost", m_port);
m_svr.stop();

m_svrThread.join();
}

void listen()
{

m_svrThread = std::thread([this]()
{
m_svr.listen("localhost", m_port);
});

// wait for server to be ready
m_svr.wait_until_ready();
}

void responseHandler(const std::string& request, int status, std::string response, const std::map<std::string, std::string>& header = {})
{
assert(not m_svrThread.joinable());

m_svr.Get(request, [response, header](const httplib::Request& req, httplib::Response& res)
{
res.set_content(response, "text/plain");

for (const auto& [key, value]: header)
res.set_header(key, value);
});
}

private:
httplib::Server m_svr;
std::thread m_svrThread;
int m_port;
};

#endif
3 changes: 2 additions & 1 deletion vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"homepage": "https://github.com/Kicer86/github_api",
"description": "This is a c++ library for accessing GitHub REST API v3.",
"dependencies": [
"jsoncpp"
"jsoncpp",
"cpp-httplib"
]
}

0 comments on commit 4e0d1d7

Please sign in to comment.