|
17 | 17 | //==============================================================================
|
18 | 18 |
|
19 | 19 | #include "rpc/Errors.hpp"
|
| 20 | +#include "rpc/common/APIVersion.hpp" |
20 | 21 | #include "rpc/common/Types.hpp"
|
21 | 22 | #include "util/AsioContextTestFixture.hpp"
|
22 | 23 | #include "util/MockBackendTestFixture.hpp"
|
23 | 24 | #include "util/MockETLService.hpp"
|
24 | 25 | #include "util/MockPrometheus.hpp"
|
25 | 26 | #include "util/MockRPCEngine.hpp"
|
| 27 | +#include "util/NameGenerator.hpp" |
26 | 28 | #include "util/Taggable.hpp"
|
27 | 29 | #include "util/config/Config.hpp"
|
28 | 30 | #include "web/RPCServerHandler.hpp"
|
29 | 31 | #include "web/interface/ConnectionBase.hpp"
|
30 | 32 |
|
31 | 33 | #include <boost/beast/http/status.hpp>
|
32 | 34 | #include <boost/json/parse.hpp>
|
| 35 | +#include <fmt/core.h> |
33 | 36 | #include <gmock/gmock.h>
|
34 | 37 | #include <gtest/gtest.h>
|
35 | 38 |
|
| 39 | +#include <cstdint> |
36 | 40 | #include <memory>
|
37 | 41 | #include <stdexcept>
|
38 | 42 | #include <string>
|
| 43 | +#include <vector> |
39 | 44 |
|
40 | 45 | using namespace web;
|
41 | 46 |
|
42 |
| -constexpr static auto MINSEQ = 10; |
43 |
| -constexpr static auto MAXSEQ = 30; |
| 47 | +namespace { |
| 48 | + |
| 49 | +constexpr auto MINSEQ = 10; |
| 50 | +constexpr auto MAXSEQ = 30; |
44 | 51 |
|
45 | 52 | struct MockWsBase : public web::ConnectionBase {
|
46 | 53 | std::string message;
|
@@ -466,54 +473,6 @@ TEST_F(WebRPCServerHandlerTest, WsNotReady)
|
466 | 473 | EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
467 | 474 | }
|
468 | 475 |
|
469 |
| -TEST_F(WebRPCServerHandlerTest, HTTPInvalidAPIVersion) |
470 |
| -{ |
471 |
| - static auto constexpr request = R"({ |
472 |
| - "method": "server_info", |
473 |
| - "params": [{ |
474 |
| - "api_version": null |
475 |
| - }] |
476 |
| - })"; |
477 |
| - |
478 |
| - backend->setRange(MINSEQ, MAXSEQ); |
479 |
| - |
480 |
| - static auto constexpr response = "invalid_API_version"; |
481 |
| - |
482 |
| - EXPECT_CALL(*rpcEngine, notifyBadSyntax).Times(1); |
483 |
| - |
484 |
| - (*handler)(request, session); |
485 |
| - EXPECT_EQ(session->message, response); |
486 |
| - EXPECT_EQ(session->lastStatus, boost::beast::http::status::bad_request); |
487 |
| -} |
488 |
| - |
489 |
| -TEST_F(WebRPCServerHandlerTest, WSInvalidAPIVersion) |
490 |
| -{ |
491 |
| - session->upgraded = true; |
492 |
| - static auto constexpr request = R"({ |
493 |
| - "method": "server_info", |
494 |
| - "api_version": null |
495 |
| - })"; |
496 |
| - |
497 |
| - backend->setRange(MINSEQ, MAXSEQ); |
498 |
| - |
499 |
| - static auto constexpr response = R"({ |
500 |
| - "error": "invalid_API_version", |
501 |
| - "error_code": 6000, |
502 |
| - "error_message": "API version must be an integer", |
503 |
| - "status": "error", |
504 |
| - "type": "response", |
505 |
| - "request": { |
506 |
| - "method": "server_info", |
507 |
| - "api_version": null |
508 |
| - } |
509 |
| - })"; |
510 |
| - |
511 |
| - EXPECT_CALL(*rpcEngine, notifyBadSyntax).Times(1); |
512 |
| - |
513 |
| - (*handler)(request, session); |
514 |
| - EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response)); |
515 |
| -} |
516 |
| - |
517 | 476 | TEST_F(WebRPCServerHandlerTest, HTTPBadSyntaxWhenRequestSubscribe)
|
518 | 477 | {
|
519 | 478 | static auto constexpr request = R"({"method": "subscribe"})";
|
@@ -872,3 +831,84 @@ TEST_F(WebRPCServerHandlerTest, WsRequestNotJson)
|
872 | 831 | (*handler)(request, session);
|
873 | 832 | EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
874 | 833 | }
|
| 834 | + |
| 835 | +struct InvalidAPIVersionTestBundle { |
| 836 | + std::string testName; |
| 837 | + std::string version; |
| 838 | + std::string wsMessage; |
| 839 | +}; |
| 840 | + |
| 841 | +// parameterized test cases for parameters check |
| 842 | +struct WebRPCServerHandlerInvalidAPIVersionParamTest : public WebRPCServerHandlerTest, |
| 843 | + public testing::WithParamInterface<InvalidAPIVersionTestBundle> { |
| 844 | +}; |
| 845 | + |
| 846 | +auto |
| 847 | +generateInvalidVersions() |
| 848 | +{ |
| 849 | + return std::vector<InvalidAPIVersionTestBundle>{ |
| 850 | + {"v0", "0", fmt::format("Requested API version is lower than minimum supported ({})", rpc::API_VERSION_MIN)}, |
| 851 | + {"v4", "4", fmt::format("Requested API version is higher than maximum supported ({})", rpc::API_VERSION_MAX)}, |
| 852 | + {"null", "null", "API version must be an integer"}, |
| 853 | + {"str", "\"bogus\"", "API version must be an integer"}, |
| 854 | + {"bool", "false", "API version must be an integer"}, |
| 855 | + {"double", "12.34", "API version must be an integer"}, |
| 856 | + }; |
| 857 | +} |
| 858 | + |
| 859 | +INSTANTIATE_TEST_CASE_P( |
| 860 | + WebRPCServerHandlerAPIVersionGroup, |
| 861 | + WebRPCServerHandlerInvalidAPIVersionParamTest, |
| 862 | + testing::ValuesIn(generateInvalidVersions()), |
| 863 | + tests::util::NameGenerator |
| 864 | +); |
| 865 | + |
| 866 | +TEST_P(WebRPCServerHandlerInvalidAPIVersionParamTest, HTTPInvalidAPIVersion) |
| 867 | +{ |
| 868 | + auto request = fmt::format( |
| 869 | + R"({{ |
| 870 | + "method": "server_info", |
| 871 | + "params": [{{ |
| 872 | + "api_version": {} |
| 873 | + }}] |
| 874 | + }})", |
| 875 | + GetParam().version |
| 876 | + ); |
| 877 | + |
| 878 | + backend->setRange(MINSEQ, MAXSEQ); |
| 879 | + |
| 880 | + EXPECT_CALL(*rpcEngine, notifyBadSyntax).Times(1); |
| 881 | + |
| 882 | + (*handler)(request, session); |
| 883 | + EXPECT_EQ(session->message, "invalid_API_version"); |
| 884 | + EXPECT_EQ(session->lastStatus, boost::beast::http::status::bad_request); |
| 885 | +} |
| 886 | + |
| 887 | +TEST_P(WebRPCServerHandlerInvalidAPIVersionParamTest, WSInvalidAPIVersion) |
| 888 | +{ |
| 889 | + session->upgraded = true; |
| 890 | + auto request = fmt::format( |
| 891 | + R"({{ |
| 892 | + "method": "server_info", |
| 893 | + "api_version": {} |
| 894 | + }})", |
| 895 | + GetParam().version |
| 896 | + ); |
| 897 | + |
| 898 | + backend->setRange(MINSEQ, MAXSEQ); |
| 899 | + |
| 900 | + EXPECT_CALL(*rpcEngine, notifyBadSyntax).Times(1); |
| 901 | + |
| 902 | + (*handler)(request, session); |
| 903 | + |
| 904 | + auto response = boost::json::parse(session->message); |
| 905 | + EXPECT_TRUE(response.is_object()); |
| 906 | + EXPECT_TRUE(response.as_object().contains("error")); |
| 907 | + EXPECT_EQ(response.at("error").as_string(), "invalid_API_version"); |
| 908 | + EXPECT_TRUE(response.as_object().contains("error_message")); |
| 909 | + EXPECT_EQ(response.at("error_message").as_string(), GetParam().wsMessage); |
| 910 | + EXPECT_TRUE(response.as_object().contains("error_code")); |
| 911 | + EXPECT_EQ(response.at("error_code").as_int64(), static_cast<int64_t>(rpc::ClioError::rpcINVALID_API_VERSION)); |
| 912 | +} |
| 913 | + |
| 914 | +} // namespace |
0 commit comments