From 4e0d1d796e34f88b4267ce9f4d12888d4fa9f0f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Walenciak?= Date: Mon, 4 Dec 2023 22:00:58 +0100 Subject: [PATCH] Replace httpmockserver with cpp-httplib --- .github/workflows/linux-build-qt5.yml | 2 +- .github/workflows/linux-build-qt6.yml | 2 +- src/qt_backend/connection.cpp | 1 + tests/CMakeLists.txt | 20 +-------- tests/api_tests.cpp | 45 +++++++------------ tests/github_server_mock.hpp | 63 ++++++++++++++++++++------- vcpkg.json | 3 +- 7 files changed, 70 insertions(+), 66 deletions(-) diff --git a/.github/workflows/linux-build-qt5.yml b/.github/workflows/linux-build-qt5.yml index 7ffd784..eed6e62 100644 --- a/.github/workflows/linux-build-qt5.yml +++ b/.github/workflows/linux-build-qt5.yml @@ -28,7 +28,7 @@ jobs: libgmock-dev \ qtbase5-dev \ libcurl4-openssl-dev \ - libmicrohttpd-dev \ + libcpp-httplib-dev \ libjsoncpp-dev - name: Build diff --git a/.github/workflows/linux-build-qt6.yml b/.github/workflows/linux-build-qt6.yml index ab33d21..fe112e3 100644 --- a/.github/workflows/linux-build-qt6.yml +++ b/.github/workflows/linux-build-qt6.yml @@ -28,7 +28,7 @@ jobs: libgmock-dev \ qt6-base-dev \ libcurl4-openssl-dev \ - libmicrohttpd-dev \ + libcpp-httplib-dev \ libjsoncpp-dev - name: Build diff --git a/src/qt_backend/connection.cpp b/src/qt_backend/connection.cpp index a03ae62..49affc1 100644 --- a/src/qt_backend/connection.cpp +++ b/src/qt_backend/connection.cpp @@ -50,6 +50,7 @@ namespace cpp_restapi::QtBackend result.first = rawData.data(); result.second = header.toStdString(); + reply->close(); reply->deleteLater(); loop.exit(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f9bfefb..2766464 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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 @@ -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) diff --git a/tests/api_tests.cpp b/tests/api_tests.cpp index fa22f87..fb13bc1 100644 --- a/tests/api_tests.cpp +++ b/tests/api_tests.cpp @@ -1,8 +1,7 @@ #include #include -#include -#include +#include #include "cpp_restapi/curl_connection.hpp" #include "cpp_restapi/qt_connection.hpp" @@ -50,7 +49,7 @@ namespace } template<> - std::shared_ptrbuildNewApi() + std::shared_ptr buildNewApi() { static QNetworkAccessManager networkmanager; return GitHub::ConnectionBuilder().setAddress(std::string("http://localhost:") + std::to_string(port)).build(networkmanager); @@ -64,11 +63,11 @@ class ApiTest: public testing::Test public: ApiTest(): server(port) { - server.start(); + } protected: - NiceMock server; + GithubServerMock server; }; template @@ -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(); auto connection = api.connect(); @@ -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::Connection; auto connection = buildNewApi(); @@ -125,19 +124,13 @@ TYPED_TEST(ApiTest, pagination) auto api = buildApi(); 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", "; 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", "; 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"); @@ -151,19 +144,13 @@ TYPED_TEST(ApiTest, arraysPagination) auto api = buildApi(); 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", "; 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"); diff --git a/tests/github_server_mock.hpp b/tests/github_server_mock.hpp index 229ae99..3d937cd 100644 --- a/tests/github_server_mock.hpp +++ b/tests/github_server_mock.hpp @@ -2,25 +2,56 @@ #ifndef GITHUB_SERVER_MOCK_HPP_INCLUDED #define GITHUB_SERVER_MOCK_HPP_INCLUDED - +#include #include -#include +#include -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 &, - const std::vector
&), - (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& 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 diff --git a/vcpkg.json b/vcpkg.json index 10ba070..e6b63d5 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -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" ] }