diff options
| author | Stefan Boberg <[email protected]> | 2025-10-24 19:32:01 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-10-24 19:32:01 +0200 |
| commit | 4cba4eb3f122c7a1a49b629b1c0656d7f817f001 (patch) | |
| tree | e184821073167f6e81a75193efca91013d7b359b /thirdparty/cpr/test/interceptor_multi_tests.cpp | |
| parent | fixed progress bar when scanning changed local files (#608) (diff) | |
| download | zen-4cba4eb3f122c7a1a49b629b1c0656d7f817f001.tar.xz zen-4cba4eb3f122c7a1a49b629b1c0656d7f817f001.zip | |
move cpr in-tree (#605)
* added cpr 1.10.5 in-tree to allow updates to vcpkg without breaking the build
* added asio 1.29.0 in-tree to remove one more vcpkg dependency
* bumped vcpkg to 2024.06.15 to address failure to build due to use of deprecated binaries in vcpkg (404 error: `https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-pkgconf-1~2.1.0-1-any.pkg.tar.zst` during build)
Diffstat (limited to 'thirdparty/cpr/test/interceptor_multi_tests.cpp')
| -rw-r--r-- | thirdparty/cpr/test/interceptor_multi_tests.cpp | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/thirdparty/cpr/test/interceptor_multi_tests.cpp b/thirdparty/cpr/test/interceptor_multi_tests.cpp new file mode 100644 index 000000000..28a0af573 --- /dev/null +++ b/thirdparty/cpr/test/interceptor_multi_tests.cpp @@ -0,0 +1,470 @@ +#include <gtest/gtest.h> +#include <iostream> +#include <memory> + +#include "cpr/cpr.h" +#include "cpr/interceptor.h" +#include "cpr/response.h" +#include "cpr/session.h" +#include "httpServer.hpp" + +using namespace cpr; + +static HttpServer* server = new HttpServer(); + +class HiddenHelloWorldRedirectInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + std::shared_ptr<Session> session = multi.GetSessions().front().first; + + // Save original url + Url old_url = session->GetFullRequestUrl(); + + // Rewrite the url + Url url{server->GetBaseUrl() + "/hello.html"}; + session->SetUrl(url); + + // Proceed the chain + std::vector<Response> response = proceed(multi); + EXPECT_FALSE(response.empty()); + + // Restore the url again + response.front().url = old_url; + return response; + } +}; + +class ChangeStatusCodeInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + std::shared_ptr<Session> session = multi.GetSessions().front().first; + + // Proceed the chain + std::vector<Response> response = proceed(multi); + EXPECT_FALSE(response.empty()); + + // Change the status code + response.front().status_code = 12345; + return response; + } +}; + +class SetBasicAuthInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + std::shared_ptr<Session> session = multi.GetSessions().front().first; + + // Set authentication + session->SetAuth(Authentication{"user", "password", AuthMode::BASIC}); + + // Proceed the chain + return proceed(multi); + } +}; + +class SetUnsupportedProtocolErrorInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + std::shared_ptr<Session> session = multi.GetSessions().front().first; + + // Proceed the chain + std::vector<Response> response = proceed(multi); + EXPECT_FALSE(response.empty()); + + // Set unsupported protocol error + response.front().error = Error{CURLE_UNSUPPORTED_PROTOCOL, "SetErrorInterceptorMulti"}; + + // Return response + return response; + } +}; + +class ChangeRequestMethodToGetInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + multi.GetSessions().front().second = MultiPerform::HttpMethod::GET_REQUEST; + + return proceed(multi); + } +}; + +class ChangeRequestMethodToPostInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + multi.GetSessions().front().second = MultiPerform::HttpMethod::POST_REQUEST; + multi.GetSessions().front().first->SetOption(Payload{{"x", "5"}}); + return proceed(multi); + } +}; + +class ChangeRequestMethodToPutInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + multi.GetSessions().front().second = MultiPerform::HttpMethod::PUT_REQUEST; + multi.GetSessions().front().first->SetOption(Payload{{"x", "5"}}); + return proceed(multi); + } +}; + +class ChangeRequestMethodToDeleteInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + multi.GetSessions().front().second = MultiPerform::HttpMethod::DELETE_REQUEST; + return proceed(multi); + } +}; + +bool write_data(std::string /*data*/, intptr_t /*userdata*/) { + return true; +} + +class ChangeRequestMethodToDownloadCallbackInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + multi.GetSessions().front().second = MultiPerform::HttpMethod::DOWNLOAD_REQUEST; + PrepareDownloadSession(multi, 0, WriteCallback{write_data, 0}); + return proceed(multi); + } +}; + +class ChangeRequestMethodToHeadInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + multi.GetSessions().front().second = MultiPerform::HttpMethod::HEAD_REQUEST; + return proceed(multi); + } +}; + +class ChangeRequestMethodToOptionsInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + multi.GetSessions().front().second = MultiPerform::HttpMethod::OPTIONS_REQUEST; + return proceed(multi); + } +}; + +class ChangeRequestMethodToPatchInterceptorMulti : public InterceptorMulti { + public: + std::vector<Response> intercept(MultiPerform& multi) override { + EXPECT_FALSE(multi.GetSessions().empty()); + multi.GetSessions().front().second = MultiPerform::HttpMethod::PATCH_REQUEST; + multi.GetSessions().front().first->SetOption(Payload{{"x", "5"}}); + return proceed(multi); + } +}; + +TEST(InterceptorMultiTest, HiddenUrlRewriteInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/basic.json"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<HiddenHelloWorldRedirectInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{"Hello world!"}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, ChangeStatusCodeInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/hello.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeStatusCodeInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + long expected_status_code{12345}; + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(expected_status_code, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, DownloadChangeStatusCodeInterceptorMultiTest) { + cpr::Url url{server->GetBaseUrl() + "/download_gzip.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + session->SetHeader(cpr::Header{{"Accept-Encoding", "gzip"}}); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeStatusCodeInterceptorMulti>()); + std::vector<Response> response = multi.Download(cpr::WriteCallback{write_data, 0}); + EXPECT_EQ(response.size(), 1); + + long expected_status_code{12345}; + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(expected_status_code, response.front().status_code); + EXPECT_EQ(cpr::ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, SetBasicAuthInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/basic_auth.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<SetBasicAuthInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{"Header reflect GET"}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(std::string{"text/html"}, response.front().header["content-type"]); + EXPECT_EQ(200, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, SetUnsupportedProtocolErrorInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/hello.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<SetUnsupportedProtocolErrorInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + std::string expected_error_message{"SetErrorInterceptorMulti"}; + ErrorCode expected_error_code{ErrorCode::UNSUPPORTED_PROTOCOL}; + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(std::string{"text/html"}, response.front().header["content-type"]); + EXPECT_EQ(200, response.front().status_code); + EXPECT_EQ(expected_error_message, response.front().error.message); + EXPECT_EQ(expected_error_code, response.front().error.code); +} + +TEST(InterceptorMultiTest, ChangeRequestMethodToGetInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/hello.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeRequestMethodToGetInterceptorMulti>()); + std::vector<Response> response = multi.Head(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{"Hello world!"}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(std::string{"text/html"}, response.front().header["content-type"]); + EXPECT_EQ(200, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, ChangeRequestMethodToPostInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/url_post.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeRequestMethodToPostInterceptorMulti>()); + std::vector<Response> response = multi.Head(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{ + "{\n" + " \"x\": 5\n" + "}"}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(std::string{"application/json"}, response.front().header["content-type"]); + EXPECT_EQ(201, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, ChangeRequestMethodToPutInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/put.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeRequestMethodToPutInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{ + "{\n" + " \"x\": 5\n" + "}"}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(std::string{"application/json"}, response.front().header["content-type"]); + EXPECT_EQ(200, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, ChangeRequestMethodToPatchInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/patch.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeRequestMethodToPatchInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{ + "{\n" + " \"x\": 5\n" + "}"}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(std::string{"application/json"}, response.front().header["content-type"]); + EXPECT_EQ(200, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, ChangeRequestMethodToOptionsInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeRequestMethodToOptionsInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{""}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(std::string{"GET, POST, PUT, DELETE, PATCH, OPTIONS"}, response.front().header["Access-Control-Allow-Methods"]); + EXPECT_EQ(200, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, ChangeRequestMethodToHeadInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/hello.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeRequestMethodToHeadInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + EXPECT_EQ(std::string{}, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(std::string{"text/html"}, response.front().header["content-type"]); + EXPECT_EQ(200, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, ChangeRequestMethodToDownloadCallbackInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/download_gzip.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + session->SetHeader(cpr::Header{{"Accept-Encoding", "gzip"}}); + session->SetTimeout(Timeout{2000}); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeRequestMethodToDownloadCallbackInterceptorMulti>()); + std::vector<Response> response = multi.Put(); + EXPECT_EQ(response.size(), 1); + + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(200, response.front().status_code); + EXPECT_EQ(cpr::ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, ChangeRequestMethodToDownloadCallbackInterceptorMultiMixTest) { + Url url{server->GetBaseUrl() + "/download_gzip.html"}; + std::shared_ptr<Session> session1 = std::make_shared<Session>(); + session1->SetUrl(url); + session1->SetHeader(cpr::Header{{"Accept-Encoding", "gzip"}}); + session1->SetTimeout(Timeout{2000}); + + std::shared_ptr<Session> session2 = std::make_shared<Session>(); + session2->SetUrl(url); + session2->SetHeader(cpr::Header{{"Accept-Encoding", "gzip"}}); + session2->SetTimeout(Timeout{2000}); + + MultiPerform multi; + multi.AddSession(session1); + multi.AddSession(session2); + // Changes only one of two sessions to download, so it is expected to throw an exception here since we can not mix them. + multi.AddInterceptor(std::make_shared<ChangeRequestMethodToDownloadCallbackInterceptorMulti>()); + EXPECT_THROW(multi.Put(), std::invalid_argument); +} + +TEST(InterceptorMultiTest, ChangeRequestMethodToDeleteInterceptorMultiTest) { + Url url{server->GetBaseUrl() + "/delete.html"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<ChangeRequestMethodToDeleteInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{"Delete success"}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(std::string{"text/html"}, response.front().header["content-type"]); + EXPECT_EQ(200, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, TwoInterceptorMultisTest) { + Url url{server->GetBaseUrl() + "/basic.json"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<HiddenHelloWorldRedirectInterceptorMulti>()); + multi.AddInterceptor(std::make_shared<ChangeStatusCodeInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{"Hello world!"}; + long expected_status_code{12345}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(expected_status_code, response.front().status_code); + EXPECT_EQ(ErrorCode::OK, response.front().error.code); +} + +TEST(InterceptorMultiTest, ThreeInterceptorMultisTest) { + Url url{server->GetBaseUrl() + "/basic.json"}; + std::shared_ptr<Session> session = std::make_shared<Session>(); + session->SetUrl(url); + MultiPerform multi; + multi.AddSession(session); + multi.AddInterceptor(std::make_shared<HiddenHelloWorldRedirectInterceptorMulti>()); + multi.AddInterceptor(std::make_shared<ChangeStatusCodeInterceptorMulti>()); + multi.AddInterceptor(std::make_shared<SetUnsupportedProtocolErrorInterceptorMulti>()); + std::vector<Response> response = multi.Get(); + EXPECT_EQ(response.size(), 1); + + std::string expected_text{"Hello world!"}; + long expected_status_code{12345}; + std::string expected_error_message{"SetErrorInterceptorMulti"}; + ErrorCode expected_error_code{ErrorCode::UNSUPPORTED_PROTOCOL}; + EXPECT_EQ(expected_text, response.front().text); + EXPECT_EQ(url, response.front().url); + EXPECT_EQ(expected_status_code, response.front().status_code); + EXPECT_EQ(expected_error_message, response.front().error.message); + EXPECT_EQ(expected_error_code, response.front().error.code); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ::testing::AddGlobalTestEnvironment(server); + return RUN_ALL_TESTS(); +}
\ No newline at end of file |