chore: Use libxrpl 3.2.0 (#3095)

This commit is contained in:
Sergey Kuznetsov
2026-06-05 17:48:07 +01:00
committed by GitHub
parent 6bb4953f16
commit 8f3afd09e6
272 changed files with 5916 additions and 6036 deletions

View File

@@ -47,20 +47,18 @@ using namespace rpc::validation;
using namespace rpc::meta;
using namespace rpc::modifiers;
namespace json = boost::json;
class RPCBaseTest : public virtual ::testing::Test {};
TEST_F(RPCBaseTest, CheckTypeString)
{
auto const jString = json::value("a string");
auto const jString = boost::json::value("a string");
ASSERT_TRUE(checkType<string>(jString));
ASSERT_FALSE(checkType<int>(jString));
}
TEST_F(RPCBaseTest, CheckTypeUint)
{
auto const jUint = json::value(123u);
auto const jUint = boost::json::value(123u);
ASSERT_TRUE(checkType<uint32_t>(jUint));
ASSERT_TRUE(checkType<int32_t>(jUint));
ASSERT_FALSE(checkType<bool>(jUint));
@@ -68,12 +66,12 @@ TEST_F(RPCBaseTest, CheckTypeUint)
TEST_F(RPCBaseTest, CheckTypeInt)
{
auto jInt = json::value(123);
auto jInt = boost::json::value(123);
ASSERT_TRUE(checkType<int32_t>(jInt));
ASSERT_TRUE(checkType<uint32_t>(jInt));
ASSERT_FALSE(checkType<bool>(jInt));
jInt = json::value(-123);
jInt = boost::json::value(-123);
ASSERT_TRUE(checkType<int32_t>(jInt));
ASSERT_FALSE(checkType<uint32_t>(jInt)); // Unsigned can't be negative
ASSERT_FALSE(checkType<bool>(jInt));
@@ -81,14 +79,14 @@ TEST_F(RPCBaseTest, CheckTypeInt)
TEST_F(RPCBaseTest, CheckTypeBool)
{
auto const jBool = json::value(true);
auto const jBool = boost::json::value(true);
ASSERT_TRUE(checkType<bool>(jBool));
ASSERT_FALSE(checkType<int>(jBool));
}
TEST_F(RPCBaseTest, CheckTypeDouble)
{
auto const jDouble = json::value(0.123);
auto const jDouble = boost::json::value(0.123);
ASSERT_TRUE(checkType<double>(jDouble));
ASSERT_TRUE(checkType<float>(jDouble));
ASSERT_FALSE(checkType<bool>(jDouble));
@@ -96,50 +94,50 @@ TEST_F(RPCBaseTest, CheckTypeDouble)
TEST_F(RPCBaseTest, CheckTypeArray)
{
auto const jArr = json::value({1, 2, 3});
ASSERT_TRUE(checkType<json::array>(jArr));
auto const jArr = boost::json::value({1, 2, 3});
ASSERT_TRUE(checkType<boost::json::array>(jArr));
ASSERT_FALSE(checkType<int>(jArr));
}
TEST_F(RPCBaseTest, CheckTypeAndClampValueUnchanged)
{
auto jUint = json::value(123u);
auto jUint = boost::json::value(123u);
ASSERT_TRUE(checkTypeAndClamp<uint32_t>(jUint));
ASSERT_EQ(jUint.as_uint64(), 123u);
ASSERT_TRUE(checkTypeAndClamp<int32_t>(jUint));
ASSERT_EQ(jUint.as_uint64(), 123u);
auto jInt = json::value(123);
auto jInt = boost::json::value(123);
ASSERT_TRUE(checkTypeAndClamp<int32_t>(jInt));
ASSERT_EQ(jInt.as_int64(), 123);
ASSERT_TRUE(checkTypeAndClamp<uint32_t>(jInt));
ASSERT_EQ(jInt.as_int64(), 123);
jInt = json::value(-123);
jInt = boost::json::value(-123);
ASSERT_TRUE(checkTypeAndClamp<int32_t>(jInt));
ASSERT_EQ(jInt.as_int64(), -123);
}
TEST_F(RPCBaseTest, CheckTypeAndClampInvalidValues)
{
auto jInt = json::value(-123);
auto jInt = boost::json::value(-123);
ASSERT_FALSE(checkTypeAndClamp<uint32_t>(jInt)); // Unsigned can't be negative
}
TEST_F(RPCBaseTest, CheckTypeAndClampOverflow)
{
auto jBigUint = json::value(std::numeric_limits<uint64_t>::max());
auto jBigUint = boost::json::value(std::numeric_limits<uint64_t>::max());
ASSERT_TRUE(checkTypeAndClamp<uint32_t>(jBigUint));
ASSERT_EQ(jBigUint.as_uint64(), std::numeric_limits<uint32_t>::max());
auto jBigInt = json::value(std::numeric_limits<int64_t>::max());
auto jBigInt = boost::json::value(std::numeric_limits<int64_t>::max());
ASSERT_TRUE(checkTypeAndClamp<int32_t>(jBigInt));
ASSERT_EQ(jBigInt.as_int64(), std::numeric_limits<int32_t>::max());
}
TEST_F(RPCBaseTest, CheckTypeAndClampUnderflow)
{
auto jLowInt = json::value(std::numeric_limits<int64_t>::min());
auto jLowInt = boost::json::value(std::numeric_limits<int64_t>::min());
ASSERT_TRUE(checkTypeAndClamp<int32_t>(jLowInt));
ASSERT_EQ(jLowInt.as_int64(), std::numeric_limits<int32_t>::min());
}
@@ -152,10 +150,10 @@ TEST_F(RPCBaseTest, TypeValidator)
{"str", Type<string>{}},
{"double", Type<double>{}},
{"bool", Type<bool>{}},
{"arr", Type<json::array>{}},
{"arr", Type<boost::json::array>{}},
};
auto passingInput = json::parse(R"JSON({
auto passingInput = boost::json::parse(R"JSON({
"uint": 123,
"int": 321,
"str": "a string",
@@ -166,27 +164,27 @@ TEST_F(RPCBaseTest, TypeValidator)
ASSERT_TRUE(spec.process(passingInput));
{
auto failingInput = json::parse(R"JSON({ "uint": "a string" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "uint": "a string" })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
{
auto failingInput = json::parse(R"JSON({ "int": "a string" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "int": "a string" })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
{
auto failingInput = json::parse(R"JSON({ "str": 1234 })JSON");
auto failingInput = boost::json::parse(R"JSON({ "str": 1234 })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
{
auto failingInput = json::parse(R"JSON({ "double": "a string" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "double": "a string" })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
{
auto failingInput = json::parse(R"JSON({ "bool": "a string" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "bool": "a string" })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
{
auto failingInput = json::parse(R"JSON({ "arr": "a string" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "arr": "a string" })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
}
@@ -198,13 +196,13 @@ TEST_F(RPCBaseTest, TypeValidatorMultipleTypes)
{"test", Type<uint32_t, string>{}},
};
auto passingInput = json::parse(R"JSON({ "test": "1234" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "test": "1234" })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto passingInput2 = json::parse(R"JSON({ "test": 1234 })JSON");
auto passingInput2 = boost::json::parse(R"JSON({ "test": 1234 })JSON");
ASSERT_TRUE(spec.process(passingInput2));
auto failingInput = json::parse(R"JSON({ "test": true })JSON");
auto failingInput = boost::json::parse(R"JSON({ "test": true })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -214,13 +212,13 @@ TEST_F(RPCBaseTest, RequiredValidator)
{"required", Required{}},
};
auto passingInput = json::parse(R"JSON({ "required": "present" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "required": "present" })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto passingInput2 = json::parse(R"JSON({ "required": true })JSON");
auto passingInput2 = boost::json::parse(R"JSON({ "required": true })JSON");
ASSERT_TRUE(spec.process(passingInput2));
auto failingInput = json::parse(R"JSON({})JSON");
auto failingInput = boost::json::parse(R"JSON({})JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -230,19 +228,19 @@ TEST_F(RPCBaseTest, BetweenValidator)
{"amount", Between<uint32_t>{10u, 20u}},
};
auto passingInput = json::parse(R"JSON({ "amount": 15 })JSON");
auto passingInput = boost::json::parse(R"JSON({ "amount": 15 })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto passingInput2 = json::parse(R"JSON({ "amount": 10 })JSON");
auto passingInput2 = boost::json::parse(R"JSON({ "amount": 10 })JSON");
ASSERT_TRUE(spec.process(passingInput2));
auto passingInput3 = json::parse(R"JSON({ "amount": 20 })JSON");
auto passingInput3 = boost::json::parse(R"JSON({ "amount": 20 })JSON");
ASSERT_TRUE(spec.process(passingInput3));
auto failingInput = json::parse(R"JSON({ "amount": 9 })JSON");
auto failingInput = boost::json::parse(R"JSON({ "amount": 9 })JSON");
ASSERT_FALSE(spec.process(failingInput));
auto failingInput2 = json::parse(R"JSON({ "amount": 21 })JSON");
auto failingInput2 = boost::json::parse(R"JSON({ "amount": 21 })JSON");
ASSERT_FALSE(spec.process(failingInput2));
}
@@ -252,13 +250,13 @@ TEST_F(RPCBaseTest, MinValidator)
{"amount", Min{6}},
};
auto passingInput = json::parse(R"JSON({ "amount": 7 })JSON");
auto passingInput = boost::json::parse(R"JSON({ "amount": 7 })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto passingInput2 = json::parse(R"JSON({ "amount": 6 })JSON");
auto passingInput2 = boost::json::parse(R"JSON({ "amount": 6 })JSON");
ASSERT_TRUE(spec.process(passingInput2));
auto failingInput = json::parse(R"JSON({ "amount": 5 })JSON");
auto failingInput = boost::json::parse(R"JSON({ "amount": 5 })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -270,7 +268,8 @@ TEST_F(RPCBaseTest, MinValidatorAfterType)
{"amount3", Type<std::int32_t>{}, Min{std::numeric_limits<int32_t>::min()}},
};
auto bigInput = json::parse(R"JSON({ "amount": 9999999999, "amount2": 9999999999, "amount3": -9999999999 })JSON");
auto bigInput =
boost::json::parse(R"JSON({ "amount": 9999999999, "amount2": 9999999999, "amount3": -9999999999 })JSON");
ASSERT_TRUE(spec.process(bigInput)); // type check clamps to type's max/min value
}
@@ -280,13 +279,13 @@ TEST_F(RPCBaseTest, MaxValidator)
{"amount", Max{6}},
};
auto passingInput = json::parse(R"JSON({ "amount": 5 })JSON");
auto passingInput = boost::json::parse(R"JSON({ "amount": 5 })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto passingInput2 = json::parse(R"JSON({ "amount": 6 })JSON");
auto passingInput2 = boost::json::parse(R"JSON({ "amount": 6 })JSON");
ASSERT_TRUE(spec.process(passingInput2));
auto failingInput = json::parse(R"JSON({ "amount": 7 })JSON");
auto failingInput = boost::json::parse(R"JSON({ "amount": 7 })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -298,7 +297,8 @@ TEST_F(RPCBaseTest, MaxValidatorAfterType)
{"amount3", Type<std::int32_t>{}, Max{std::numeric_limits<int32_t>::min()}},
};
auto bigInput = json::parse(R"JSON({ "amount": 9999999999, "amount2": 9999999999, "amount3": -9999999999 })JSON");
auto bigInput =
boost::json::parse(R"JSON({ "amount": 9999999999, "amount2": 9999999999, "amount3": -9999999999 })JSON");
ASSERT_TRUE(spec.process(bigInput)); // type check clamps to type's min/max value
}
@@ -308,13 +308,13 @@ TEST_F(RPCBaseTest, OneOfValidator)
{"currency", OneOf{"XRP", "USD"}},
};
auto passingInput = json::parse(R"JSON({ "currency": "XRP" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "currency": "XRP" })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto passingInput2 = json::parse(R"JSON({ "currency": "USD" })JSON");
auto passingInput2 = boost::json::parse(R"JSON({ "currency": "USD" })JSON");
ASSERT_TRUE(spec.process(passingInput2));
auto failingInput = json::parse(R"JSON({ "currency": "PRX" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "currency": "PRX" })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -324,10 +324,10 @@ TEST_F(RPCBaseTest, EqualToValidator)
{"exact", EqualTo{"CaseSensitive"}},
};
auto passingInput = json::parse(R"JSON({ "exact": "CaseSensitive" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "exact": "CaseSensitive" })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "exact": "Different" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "exact": "Different" })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -336,7 +336,7 @@ TEST_F(RPCBaseTest, ArrayAtValidator)
auto spec = RpcSpec{
{"arr",
Required{},
Type<json::array>{},
Type<boost::json::array>{},
ValidateArrayAt{
0,
{
@@ -353,16 +353,16 @@ TEST_F(RPCBaseTest, ArrayAtValidator)
};
// clang-format on
auto passingInput = json::parse(R"JSON({ "arr": [{"limit": 42}] })JSON");
auto passingInput = boost::json::parse(R"JSON({ "arr": [{"limit": 42}] })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "arr": [{"limit": "not int"}] })JSON");
auto failingInput = boost::json::parse(R"JSON({ "arr": [{"limit": "not int"}] })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "arr": [{"limit": 42}], "arr2": "not array type" })JSON");
failingInput = boost::json::parse(R"JSON({ "arr": [{"limit": 42}], "arr2": "not array type" })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "arr": [] })JSON");
failingInput = boost::json::parse(R"JSON({ "arr": [] })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -371,41 +371,41 @@ TEST_F(RPCBaseTest, IfTypeValidator)
auto spec = RpcSpec{
{"mix",
Required{},
Type<std::string, json::object>{},
IfType<json::object>{
Type<std::string, boost::json::object>{},
IfType<boost::json::object>{
Section{{"limit", Required{}, Type<uint32_t>{}, Between<uint32_t>{0, 100}}},
Section{{"limit2", Required{}, Type<uint32_t>{}, Between<uint32_t>{0, 100}}}
},
IfType<std::string>{CustomValidators::uint256HexStringValidator}},
{"mix2",
Section{{"limit", Required{}, Type<uint32_t>{}, Between<uint32_t>{0, 100}}},
Type<std::string, json::object>{}},
Type<std::string, boost::json::object>{}},
};
// if json object pass
auto passingInput = json::parse(R"JSON({ "mix": {"limit": 42, "limit2": 22} })JSON");
auto passingInput = boost::json::parse(R"JSON({ "mix": {"limit": 42, "limit2": 22} })JSON");
ASSERT_TRUE(spec.process(passingInput));
// if string pass
passingInput =
json::parse(R"JSON({ "mix": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC" })JSON");
boost::json::parse(R"JSON({ "mix": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC" })JSON");
ASSERT_TRUE(spec.process(passingInput));
// if json object fail at first requirement
auto failingInput = json::parse(R"JSON({ "mix": {"limit": "not int"} })JSON");
auto failingInput = boost::json::parse(R"JSON({ "mix": {"limit": "not int"} })JSON");
ASSERT_FALSE(spec.process(failingInput));
// if json object fail at second requirement
failingInput = json::parse(R"JSON({ "mix": {"limit": 22, "limit2": "y"} })JSON");
failingInput = boost::json::parse(R"JSON({ "mix": {"limit": 22, "limit2": "y"} })JSON");
ASSERT_FALSE(spec.process(failingInput));
// if string fail
failingInput = json::parse(R"JSON({ "mix": "not hash" })JSON");
failingInput = boost::json::parse(R"JSON({ "mix": "not hash" })JSON");
ASSERT_FALSE(spec.process(failingInput));
// type check fail
failingInput = json::parse(R"JSON({ "mix": 1213 })JSON");
failingInput = boost::json::parse(R"JSON({ "mix": 1213 })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "mix": {"limit": 42, "limit2": 22}, "mix2": 1213 })JSON");
failingInput = boost::json::parse(R"JSON({ "mix": {"limit": 42, "limit2": 22}, "mix2": 1213 })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -414,28 +414,29 @@ TEST_F(RPCBaseTest, WithCustomError)
auto const spec = RpcSpec{
{"transaction",
WithCustomError{
CustomValidators::uint256HexStringValidator, rpc::Status{ripple::rpcBAD_FEATURE, "MyCustomError"}
CustomValidators::uint256HexStringValidator, rpc::Status{xrpl::RpcBadFeature, "MyCustomError"}
}},
{"other", WithCustomError{Type<std::string>{}, rpc::Status{ripple::rpcALREADY_MULTISIG, "MyCustomError2"}}}
{"other", WithCustomError{Type<std::string>{}, rpc::Status{xrpl::RpcAlreadyMultisig, "MyCustomError2"}}}
};
auto passingInput = json::parse(
auto passingInput = boost::json::parse(
R"JSON({ "transaction": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC", "other": "1"})JSON"
);
ASSERT_TRUE(spec.process(passingInput));
auto failingInput =
json::parse(R"JSON({ "transaction": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515B"})JSON");
auto failingInput = boost::json::parse(
R"JSON({ "transaction": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515B"})JSON"
);
auto err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "MyCustomError");
ASSERT_EQ(err.error(), ripple::rpcBAD_FEATURE);
ASSERT_EQ(err.error(), xrpl::RpcBadFeature);
failingInput = json::parse(R"JSON({ "other": 1})JSON");
failingInput = boost::json::parse(R"JSON({ "other": 1})JSON");
err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "MyCustomError2");
ASSERT_EQ(err.error(), ripple::rpcALREADY_MULTISIG);
ASSERT_EQ(err.error(), xrpl::RpcAlreadyMultisig);
}
TEST_F(RPCBaseTest, TimeFormatValidator)
@@ -444,50 +445,51 @@ TEST_F(RPCBaseTest, TimeFormatValidator)
{"date", TimeFormatValidator{"%Y-%m-%dT%H:%M:%SZ"}},
};
auto passingInput = json::parse(R"JSON({ "date": "2023-01-01T00:00:00Z" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "date": "2023-01-01T00:00:00Z" })JSON");
EXPECT_TRUE(spec.process(passingInput));
passingInput = json::parse("123");
passingInput = boost::json::parse("123");
EXPECT_TRUE(spec.process(passingInput));
// key not exists
passingInput = json::parse(R"JSON({ "date1": "2023-01-01T00:00:00Z" })JSON");
passingInput = boost::json::parse(R"JSON({ "date1": "2023-01-01T00:00:00Z" })JSON");
EXPECT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "date": "2023-01-01-00:00:00" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "date": "2023-01-01-00:00:00" })JSON");
auto err = spec.process(failingInput);
EXPECT_FALSE(err);
EXPECT_EQ(err.error(), ripple::rpcINVALID_PARAMS);
EXPECT_EQ(err.error(), xrpl::RpcInvalidParams);
failingInput = json::parse(R"JSON({ "date": "01-01-2024T00:00:00" })JSON");
failingInput = boost::json::parse(R"JSON({ "date": "01-01-2024T00:00:00" })JSON");
EXPECT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "date": "2024-01-01T29:00:00" })JSON");
failingInput = boost::json::parse(R"JSON({ "date": "2024-01-01T29:00:00" })JSON");
EXPECT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "date": "" })JSON");
failingInput = boost::json::parse(R"JSON({ "date": "" })JSON");
EXPECT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "date": 1 })JSON");
failingInput = boost::json::parse(R"JSON({ "date": 1 })JSON");
err = spec.process(failingInput);
EXPECT_FALSE(err);
EXPECT_EQ(err.error(), ripple::rpcINVALID_PARAMS);
EXPECT_EQ(err.error(), xrpl::RpcInvalidParams);
}
TEST_F(RPCBaseTest, CustomValidator)
{
auto customFormatCheck = CustomValidator{[](json::value const& value, std::string_view /* key */) -> MaybeError {
return value.as_string().size() == 34 ? MaybeError{} : Error{rpc::Status{"Uh oh"}};
}};
auto customFormatCheck =
CustomValidator{[](boost::json::value const& value, std::string_view /* key */) -> MaybeError {
return value.as_string().size() == 34 ? MaybeError{} : Error{rpc::Status{"Uh oh"}};
}};
auto spec = RpcSpec{
{"taker", customFormatCheck},
};
auto passingInput = json::parse(R"JSON({ "taker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "taker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59" })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "taker": "wrongformat" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "taker": "wrongformat" })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -498,13 +500,13 @@ TEST_F(RPCBaseTest, NotSupported)
{"getter", NotSupported{}},
};
auto passingInput = json::parse(R"JSON({ "taker": 2 })JSON");
auto passingInput = boost::json::parse(R"JSON({ "taker": 2 })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "taker": 123 })JSON");
auto failingInput = boost::json::parse(R"JSON({ "taker": 123 })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "taker": 2, "getter": 2 })JSON");
failingInput = boost::json::parse(R"JSON({ "taker": 2, "getter": 2 })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
@@ -513,21 +515,21 @@ TEST_F(RPCBaseTest, LedgerIndexValidator)
auto spec = RpcSpec{
{"ledgerIndex", CustomValidators::ledgerIndexValidator},
};
auto passingInput = json::parse(R"JSON({ "ledgerIndex": "validated" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "ledgerIndex": "validated" })JSON");
ASSERT_TRUE(spec.process(passingInput));
passingInput = json::parse(R"JSON({ "ledgerIndex": "256" })JSON");
passingInput = boost::json::parse(R"JSON({ "ledgerIndex": "256" })JSON");
ASSERT_TRUE(spec.process(passingInput));
passingInput = json::parse(R"JSON({ "ledgerIndex": 256 })JSON");
passingInput = boost::json::parse(R"JSON({ "ledgerIndex": 256 })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "ledgerIndex": "wrongformat" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "ledgerIndex": "wrongformat" })JSON");
auto err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "ledgerIndexMalformed");
failingInput = json::parse(R"JSON({ "ledgerIndex": true })JSON");
failingInput = boost::json::parse(R"JSON({ "ledgerIndex": true })JSON");
err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "ledgerIndexMalformed");
@@ -538,24 +540,26 @@ TEST_F(RPCBaseTest, AccountValidator)
auto spec = RpcSpec{
{"account", CustomValidators::accountValidator},
};
auto failingInput = json::parse(R"JSON({ "account": 256 })JSON");
auto failingInput = boost::json::parse(R"JSON({ "account": 256 })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp" })JSON");
failingInput = boost::json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp" })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput =
json::parse(R"JSON({ "account": "02000000000000000000000000000000000000000000000000000000000000000" })JSON");
failingInput = boost::json::parse(
R"JSON({ "account": "02000000000000000000000000000000000000000000000000000000000000000" })JSON"
);
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp?" })JSON");
failingInput = boost::json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp?" })JSON");
ASSERT_FALSE(spec.process(failingInput));
auto passingInput = json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn" })JSON");
ASSERT_TRUE(spec.process(passingInput));
passingInput =
json::parse(R"JSON({ "account": "020000000000000000000000000000000000000000000000000000000000000000" })JSON");
passingInput = boost::json::parse(
R"JSON({ "account": "020000000000000000000000000000000000000000000000000000000000000000" })JSON"
);
ASSERT_TRUE(spec.process(passingInput));
}
@@ -564,20 +568,21 @@ TEST_F(RPCBaseTest, AccountBase58Validator)
auto spec = RpcSpec{
{"account", CustomValidators::accountBase58Validator},
};
auto failingInput = json::parse(R"JSON({ "account": 256 })JSON");
auto failingInput = boost::json::parse(R"JSON({ "account": 256 })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp" })JSON");
failingInput = boost::json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp" })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput =
json::parse(R"JSON({ "account": "020000000000000000000000000000000000000000000000000000000000000000" })JSON");
failingInput = boost::json::parse(
R"JSON({ "account": "020000000000000000000000000000000000000000000000000000000000000000" })JSON"
);
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp?" })JSON");
failingInput = boost::json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp?" })JSON");
ASSERT_FALSE(spec.process(failingInput));
auto passingInput = json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn" })JSON");
ASSERT_TRUE(spec.process(passingInput));
}
@@ -586,31 +591,31 @@ TEST_F(RPCBaseTest, AccountMarkerValidator)
auto spec = RpcSpec{
{"marker", CustomValidators::accountMarkerValidator},
};
auto failingInput = json::parse(R"JSON({ "marker": 256 })JSON");
auto failingInput = boost::json::parse(R"JSON({ "marker": 256 })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "marker": "testtest" })JSON");
failingInput = boost::json::parse(R"JSON({ "marker": "testtest" })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "marker": "ABAB1234:1H" })JSON");
failingInput = boost::json::parse(R"JSON({ "marker": "ABAB1234:1H" })JSON");
ASSERT_FALSE(spec.process(failingInput));
auto passingInput = json::parse(R"JSON({ "account": "ABAB1234:123" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "account": "ABAB1234:123" })JSON");
ASSERT_TRUE(spec.process(passingInput));
}
TEST_F(RPCBaseTest, Uint160HexStringValidator)
{
auto const spec = RpcSpec{{"marker", CustomValidators::uint160HexStringValidator}};
auto passingInput = json::parse(R"JSON({ "marker": "F609A18102218C75767209946A77523CBD97E225"})JSON");
auto passingInput = boost::json::parse(R"JSON({ "marker": "F609A18102218C75767209946A77523CBD97E225"})JSON");
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "marker": 160})JSON");
auto failingInput = boost::json::parse(R"JSON({ "marker": 160})JSON");
auto err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "markerNotString");
failingInput = json::parse(R"JSON({ "marker": "F609A18102218C75767209946A77523CBD97E2253515BC"})JSON");
failingInput = boost::json::parse(R"JSON({ "marker": "F609A18102218C75767209946A77523CBD97E2253515BC"})JSON");
err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "markerMalformed");
@@ -620,16 +625,17 @@ TEST_F(RPCBaseTest, Uint192HexStringValidator)
{
auto const spec = RpcSpec{{"mpt_issuance_id", CustomValidators::uint192HexStringValidator}};
auto passingInput =
json::parse(R"JSON({ "mpt_issuance_id": "0000012F27A9DE73EAA1E8831FA253E19030A17E2D038198"})JSON");
boost::json::parse(R"JSON({ "mpt_issuance_id": "0000012F27A9DE73EAA1E8831FA253E19030A17E2D038198"})JSON");
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "mpt_issuance_id": 192})JSON");
auto failingInput = boost::json::parse(R"JSON({ "mpt_issuance_id": 192})JSON");
auto err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "mpt_issuance_idNotString");
failingInput =
json::parse(R"JSON({ "mpt_issuance_id": "0000012F27A9DE73EAA1E8831FA253E19030A17E2D038198983515BC"})JSON");
failingInput = boost::json::parse(
R"JSON({ "mpt_issuance_id": "0000012F27A9DE73EAA1E8831FA253E19030A17E2D038198983515BC"})JSON"
);
err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "mpt_issuance_idMalformed");
@@ -638,17 +644,18 @@ TEST_F(RPCBaseTest, Uint192HexStringValidator)
TEST_F(RPCBaseTest, Uint256HexStringValidator)
{
auto const spec = RpcSpec{{"transaction", CustomValidators::uint256HexStringValidator}};
auto passingInput =
json::parse(R"JSON({ "transaction": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC"})JSON");
auto passingInput = boost::json::parse(
R"JSON({ "transaction": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC"})JSON"
);
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "transaction": 256})JSON");
auto failingInput = boost::json::parse(R"JSON({ "transaction": 256})JSON");
auto err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "transactionNotString");
failingInput =
json::parse(R"JSON({ "transaction": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC"})JSON");
boost::json::parse(R"JSON({ "transaction": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC"})JSON");
err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "transactionMalformed");
@@ -657,26 +664,26 @@ TEST_F(RPCBaseTest, Uint256HexStringValidator)
TEST_F(RPCBaseTest, CurrencyValidator)
{
auto const spec = RpcSpec{{"currency", CustomValidators::currencyValidator}};
auto passingInput = json::parse(R"JSON({ "currency": "GBP"})JSON");
auto passingInput = boost::json::parse(R"JSON({ "currency": "GBP"})JSON");
ASSERT_TRUE(spec.process(passingInput));
passingInput = json::parse(R"JSON({ "currency": "0158415500000000C1F76FF6ECB0BAC600000000"})JSON");
passingInput = boost::json::parse(R"JSON({ "currency": "0158415500000000C1F76FF6ECB0BAC600000000"})JSON");
ASSERT_TRUE(spec.process(passingInput));
passingInput = json::parse(R"JSON({ "currency": "0158415500000000c1f76ff6ecb0bac600000000"})JSON");
passingInput = boost::json::parse(R"JSON({ "currency": "0158415500000000c1f76ff6ecb0bac600000000"})JSON");
ASSERT_TRUE(spec.process(passingInput));
for (auto const& currency : {"[]<", ">()", "{}|", "?!@", "#$%", "^&*"}) {
passingInput = json::parse(fmt::format(R"JSON({{ "currency": "{}" }})JSON", currency));
passingInput = boost::json::parse(fmt::format(R"JSON({{ "currency": "{}" }})JSON", currency));
ASSERT_TRUE(spec.process(passingInput));
}
auto failingInput = json::parse(R"JSON({ "currency": 256})JSON");
auto failingInput = boost::json::parse(R"JSON({ "currency": 256})JSON");
auto err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "currencyNotString");
failingInput = json::parse(R"JSON({ "currency": "12314"})JSON");
failingInput = boost::json::parse(R"JSON({ "currency": "12314"})JSON");
err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "malformedCurrency");
@@ -685,15 +692,15 @@ TEST_F(RPCBaseTest, CurrencyValidator)
TEST_F(RPCBaseTest, IssuerValidator)
{
auto const spec = RpcSpec{{"issuer", CustomValidators::issuerValidator}};
auto passingInput = json::parse(R"JSON({ "issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"})JSON");
auto passingInput = boost::json::parse(R"JSON({ "issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"})JSON");
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "issuer": 256})JSON");
auto failingInput = boost::json::parse(R"JSON({ "issuer": 256})JSON");
auto err = spec.process(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "issuerNotString");
failingInput = json::parse(fmt::format(R"JSON({{ "issuer": "{}"}})JSON", toBase58(ripple::noAccount())));
failingInput = boost::json::parse(fmt::format(R"JSON({{ "issuer": "{}"}})JSON", toBase58(xrpl::noAccount())));
err = spec.process(failingInput);
ASSERT_FALSE(err);
}
@@ -701,7 +708,7 @@ TEST_F(RPCBaseTest, IssuerValidator)
TEST_F(RPCBaseTest, SubscribeStreamValidator)
{
auto const spec = RpcSpec{{"streams", CustomValidators::subscribeStreamValidator}};
auto passingInput = json::parse(
auto passingInput = boost::json::parse(
R"JSON({
"streams": [
"ledger",
@@ -716,15 +723,15 @@ TEST_F(RPCBaseTest, SubscribeStreamValidator)
);
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "streams": 256})JSON");
auto failingInput = boost::json::parse(R"JSON({ "streams": 256})JSON");
auto err = spec.process(failingInput);
ASSERT_FALSE(err);
failingInput = json::parse(R"JSON({ "streams": ["test"]})JSON");
failingInput = boost::json::parse(R"JSON({ "streams": ["test"]})JSON");
err = spec.process(failingInput);
ASSERT_FALSE(err);
failingInput = json::parse(R"JSON({ "streams": [123]})JSON");
failingInput = boost::json::parse(R"JSON({ "streams": [123]})JSON");
err = spec.process(failingInput);
ASSERT_FALSE(err);
}
@@ -732,20 +739,20 @@ TEST_F(RPCBaseTest, SubscribeStreamValidator)
TEST_F(RPCBaseTest, SubscribeAccountsValidator)
{
auto const spec = RpcSpec{{"accounts", CustomValidators::subscribeAccountsValidator}};
auto passingInput = json::parse(
auto passingInput = boost::json::parse(
R"JSON({ "accounts": ["rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun"]})JSON"
);
ASSERT_TRUE(spec.process(passingInput));
auto failingInput = json::parse(R"JSON({ "accounts": 256})JSON");
auto failingInput = boost::json::parse(R"JSON({ "accounts": 256})JSON");
auto err = spec.process(failingInput);
ASSERT_FALSE(err);
failingInput = json::parse(R"JSON({ "accounts": ["test"]})JSON");
failingInput = boost::json::parse(R"JSON({ "accounts": ["test"]})JSON");
err = spec.process(failingInput);
ASSERT_FALSE(err);
failingInput = json::parse(R"JSON({ "accounts": [123]})JSON");
failingInput = boost::json::parse(R"JSON({ "accounts": [123]})JSON");
err = spec.process(failingInput);
ASSERT_FALSE(err);
}
@@ -756,14 +763,14 @@ TEST_F(RPCBaseTest, ClampingModifier)
{"amount", Clamp<uint32_t>{10u, 20u}},
};
auto passingInput = json::parse(R"JSON({ "amount": 15 })JSON");
auto passingInput = boost::json::parse(R"JSON({ "amount": 15 })JSON");
ASSERT_TRUE(spec.process(passingInput));
auto passingInput2 = json::parse(R"JSON({ "amount": 5 })JSON");
auto passingInput2 = boost::json::parse(R"JSON({ "amount": 5 })JSON");
ASSERT_TRUE(spec.process(passingInput2));
ASSERT_EQ(passingInput2.at("amount").as_uint64(), 10u); // clamped
auto passingInput3 = json::parse(R"JSON({ "amount": 25 })JSON");
auto passingInput3 = boost::json::parse(R"JSON({ "amount": 25 })JSON");
ASSERT_TRUE(spec.process(passingInput3));
ASSERT_EQ(passingInput3.at("amount").as_uint64(), 20u); // clamped
}
@@ -774,18 +781,18 @@ TEST_F(RPCBaseTest, ToLowerModifier)
{"str", ToLower{}},
};
auto passingInput = json::parse(R"JSON({ "str": "TesT" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "str": "TesT" })JSON");
ASSERT_TRUE(spec.process(passingInput));
ASSERT_EQ(passingInput.at("str").as_string(), "test");
auto passingInput2 = json::parse(R"JSON({ "str2": "TesT" })JSON");
auto passingInput2 = boost::json::parse(R"JSON({ "str2": "TesT" })JSON");
ASSERT_TRUE(spec.process(passingInput2)); // no str no problem
auto passingInput3 = json::parse(R"JSON({ "str": "already lower case" })JSON");
auto passingInput3 = boost::json::parse(R"JSON({ "str": "already lower case" })JSON");
ASSERT_TRUE(spec.process(passingInput3));
ASSERT_EQ(passingInput3.at("str").as_string(), "already lower case");
auto passingInput4 = json::parse(R"JSON({ "str": "" })JSON");
auto passingInput4 = boost::json::parse(R"JSON({ "str": "" })JSON");
ASSERT_TRUE(spec.process(passingInput4)); // empty str no problem
ASSERT_EQ(passingInput4.at("str").as_string(), "");
}
@@ -796,42 +803,42 @@ TEST_F(RPCBaseTest, ToNumberModifier)
{"str", ToNumber{}},
};
auto passingInput = json::parse(R"JSON({ "str": [] })JSON");
auto passingInput = boost::json::parse(R"JSON({ "str": [] })JSON");
ASSERT_TRUE(spec.process(passingInput));
passingInput = json::parse(R"JSON({ "str2": "TesT" })JSON");
passingInput = boost::json::parse(R"JSON({ "str2": "TesT" })JSON");
ASSERT_TRUE(spec.process(passingInput));
passingInput = json::parse(R"JSON([])JSON");
passingInput = boost::json::parse(R"JSON([])JSON");
ASSERT_TRUE(spec.process(passingInput));
passingInput = json::parse(R"JSON({ "str": "123" })JSON");
passingInput = boost::json::parse(R"JSON({ "str": "123" })JSON");
ASSERT_TRUE(spec.process(passingInput));
ASSERT_EQ(passingInput.at("str").as_int64(), 123);
auto failingInput = json::parse(R"JSON({ "str": "ok" })JSON");
auto failingInput = boost::json::parse(R"JSON({ "str": "ok" })JSON");
ASSERT_FALSE(spec.process(failingInput));
failingInput = json::parse(R"JSON({ "str": "123.123" })JSON");
failingInput = boost::json::parse(R"JSON({ "str": "123.123" })JSON");
ASSERT_FALSE(spec.process(failingInput));
}
TEST_F(RPCBaseTest, CustomModifier)
{
testing::StrictMock<testing::MockFunction<MaybeError(json::value & value, std::string_view)>> mockModifier;
testing::StrictMock<testing::MockFunction<MaybeError(boost::json::value & value, std::string_view)>> mockModifier;
auto const customModifier = CustomModifier{mockModifier.AsStdFunction()};
auto const spec = RpcSpec{
{"str", customModifier},
};
EXPECT_CALL(mockModifier, Call).WillOnce(testing::Return(MaybeError{}));
auto passingInput = json::parse(R"JSON({ "str": "sss" })JSON");
auto passingInput = boost::json::parse(R"JSON({ "str": "sss" })JSON");
ASSERT_TRUE(spec.process(passingInput));
passingInput = json::parse(R"JSON({ "strNotExist": 123 })JSON");
passingInput = boost::json::parse(R"JSON({ "strNotExist": 123 })JSON");
ASSERT_TRUE(spec.process(passingInput));
// not a json object
passingInput = json::parse(R"JSON([])JSON");
passingInput = boost::json::parse(R"JSON([])JSON");
ASSERT_TRUE(spec.process(passingInput));
}