mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-20 11:45:53 +00:00
3784 lines
134 KiB
C++
3784 lines
134 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
This file is part of clio: https://github.com/XRPLF/clio
|
|
Copyright (c) 2023, the clio developers.
|
|
|
|
Permission to use, copy, modify, and distribute this software for any
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
//==============================================================================
|
|
|
|
#include "data/Types.hpp"
|
|
#include "rpc/CredentialHelpers.hpp"
|
|
#include "rpc/Errors.hpp"
|
|
#include "rpc/common/AnyHandler.hpp"
|
|
#include "rpc/common/Types.hpp"
|
|
#include "rpc/handlers/LedgerEntry.hpp"
|
|
#include "util/HandlerBaseTestFixture.hpp"
|
|
#include "util/NameGenerator.hpp"
|
|
#include "util/TestObject.hpp"
|
|
|
|
#include <boost/json/array.hpp>
|
|
#include <boost/json/object.hpp>
|
|
#include <boost/json/parse.hpp>
|
|
#include <boost/json/value.hpp>
|
|
#include <boost/json/value_to.hpp>
|
|
#include <fmt/format.h>
|
|
#include <gmock/gmock.h>
|
|
#include <gtest/gtest.h>
|
|
#include <xrpl/basics/Blob.h>
|
|
#include <xrpl/basics/Slice.h>
|
|
#include <xrpl/basics/StringUtilities.h>
|
|
#include <xrpl/basics/base_uint.h>
|
|
#include <xrpl/basics/strHex.h>
|
|
#include <xrpl/protocol/AccountID.h>
|
|
#include <xrpl/protocol/Indexes.h>
|
|
#include <xrpl/protocol/Issue.h>
|
|
#include <xrpl/protocol/LedgerFormats.h>
|
|
#include <xrpl/protocol/STLedgerEntry.h>
|
|
#include <xrpl/protocol/STObject.h>
|
|
#include <xrpl/protocol/STXChainBridge.h>
|
|
#include <xrpl/protocol/Serializer.h>
|
|
#include <xrpl/protocol/UintTypes.h>
|
|
|
|
#include <cstdint>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
using namespace rpc;
|
|
using namespace data;
|
|
namespace json = boost::json;
|
|
using namespace testing;
|
|
|
|
namespace {
|
|
|
|
constexpr auto kINDEX1 = "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD";
|
|
constexpr auto kACCOUNT = "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn";
|
|
constexpr auto kACCOUNT2 = "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun";
|
|
constexpr auto kACCOUNT3 = "rhzcyub9SbyZ4YF1JYskN5rLrTDUuLZG6D";
|
|
constexpr auto kRANGE_MIN = 10;
|
|
constexpr auto kRANGE_MAX = 30;
|
|
constexpr auto kLEDGER_HASH = "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652";
|
|
constexpr auto kTOKEN_ID = "000827103B94ECBB7BF0A0A6ED62B3607801A27B65F4679F4AD1D4850000C0EA";
|
|
constexpr auto kNFT_ID = "00010000A7CAD27B688D14BA1A9FA5366554D6ADCF9CE0875B974D9F00000004";
|
|
constexpr auto kTXN_ID = "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD";
|
|
constexpr auto kCREDENTIAL_TYPE = "4B5943";
|
|
|
|
} // namespace
|
|
|
|
struct RPCLedgerEntryTest : HandlerBaseTest {
|
|
RPCLedgerEntryTest()
|
|
{
|
|
backend_->setRange(kRANGE_MIN, kRANGE_MAX);
|
|
}
|
|
};
|
|
|
|
struct ParamTestCaseBundle {
|
|
std::string testName;
|
|
std::string testJson;
|
|
std::string expectedError;
|
|
std::string expectedErrorMessage;
|
|
};
|
|
|
|
// parameterized test cases for parameters check
|
|
struct LedgerEntryParameterTest : public RPCLedgerEntryTest, public WithParamInterface<ParamTestCaseBundle> {};
|
|
|
|
// TODO: because we extract the error generation from the handler to framework
|
|
// the error messages need one round fine tuning
|
|
static auto
|
|
generateTestValuesForParametersTest()
|
|
{
|
|
return std::vector<ParamTestCaseBundle>{
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidBinaryType",
|
|
.testJson = R"JSON({
|
|
"index":
|
|
"05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"binary": "invalid"
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Invalid parameters."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidAccountRootFormat",
|
|
.testJson = R"JSON({
|
|
"account_root": "invalid"
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDidFormat",
|
|
.testJson = R"JSON({
|
|
"did": "invalid"
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidAccountRootNotString",
|
|
.testJson = R"JSON({
|
|
"account_root": 123
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "account_rootNotString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidLedgerIndex",
|
|
.testJson = R"JSON({
|
|
"ledger_index": "wrong"
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "ledgerIndexMalformed"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "UnknownOption",
|
|
.testJson = R"JSON({})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Invalid parameters."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDepositPreauthType",
|
|
.testJson = R"JSON({
|
|
"deposit_preauth": 123
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Invalid parameters."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDepositPreauthString",
|
|
.testJson = R"JSON({
|
|
"deposit_preauth": "invalid"
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDepositPreauthEmptyJson",
|
|
.testJson = R"JSON({
|
|
"deposit_preauth": {}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Required field 'owner' missing"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDepositPreauthJsonWrongAccount",
|
|
.testJson = R"JSON({
|
|
"deposit_preauth": {
|
|
"owner": "invalid",
|
|
"authorized": "invalid"
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedOwner",
|
|
.expectedErrorMessage = "Malformed owner."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDepositPreauthJsonOwnerNotString",
|
|
.testJson = R"JSON({
|
|
"deposit_preauth": {
|
|
"owner": 123,
|
|
"authorized": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedOwner",
|
|
.expectedErrorMessage = "Malformed owner."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDepositPreauthJsonAuthorizedNotString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized": 123
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "authorizedNotString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDepositPreauthJsonAuthorizeCredentialsNotArray",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": "asdf"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "authorized_credentials not array"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDepositPreauthJsonAuthorizeCredentialsMalformedString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": ["C2F2A19C8D0D893D18F18FDCFE13A3ECB41767E48422DF07F2455CDA08FDF09B"]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedAuthorizedCredentials",
|
|
.expectedErrorMessage = "authorized_credentials elements in array are not objects."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthBothAuthAndAuthCredentialsDoesNotExists",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Must have one of authorized or authorized_credentials."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthBothAuthAndAuthCredentialsExists",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized": "{}",
|
|
"authorized_credentials": [
|
|
{{
|
|
"issuer": "{}",
|
|
"credential_type": "{}"
|
|
}}
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kACCOUNT3,
|
|
kCREDENTIAL_TYPE
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Must have one of authorized or authorized_credentials."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthEmptyAuthorizeCredentials",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": [
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedAuthorizedCredentials",
|
|
.expectedErrorMessage = "Requires at least one element in authorized_credentials array."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthAuthorizeCredentialsMissingCredentialType",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": [
|
|
{{
|
|
"issuer": "{}"
|
|
}}
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedAuthorizedCredentials",
|
|
.expectedErrorMessage = "Field 'CredentialType' is required but missing."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthAuthorizeCredentialsMissingIssuer",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": [
|
|
{{
|
|
"credential_type": "{}"
|
|
}}
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kCREDENTIAL_TYPE
|
|
),
|
|
.expectedError = "malformedAuthorizedCredentials",
|
|
.expectedErrorMessage = "Field 'Issuer' is required but missing."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthAuthorizeCredentialsIncorrectIssuerType",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": [
|
|
{{
|
|
"issuer": 123,
|
|
"credential_type": "{}"
|
|
}}
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kCREDENTIAL_TYPE
|
|
),
|
|
.expectedError = "malformedAuthorizedCredentials",
|
|
.expectedErrorMessage = "issuer NotString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthAuthorizeCredentialsIncorrectCredentialType",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": [
|
|
{{
|
|
"issuer": "{}",
|
|
"credential_type": 432
|
|
}}
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedAuthorizedCredentials",
|
|
.expectedErrorMessage = "credential_type NotString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthAuthorizeCredentialsCredentialTypeNotHex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": [
|
|
{{
|
|
"issuer": "{}",
|
|
"credential_type": "hello world"
|
|
}}
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedAuthorizedCredentials",
|
|
.expectedErrorMessage = "credential_type NotHexString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthAuthorizeCredentialsCredentialTypeEmpty",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": [
|
|
{{
|
|
"issuer": "{}",
|
|
"credential_type": ""
|
|
}}
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedAuthorizedCredentials",
|
|
.expectedErrorMessage = "credential_type is empty"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "DepositPreauthDuplicateAuthorizeCredentials",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": [
|
|
{{
|
|
"issuer": "{}",
|
|
"credential_type": "{}"
|
|
}},
|
|
{{
|
|
"issuer": "{}",
|
|
"credential_type": "{}"
|
|
}}
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kCREDENTIAL_TYPE,
|
|
kACCOUNT2,
|
|
kCREDENTIAL_TYPE
|
|
),
|
|
.expectedError = "malformedAuthorizedCredentials",
|
|
.expectedErrorMessage = "duplicates in credentials."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidTicketType",
|
|
.testJson = R"JSON({
|
|
"ticket": 123
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Invalid parameters."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidTicketIndex",
|
|
.testJson = R"JSON({
|
|
"ticket": "invalid"
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidTicketEmptyJson",
|
|
.testJson = R"JSON({
|
|
"ticket": {}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Required field 'account' missing"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidTicketJsonAccountNotString",
|
|
.testJson = R"JSON({
|
|
"ticket": {
|
|
"account": 123,
|
|
"ticket_seq": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "accountNotString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidTicketJsonAccountInvalid",
|
|
.testJson = R"JSON({
|
|
"ticket": {
|
|
"account": "123",
|
|
"ticket_seq": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidTicketJsonSeqNotInt",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"ticket": {{
|
|
"account": "{}",
|
|
"ticket_seq": "123"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidOfferType",
|
|
.testJson = R"JSON({
|
|
"offer": 123
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Invalid parameters."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidOfferIndex",
|
|
.testJson = R"JSON({
|
|
"offer": "invalid"
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidOfferEmptyJson",
|
|
.testJson = R"JSON({
|
|
"offer": {}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Required field 'account' missing"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidOfferJsonAccountNotString",
|
|
.testJson = R"JSON({
|
|
"ticket": {
|
|
"account": 123,
|
|
"seq": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "accountNotString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidOfferJsonAccountInvalid",
|
|
.testJson = R"JSON({
|
|
"ticket": {
|
|
"account": "123",
|
|
"seq": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidOfferJsonSeqNotInt",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"offer": {{
|
|
"account": "{}",
|
|
"seq": "123"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidEscrowType",
|
|
.testJson = R"JSON({
|
|
"escrow": 123
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Invalid parameters."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidEscrowIndex",
|
|
.testJson = R"JSON({
|
|
"escrow": "invalid"
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidEscrowEmptyJson",
|
|
.testJson = R"JSON({
|
|
"escrow": {}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Required field 'owner' missing"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidEscrowJsonAccountNotString",
|
|
.testJson = R"JSON({
|
|
"escrow": {
|
|
"owner": 123,
|
|
"seq": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedOwner",
|
|
.expectedErrorMessage = "Malformed owner."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidEscrowJsonAccountInvalid",
|
|
.testJson = R"JSON({
|
|
"escrow": {
|
|
"owner": "123",
|
|
"seq": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedOwner",
|
|
.expectedErrorMessage = "Malformed owner."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidEscrowJsonSeqNotInt",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"escrow": {{
|
|
"owner": "{}",
|
|
"seq": "123"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidRippleStateType",
|
|
.testJson = R"JSON({
|
|
"ripple_state": "123"
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Invalid parameters."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidRippleStateMissField",
|
|
.testJson = R"JSON({
|
|
"ripple_state": {
|
|
"currency": "USD"
|
|
}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Required field 'accounts' missing"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidRippleStateEmptyJson",
|
|
.testJson = R"JSON({
|
|
"ripple_state": {}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Required field 'accounts' missing"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidRippleStateOneAccount",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"ripple_state": {{
|
|
"accounts": ["{}"]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "malformedAccounts"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidRippleStateSameAccounts",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"ripple_state": {{
|
|
"accounts": ["{}", "{}"],
|
|
"currency": "USD"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "malformedAccounts"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidRippleStateWrongAccountsNotString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"ripple_state": {{
|
|
"accounts": ["{}",123],
|
|
"currency": "USD"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "malformedAccounts"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidRippleStateWrongAccountsFormat",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"ripple_state": {{
|
|
"accounts": ["{}", "123"],
|
|
"currency": "USD"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "malformedAddresses"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidRippleStateWrongCurrency",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"ripple_state": {{
|
|
"accounts": ["{}", "{}"],
|
|
"currency": "XXXX"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedCurrency",
|
|
.expectedErrorMessage = "malformedCurrency"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidRippleStateWrongCurrencyNotString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"ripple_state": {{
|
|
"accounts": ["{}", "{}"],
|
|
"currency": 123
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "currencyNotString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDirectoryType",
|
|
.testJson = R"JSON({
|
|
"directory": 123
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "Invalid parameters."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDirectoryIndex",
|
|
.testJson = R"JSON({
|
|
"directory": "123"
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDirectoryEmptyJson",
|
|
.testJson = R"JSON({
|
|
"directory": {}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "missingOwnerOrDirRoot"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDirectoryWrongOwnerNotString",
|
|
.testJson = R"JSON({
|
|
"directory": {
|
|
"owner": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "ownerNotString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDirectoryWrongOwnerFormat",
|
|
.testJson = R"JSON({
|
|
"directory": {
|
|
"owner": "123"
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDirectoryWrongDirFormat",
|
|
.testJson = R"JSON({
|
|
"directory": {
|
|
"dir_root": "123"
|
|
}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "dir_rootMalformed"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDirectoryWrongDirNotString",
|
|
.testJson = R"JSON({
|
|
"directory": {
|
|
"dir_root": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "dir_rootNotString"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDirectoryDirOwnerConflict",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"directory": {{
|
|
"dir_root": "{}",
|
|
"owner": "{}"
|
|
}}
|
|
}})JSON",
|
|
kINDEX1,
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "invalidParams",
|
|
.expectedErrorMessage = "mayNotSpecifyBothDirRootAndOwner"
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidDirectoryDirSubIndexNotInt",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"directory": {{
|
|
"dir_root": "{}",
|
|
"sub_index": "not int"
|
|
}}
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidAMMStringIndex",
|
|
.testJson = R"JSON({
|
|
"amm": "invalid"
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "EmptyAMMJson",
|
|
.testJson = R"JSON({
|
|
"amm": {}
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "NonObjectAMMJsonAsset",
|
|
.testJson = R"JSON({
|
|
"amm": {
|
|
"asset": 123,
|
|
"asset2": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "EmptyAMMAssetJson",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset": {{}},
|
|
"asset2": {{
|
|
"currency": "USD",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "EmptyAMMAsset2Json",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset2": {{}},
|
|
"asset": {{
|
|
"currency": "USD",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "MissingAMMAsset2Json",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset": {{
|
|
"currency": "USD",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "MissingAMMAssetJson",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset2": {{
|
|
"currency": "USD",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "AMMAssetNotJson",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset": "invalid",
|
|
"asset2": {{
|
|
"currency": "USD",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "AMMAsset2NotJson",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset2": "invalid",
|
|
"asset": {{
|
|
"currency": "USD",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "WrongAMMAssetCurrency",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset2": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"asset": {{
|
|
"currency": "USD2",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "WrongAMMAssetIssuer",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset2": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"asset": {{
|
|
"currency": "USD",
|
|
"issuer": "aa{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "MissingAMMAssetIssuerForNonXRP",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset2": {{
|
|
"currency": "JPY"
|
|
}},
|
|
"asset": {{
|
|
"currency": "USD",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "AMMAssetHasIssuerForXRP",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset2": {{
|
|
"currency": "XRP",
|
|
"issuer": "{}"
|
|
}},
|
|
"asset": {{
|
|
"currency": "USD",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "MissingAMMAssetCurrency",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"amm": {{
|
|
"asset2": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"asset": {{
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeMissingBridgeAccount",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeCurrencyIsNumber",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": {},
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
1,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeIssuerIsNumber",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": {}
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
"JPY",
|
|
2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeIssuingChainIssueIsNotObject",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": 1
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeWithInvalidBridgeAccount",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "abcd",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeDoorInvalid",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "abcd",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeIssuerInvalid",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "invalid"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
"JPY"
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeIssueCurrencyInvalid",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPJPJP",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeIssueXRPCurrencyInvalid",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP",
|
|
"issuer": "{}"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPY",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kACCOUNT2,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeIssueJPYCurrencyInvalid",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPY"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeMissingLockingChainDoor",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP",
|
|
"issuer": "{}"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPY",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kACCOUNT2,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeMissingIssuingChainDoor",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPY",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeMissingLockingChainIssue",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPY",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeMissingIssuingChainIssue",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "JPY",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BridgeInvalidType",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"bridge_account": "{}",
|
|
"bridge": "invalid"
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedClaimIdInvalidType",
|
|
.testJson = R"JSON({
|
|
"xchain_owned_claim_id": 123
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedClaimIdJsonMissingClaimId",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_claim_id": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedClaimIdJsonMissingDoor",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_claim_id": {{
|
|
"xchain_owned_claim_id": 10,
|
|
"LockingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedClaimIdJsonMissingIssue",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_claim_id": {{
|
|
"xchain_owned_claim_id": 10,
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT
|
|
),
|
|
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedClaimIdJsonInvalidDoor",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_claim_id": {{
|
|
"xchain_owned_claim_id": 10,
|
|
"LockingChainDoor": "abcd",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedClaimIdJsonInvalidIssue",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_claim_id": {{
|
|
"xchain_owned_claim_id": 10,
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
"JPY"
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedCreateAccountClaimIdInvalidType",
|
|
.testJson = R"JSON({
|
|
"xchain_owned_create_account_claim_id": 123
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedCreateAccountClaimIdJsonMissingClaimId",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_create_account_claim_id": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedCreateAccountClaimIdJsonMissingDoor",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_create_account_claim_id": {{
|
|
"xchain_owned_create_account_claim_id": 10,
|
|
"LockingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedCreateAccountClaimIdJsonMissingIssue",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_create_account_claim_id": {{
|
|
"xchain_owned_create_account_claim_id": 10,
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT
|
|
),
|
|
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedCreateAccountClaimIdJsonInvalidDoor",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_create_account_claim_id": {{
|
|
"xchain_owned_create_account_claim_id": 10,
|
|
"LockingChainDoor": "abcd",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OwnedCreateAccountClaimIdJsonInvalidIssue",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"xchain_owned_create_account_claim_id": {{
|
|
"xchain_owned_create_account_claim_id": 10,
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
"JPY"
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectDocumentIdMissing",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"oracle": {{
|
|
"account": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectDocumentIdInvalidNegative",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"oracle": {{
|
|
"account": "{}",
|
|
"oracle_document_id": -1
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedDocumentID",
|
|
.expectedErrorMessage = "Malformed oracle_document_id."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectDocumentIdInvalidTypeString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"oracle": {{
|
|
"account": "{}",
|
|
"oracle_document_id": "invalid"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedDocumentID",
|
|
.expectedErrorMessage = "Malformed oracle_document_id."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectDocumentIdInvalidTypeDouble",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"oracle": {{
|
|
"account": "{}",
|
|
"oracle_document_id": 3.21
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedDocumentID",
|
|
.expectedErrorMessage = "Malformed oracle_document_id."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectDocumentIdInvalidTypeObject",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"oracle": {{
|
|
"account": "{}",
|
|
"oracle_document_id": {{}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedDocumentID",
|
|
.expectedErrorMessage = "Malformed oracle_document_id."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectDocumentIdInvalidTypeArray",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"oracle": {{
|
|
"account": "{}",
|
|
"oracle_document_id": []
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedDocumentID",
|
|
.expectedErrorMessage = "Malformed oracle_document_id."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectDocumentIdInvalidTypeNull",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"oracle": {{
|
|
"account": "{}",
|
|
"oracle_document_id": null
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedDocumentID",
|
|
.expectedErrorMessage = "Malformed oracle_document_id."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectAccountMissing",
|
|
.testJson = R"JSON({
|
|
"oracle": {
|
|
"oracle_document_id": 1
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectAccountInvalidTypeInteger",
|
|
.testJson = R"JSON({
|
|
"oracle": {
|
|
"account": 123,
|
|
"oracle_document_id": 1
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectAccountInvalidTypeDouble",
|
|
.testJson = R"JSON({
|
|
"oracle": {
|
|
"account": 123.45,
|
|
"oracle_document_id": 1
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectAccountInvalidTypeNull",
|
|
.testJson = R"JSON({
|
|
"oracle": {
|
|
"account": null,
|
|
"oracle_document_id": 1
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectAccountInvalidTypeObject",
|
|
.testJson = R"JSON({
|
|
"oracle": {
|
|
"account": {"test": "test"},
|
|
"oracle_document_id": 1
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectAccountInvalidTypeArray",
|
|
.testJson = R"JSON({
|
|
"oracle": {
|
|
"account": [{"test": "test"}],
|
|
"oracle_document_id": 1
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleObjectAccountInvalidFormat",
|
|
.testJson = R"JSON({
|
|
"oracle": {
|
|
"account": "NotHex",
|
|
"oracle_document_id": 1
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleStringInvalidFormat",
|
|
.testJson = R"JSON({
|
|
"oracle": "NotHex"
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleStringInvalidTypeInteger",
|
|
.testJson = R"JSON({
|
|
"oracle": 123
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleStringInvalidTypeDouble",
|
|
.testJson = R"JSON({
|
|
"oracle": 123.45
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleStringInvalidTypeArray",
|
|
.testJson = R"JSON({
|
|
"oracle": [{"test": "test"}]
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "OracleStringInvalidTypeNull",
|
|
.testJson = R"JSON({
|
|
"oracle": null
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "CredentialInvalidSubjectType",
|
|
.testJson = R"JSON({
|
|
"credential": {
|
|
"subject": 123
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "CredentialInvalidIssuerType",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"credential": {{
|
|
"issuer": ["{}"]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidMPTIssuanceStringIndex",
|
|
.testJson = R"JSON({
|
|
"mpt_issuance": "invalid"
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidMPTIssuanceType",
|
|
.testJson = R"JSON({
|
|
"mpt_issuance": 0
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidMPTokenStringIndex",
|
|
.testJson = R"JSON({
|
|
"mptoken": "invalid"
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidMPTokenObject",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"mptoken": {{}}
|
|
}})JSON"
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "MissingMPTokenID",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"mptoken": {{
|
|
"account": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "CredentialInvalidCredentialType",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"credential": {{
|
|
"subject": "{}",
|
|
"issuer": "{}",
|
|
"credential_type": 1234
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "CredentialMissingIssuerField",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"credential": {{
|
|
"subject": "{}",
|
|
"credential_type": "1234"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidMPTokenAccount",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"mptoken": {{
|
|
"mpt_issuance_id": "0000019315EABA24E6135A4B5CE2899E0DA791206413B33D",
|
|
"account": 1
|
|
}}
|
|
}})JSON"
|
|
),
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidMPTokenType",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"mptoken": 0
|
|
}})JSON"
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidPermissionedDomain_NotObject",
|
|
.testJson = R"JSON({"permissioned_domain": []})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidPermissionedDomain_InvalidString",
|
|
.testJson = R"JSON({"permissioned_domain": "invalid_string"})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidPermissionedDomain_EmptyObject",
|
|
.testJson = R"JSON({"permissioned_domain": {}})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidPermissionedDomain_BadAccount",
|
|
.testJson = R"JSON({"permissioned_domain": {"account": "1234", "seq": 1234}})JSON",
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidPermissionedDomain_MissingSeq",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"permissioned_domain": {{ "account": "{}" }}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidPermissionedDomain_SeqIsNotUint",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"permissioned_domain": {{ "account": "{}", "seq": -1 }}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidPermissionedDomain_BothAccountAndSeqAreInvalid",
|
|
.testJson =
|
|
R"JSON({
|
|
"permissioned_domain": { "account": "", "seq": -1 }
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidVault_Type",
|
|
.testJson =
|
|
R"JSON({
|
|
"vault": 0
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidVault_NotHex",
|
|
.testJson =
|
|
R"JSON({
|
|
"vault": "invalid_hex"
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "MissingOwner",
|
|
.testJson =
|
|
R"JSON({
|
|
"vault": { "seq": 1 }
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
|
|
ParamTestCaseBundle{
|
|
.testName = "MissingSeq",
|
|
.testJson =
|
|
R"JSON({
|
|
"vault": { "owner": "abcd" }
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "SeqNotInteger",
|
|
.testJson =
|
|
R"JSON({
|
|
"vault": {
|
|
"owner": "abcd",
|
|
"seq": "notAnInteger"
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "InvalidOwnerFormat",
|
|
.testJson =
|
|
R"JSON({
|
|
"vault": {
|
|
"owner": "abcd",
|
|
"seq": 10
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedOwner",
|
|
.expectedErrorMessage = "Malformed owner.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "BothOwnerAndSeqInvalid",
|
|
.testJson =
|
|
R"JSON({
|
|
"vault": {
|
|
"owner": "abcd",
|
|
"seq": -200
|
|
}
|
|
})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request.",
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "Delegate_InvalidType",
|
|
.testJson = R"JSON({"delegate": 123})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "Delegate_InvalidStringIndex",
|
|
.testJson = R"JSON({"delegate": "invalid_hex_string"})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "Delegate_EmptyObject",
|
|
.testJson = R"JSON({"delegate": {}})JSON",
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "Delegate_MissingAccount",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"delegate": {{
|
|
"authorize": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "Delegate_AccountNotString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"delegate": {{
|
|
"account": 123,
|
|
"authorize": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "Delegate_AccountInvalid",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"delegate": {{
|
|
"account": "invalid_address",
|
|
"authorize": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT2
|
|
),
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "Delegate_MissingAuthorize",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"delegate": {{
|
|
"account": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedRequest",
|
|
.expectedErrorMessage = "Malformed request."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "Delegate_AuthorizeNotString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"delegate": {{
|
|
"account": "{}",
|
|
"authorize": 123
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
ParamTestCaseBundle{
|
|
.testName = "Delegate_AuthorizeInvalid",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"delegate": {{
|
|
"account": "{}",
|
|
"authorize": "invalid_address"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedError = "malformedAddress",
|
|
.expectedErrorMessage = "Malformed address."
|
|
},
|
|
};
|
|
}
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
RPCLedgerEntryGroup1,
|
|
LedgerEntryParameterTest,
|
|
ValuesIn(generateTestValuesForParametersTest()),
|
|
tests::util::kNAME_GENERATOR
|
|
);
|
|
|
|
TEST_P(LedgerEntryParameterTest, InvalidParams)
|
|
{
|
|
auto const testBundle = GetParam();
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(testBundle.testJson);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), testBundle.expectedError);
|
|
EXPECT_EQ(err.at("error_message").as_string(), testBundle.expectedErrorMessage);
|
|
});
|
|
}
|
|
|
|
// parameterized test cases for index
|
|
struct IndexTest : public HandlerBaseTest, public WithParamInterface<std::string> {
|
|
struct NameGenerator {
|
|
template <class ParamType>
|
|
std::string
|
|
operator()(testing::TestParamInfo<ParamType> const& info) const
|
|
{
|
|
return static_cast<std::string>(info.param);
|
|
}
|
|
};
|
|
};
|
|
|
|
// content of index, payment_channel, nft_page and check fields is ledger index.
|
|
INSTANTIATE_TEST_CASE_P(
|
|
RPCLedgerEntryGroup3,
|
|
IndexTest,
|
|
Values("index", "nft_page", "payment_channel", "check"),
|
|
IndexTest::NameGenerator{}
|
|
);
|
|
|
|
TEST_P(IndexTest, InvalidIndexUint256)
|
|
{
|
|
auto const index = GetParam();
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"{}": "invalid"
|
|
}})JSON",
|
|
index
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), "malformedRequest");
|
|
EXPECT_EQ(err.at("error_message").as_string(), "Malformed request.");
|
|
});
|
|
}
|
|
|
|
TEST_P(IndexTest, InvalidIndexNotString)
|
|
{
|
|
auto const index = GetParam();
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"{}": 123
|
|
}})JSON",
|
|
index
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), "malformedRequest");
|
|
EXPECT_EQ(err.at("error_message").as_string(), "Malformed request.");
|
|
});
|
|
}
|
|
|
|
TEST_F(RPCLedgerEntryTest, LedgerEntryNotFound)
|
|
{
|
|
// return valid ledgerHeader
|
|
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerHeader));
|
|
|
|
// return null for ledger entry
|
|
auto const key = ripple::keylet::account(getAccountIdWithString(kACCOUNT)).key;
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(key, kRANGE_MAX, _)).WillRepeatedly(Return(std::optional<Blob>{}));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"account_root": "{}"
|
|
}})JSON",
|
|
kACCOUNT
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), "entryNotFound");
|
|
});
|
|
}
|
|
|
|
struct NormalPathTestBundle {
|
|
std::string testName;
|
|
std::string testJson;
|
|
ripple::uint256 expectedIndex;
|
|
ripple::STObject mockedEntity;
|
|
};
|
|
|
|
struct RPCLedgerEntryNormalPathTest : public RPCLedgerEntryTest, public WithParamInterface<NormalPathTestBundle> {};
|
|
|
|
static auto
|
|
generateTestValuesForNormalPathTest()
|
|
{
|
|
auto account1 = getAccountIdWithString(kACCOUNT);
|
|
auto account2 = getAccountIdWithString(kACCOUNT2);
|
|
ripple::Currency currency;
|
|
ripple::to_currency(currency, "USD");
|
|
|
|
return std::vector<NormalPathTestBundle>{
|
|
NormalPathTestBundle{
|
|
.testName = "Index",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"index": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createAccountRootObject(kACCOUNT2, ripple::lsfGlobalFreeze, 1, 10, 2, kINDEX1, 3)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "Payment_channel",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"payment_channel": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createPaymentChannelLedgerObject(kACCOUNT, kACCOUNT2, 100, 200, 300, kINDEX1, 400)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "Nft_page",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"nft_page": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createNftTokenPage(
|
|
std::vector{std::make_pair<std::string, std::string>(kTOKEN_ID, "www.ok.com")}, std::nullopt
|
|
)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "Check",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"check": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createCheckLedgerObject(kACCOUNT, kACCOUNT2)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DirectoryIndex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"directory": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createOwnerDirLedgerObject(std::vector<ripple::uint256>{ripple::uint256{kINDEX1}}, kINDEX1)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "OfferIndex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"offer": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createOfferLedgerObject(
|
|
kACCOUNT, 100, 200, "USD", "XRP", kACCOUNT2, ripple::toBase58(ripple::xrpAccount()), kINDEX1
|
|
)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "EscrowIndex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"escrow": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createEscrowLedgerObject(kACCOUNT, kACCOUNT2)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "TicketIndex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"ticket": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createTicketLedgerObject(kACCOUNT, 0)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DepositPreauthIndex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"deposit_preauth": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createDepositPreauthLedgerObjectByAuth(kACCOUNT, kACCOUNT2)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "AccountRoot",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"account_root": "{}"
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedIndex = ripple::keylet::account(getAccountIdWithString(kACCOUNT)).key,
|
|
.mockedEntity = createAccountRootObject(kACCOUNT, 0, 1, 1, 1, kINDEX1, 1)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DID",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"did": "{}"
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedIndex = ripple::keylet::did(getAccountIdWithString(kACCOUNT)).key,
|
|
.mockedEntity = createDidObject(kACCOUNT, "mydocument", "myURI", "mydata")
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DirectoryViaDirRoot",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"directory": {{
|
|
"dir_root": "{}",
|
|
"sub_index": 2
|
|
}}
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::keylet::page(ripple::uint256{kINDEX1}, 2).key,
|
|
.mockedEntity = createOwnerDirLedgerObject(std::vector<ripple::uint256>{ripple::uint256{kINDEX1}}, kINDEX1)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DirectoryViaOwner",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"directory": {{
|
|
"owner": "{}",
|
|
"sub_index": 2
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedIndex = ripple::keylet::page(ripple::keylet::ownerDir(account1), 2).key,
|
|
.mockedEntity = createOwnerDirLedgerObject(std::vector<ripple::uint256>{ripple::uint256{kINDEX1}}, kINDEX1)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DirectoryViaDefaultSubIndex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"directory": {{
|
|
"owner": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
// default sub_index is 0
|
|
.expectedIndex = ripple::keylet::page(ripple::keylet::ownerDir(account1), 0).key,
|
|
.mockedEntity = createOwnerDirLedgerObject(std::vector<ripple::uint256>{ripple::uint256{kINDEX1}}, kINDEX1)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "Escrow",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"escrow": {{
|
|
"owner": "{}",
|
|
"seq": 1
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedIndex = ripple::keylet::escrow(account1, 1).key,
|
|
.mockedEntity = createEscrowLedgerObject(kACCOUNT, kACCOUNT2)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DepositPreauthByAuth",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedIndex = ripple::keylet::depositPreauth(account1, account2).key,
|
|
.mockedEntity = createDepositPreauthLedgerObjectByAuth(kACCOUNT, kACCOUNT2)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DepositPreauthByAuthCredentials",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"deposit_preauth": {{
|
|
"owner": "{}",
|
|
"authorized_credentials": [
|
|
{{
|
|
"issuer": "{}",
|
|
"credential_type": "{}"
|
|
}}
|
|
]
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kCREDENTIAL_TYPE
|
|
),
|
|
.expectedIndex =
|
|
ripple::keylet::depositPreauth(
|
|
account1,
|
|
credentials::createAuthCredentials(createAuthCredentialArray(
|
|
std::vector<std::string_view>{kACCOUNT2}, std::vector<std::string_view>{kCREDENTIAL_TYPE}
|
|
))
|
|
)
|
|
.key,
|
|
.mockedEntity = createDepositPreauthLedgerObjectByAuthCredentials(kACCOUNT, kACCOUNT2, kCREDENTIAL_TYPE)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "Credentials",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"credential": {{
|
|
"subject": "{}",
|
|
"issuer": "{}",
|
|
"credential_type": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kCREDENTIAL_TYPE
|
|
),
|
|
.expectedIndex =
|
|
ripple::keylet::credential(
|
|
account1,
|
|
account2,
|
|
ripple::Slice(
|
|
ripple::strUnHex(kCREDENTIAL_TYPE)->data(), ripple::strUnHex(kCREDENTIAL_TYPE)->size()
|
|
)
|
|
)
|
|
.key,
|
|
.mockedEntity = createCredentialObject(kACCOUNT, kACCOUNT2, kCREDENTIAL_TYPE)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "RippleState",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"ripple_state": {{
|
|
"accounts": ["{}", "{}"],
|
|
"currency": "USD"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedIndex = ripple::keylet::line(account1, account2, currency).key,
|
|
.mockedEntity =
|
|
createRippleStateLedgerObject("USD", kACCOUNT2, 100, kACCOUNT, 10, kACCOUNT2, 20, kINDEX1, 123, 0)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "Ticket",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"ticket": {{
|
|
"account": "{}",
|
|
"ticket_seq": 2
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedIndex = ripple::getTicketIndex(account1, 2),
|
|
.mockedEntity = createTicketLedgerObject(kACCOUNT, 0)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "Offer",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"offer": {{
|
|
"account": "{}",
|
|
"seq": 2
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedIndex = ripple::keylet::offer(account1, 2).key,
|
|
.mockedEntity = createOfferLedgerObject(
|
|
kACCOUNT, 100, 200, "USD", "XRP", kACCOUNT2, ripple::toBase58(ripple::xrpAccount()), kINDEX1
|
|
)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "AMMViaIndex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"amm": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createAmmObject(kACCOUNT, "XRP", ripple::toBase58(ripple::xrpAccount()), "JPY", kACCOUNT2)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "AMMViaJson",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"amm": {{
|
|
"asset": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"asset2": {{
|
|
"currency": "{}",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
"JPY",
|
|
kACCOUNT2
|
|
),
|
|
.expectedIndex =
|
|
ripple::keylet::amm(getIssue("XRP", ripple::toBase58(ripple::xrpAccount())), getIssue("JPY", kACCOUNT2))
|
|
.key,
|
|
.mockedEntity = createAmmObject(kACCOUNT, "XRP", ripple::toBase58(ripple::xrpAccount()), "JPY", kACCOUNT2)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "BridgeLocking",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPY",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kACCOUNT3
|
|
),
|
|
.expectedIndex = ripple::keylet::bridge(
|
|
ripple::STXChainBridge(
|
|
getAccountIdWithString(kACCOUNT),
|
|
ripple::xrpIssue(),
|
|
getAccountIdWithString(kACCOUNT2),
|
|
getIssue("JPY", kACCOUNT3)
|
|
),
|
|
ripple::STXChainBridge::ChainType::locking
|
|
)
|
|
.key,
|
|
.mockedEntity = createBridgeObject(kACCOUNT, kACCOUNT, kACCOUNT2, "JPY", kACCOUNT3)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "BridgeIssuing",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"bridge_account": "{}",
|
|
"bridge": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPY",
|
|
"issuer": "{}"
|
|
}}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT2,
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kACCOUNT3
|
|
),
|
|
.expectedIndex = ripple::keylet::bridge(
|
|
ripple::STXChainBridge(
|
|
getAccountIdWithString(kACCOUNT),
|
|
ripple::xrpIssue(),
|
|
getAccountIdWithString(kACCOUNT2),
|
|
getIssue("JPY", kACCOUNT3)
|
|
),
|
|
ripple::STXChainBridge::ChainType::issuing
|
|
)
|
|
.key,
|
|
.mockedEntity = createBridgeObject(kACCOUNT, kACCOUNT, kACCOUNT2, "JPY", kACCOUNT3)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "XChainOwnedClaimId",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"xchain_owned_claim_id": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPY",
|
|
"issuer": "{}"
|
|
}},
|
|
"xchain_owned_claim_id": 10
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kACCOUNT3
|
|
),
|
|
.expectedIndex = ripple::keylet::xChainClaimID(
|
|
ripple::STXChainBridge(
|
|
getAccountIdWithString(kACCOUNT),
|
|
ripple::xrpIssue(),
|
|
getAccountIdWithString(kACCOUNT2),
|
|
getIssue("JPY", kACCOUNT3)
|
|
),
|
|
10
|
|
)
|
|
.key,
|
|
.mockedEntity = createChainOwnedClaimIdObject(kACCOUNT, kACCOUNT, kACCOUNT2, "JPY", kACCOUNT3, kACCOUNT)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "XChainOwnedCreateAccountClaimId",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"xchain_owned_create_account_claim_id": {{
|
|
"LockingChainDoor": "{}",
|
|
"IssuingChainDoor": "{}",
|
|
"LockingChainIssue": {{
|
|
"currency": "XRP"
|
|
}},
|
|
"IssuingChainIssue": {{
|
|
"currency": "JPY",
|
|
"issuer": "{}"
|
|
}},
|
|
"xchain_owned_create_account_claim_id": 10
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2,
|
|
kACCOUNT3
|
|
),
|
|
.expectedIndex = ripple::keylet::xChainCreateAccountClaimID(
|
|
ripple::STXChainBridge(
|
|
getAccountIdWithString(kACCOUNT),
|
|
ripple::xrpIssue(),
|
|
getAccountIdWithString(kACCOUNT2),
|
|
getIssue("JPY", kACCOUNT3)
|
|
),
|
|
10
|
|
)
|
|
.key,
|
|
.mockedEntity = createChainOwnedClaimIdObject(kACCOUNT, kACCOUNT, kACCOUNT2, "JPY", kACCOUNT3, kACCOUNT)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "OracleEntryFoundViaIntOracleDocumentId",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"oracle": {{
|
|
"account": "{}",
|
|
"oracle_document_id": 1
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedIndex = ripple::keylet::oracle(getAccountIdWithString(kACCOUNT), 1).key,
|
|
.mockedEntity = createOracleObject(
|
|
kACCOUNT,
|
|
"70726F7669646572",
|
|
32u,
|
|
1234u,
|
|
ripple::Blob(8, 's'),
|
|
ripple::Blob(8, 's'),
|
|
kRANGE_MAX - 2,
|
|
ripple::uint256{"E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC321"},
|
|
createPriceDataSeries(
|
|
{createOraclePriceData(2e4, ripple::to_currency("XRP"), ripple::to_currency("USD"), 3)}
|
|
)
|
|
)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "OracleEntryFoundViaStrOracleDocumentId",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"oracle": {{
|
|
"account": "{}",
|
|
"oracle_document_id": "1"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT
|
|
),
|
|
.expectedIndex = ripple::keylet::oracle(getAccountIdWithString(kACCOUNT), 1).key,
|
|
.mockedEntity = createOracleObject(
|
|
kACCOUNT,
|
|
"70726F7669646572",
|
|
32u,
|
|
1234u,
|
|
ripple::Blob(8, 's'),
|
|
ripple::Blob(8, 's'),
|
|
kRANGE_MAX - 2,
|
|
ripple::uint256{"E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC321"},
|
|
createPriceDataSeries(
|
|
{createOraclePriceData(2e4, ripple::to_currency("XRP"), ripple::to_currency("USD"), 3)}
|
|
)
|
|
)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "OracleEntryFoundViaString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"oracle": "{}"
|
|
}})JSON",
|
|
ripple::to_string(ripple::keylet::oracle(getAccountIdWithString(kACCOUNT), 1).key)
|
|
),
|
|
.expectedIndex = ripple::keylet::oracle(getAccountIdWithString(kACCOUNT), 1).key,
|
|
.mockedEntity = createOracleObject(
|
|
kACCOUNT,
|
|
"70726F7669646572",
|
|
64u,
|
|
4321u,
|
|
ripple::Blob(8, 'a'),
|
|
ripple::Blob(8, 'a'),
|
|
kRANGE_MAX - 4,
|
|
ripple::uint256{"E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC321"},
|
|
createPriceDataSeries(
|
|
{createOraclePriceData(1e3, ripple::to_currency("USD"), ripple::to_currency("XRP"), 2)}
|
|
)
|
|
)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "MPTIssuance",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"mpt_issuance": "{}"
|
|
}})JSON",
|
|
ripple::to_string(ripple::makeMptID(2, account1))
|
|
),
|
|
.expectedIndex = ripple::keylet::mptIssuance(ripple::makeMptID(2, account1)).key,
|
|
.mockedEntity = createMptIssuanceObject(kACCOUNT, 2, "metadata")
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "MPTokenViaIndex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"mptoken": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createMpTokenObject(kACCOUNT, ripple::makeMptID(2, account1))
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "MPTokenViaObject",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"mptoken": {{
|
|
"account": "{}",
|
|
"mpt_issuance_id": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
ripple::to_string(ripple::makeMptID(2, account1))
|
|
),
|
|
.expectedIndex = ripple::keylet::mptoken(ripple::makeMptID(2, account1), account1).key,
|
|
.mockedEntity = createMpTokenObject(kACCOUNT, ripple::makeMptID(2, account1))
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "PermissionedDomainViaString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"permissioned_domain": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256(kINDEX1),
|
|
.mockedEntity = createPermissionedDomainObject(kACCOUNT, kINDEX1, kRANGE_MAX, 0, ripple::uint256{0}, 0)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "PermissionedDomainViaObject",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"permissioned_domain": {{
|
|
"account": "{}",
|
|
"seq": {}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kRANGE_MAX
|
|
),
|
|
.expectedIndex =
|
|
ripple::keylet::permissionedDomain(ripple::parseBase58<ripple::AccountID>(kACCOUNT).value(), kRANGE_MAX)
|
|
.key,
|
|
.mockedEntity = createPermissionedDomainObject(kACCOUNT, kINDEX1, kRANGE_MAX, 0, ripple::uint256{0}, 0)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "CreateVaultObjectByHexString",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"vault": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256(kINDEX1),
|
|
.mockedEntity = createVault(
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kRANGE_MAX,
|
|
"XRP",
|
|
ripple::toBase58(ripple::xrpAccount()),
|
|
ripple::uint192(0),
|
|
0,
|
|
ripple::uint256{0},
|
|
0
|
|
)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "CreateVaultObjectByAccount",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"vault": {{
|
|
"owner": "{}",
|
|
"seq": {}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kRANGE_MAX
|
|
),
|
|
.expectedIndex =
|
|
ripple::keylet::vault(ripple::parseBase58<ripple::AccountID>(kACCOUNT).value(), kRANGE_MAX).key,
|
|
.mockedEntity = createVault(
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kRANGE_MAX,
|
|
"XRP",
|
|
ripple::toBase58(ripple::xrpAccount()),
|
|
ripple::uint192(0),
|
|
0,
|
|
ripple::uint256{0},
|
|
0
|
|
)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DelegateViaStringIndex",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"delegate": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
),
|
|
.expectedIndex = ripple::uint256{kINDEX1},
|
|
.mockedEntity = createDelegateObject(kACCOUNT, kACCOUNT2, kINDEX1, 0, ripple::uint256{0}, 0)
|
|
},
|
|
NormalPathTestBundle{
|
|
.testName = "DelegateViaObject",
|
|
.testJson = fmt::format(
|
|
R"JSON({{
|
|
"binary": true,
|
|
"delegate": {{
|
|
"account": "{}",
|
|
"authorize": "{}"
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kACCOUNT2
|
|
),
|
|
.expectedIndex =
|
|
ripple::keylet::delegate(getAccountIdWithString(kACCOUNT), getAccountIdWithString(kACCOUNT2)).key,
|
|
.mockedEntity = createDelegateObject(kACCOUNT, kACCOUNT2, kINDEX1, 0, ripple::uint256{0}, 0)
|
|
},
|
|
};
|
|
}
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
RPCLedgerEntryGroup2,
|
|
RPCLedgerEntryNormalPathTest,
|
|
ValuesIn(generateTestValuesForNormalPathTest()),
|
|
tests::util::kNAME_GENERATOR
|
|
);
|
|
|
|
// Test for normal path
|
|
// Check the index in response matches the computed index accordingly
|
|
TEST_P(RPCLedgerEntryNormalPathTest, NormalPath)
|
|
{
|
|
auto const testBundle = GetParam();
|
|
|
|
// return valid ledgerHeader
|
|
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerHeader));
|
|
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(testBundle.expectedIndex, kRANGE_MAX, _))
|
|
.WillRepeatedly(Return(testBundle.mockedEntity.getSerializer().peekData()));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(testBundle.testJson);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_TRUE(output);
|
|
auto const& outputJson = output.result.value();
|
|
EXPECT_EQ(outputJson.at("ledger_hash").as_string(), kLEDGER_HASH);
|
|
EXPECT_EQ(outputJson.at("ledger_index").as_uint64(), kRANGE_MAX);
|
|
EXPECT_EQ(
|
|
outputJson.at("node_binary").as_string(), ripple::strHex(testBundle.mockedEntity.getSerializer().peekData())
|
|
);
|
|
EXPECT_EQ(
|
|
ripple::uint256(boost::json::value_to<std::string>(outputJson.at("index")).data()), testBundle.expectedIndex
|
|
);
|
|
});
|
|
}
|
|
|
|
// this testcase will test the deserialization of ledger entry
|
|
TEST_F(RPCLedgerEntryTest, BinaryFalse)
|
|
{
|
|
static constexpr auto kOUT = R"JSON({
|
|
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
|
"ledger_index": 30,
|
|
"validated": true,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"node": {
|
|
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
|
"Amount": "100",
|
|
"Balance": "200",
|
|
"Destination": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
|
|
"Flags": 0,
|
|
"LedgerEntryType": "PayChannel",
|
|
"OwnerNode": "0",
|
|
"PreviousTxnID": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"PreviousTxnLgrSeq": 400,
|
|
"PublicKey": "020000000000000000000000000000000000000000000000000000000000000000",
|
|
"SettleDelay": 300,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD"
|
|
}
|
|
})JSON";
|
|
|
|
// return valid ledgerHeader
|
|
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerHeader));
|
|
|
|
// return valid ledger entry which can be deserialized
|
|
auto const ledgerEntry = createPaymentChannelLedgerObject(kACCOUNT, kACCOUNT2, 100, 200, 300, kINDEX1, 400);
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillRepeatedly(Return(ledgerEntry.getSerializer().peekData()));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"payment_channel": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_TRUE(output);
|
|
EXPECT_EQ(*output.result, json::parse(kOUT));
|
|
});
|
|
}
|
|
|
|
TEST_F(RPCLedgerEntryTest, Vault_BinaryFalse)
|
|
{
|
|
// return valid ledgerHeader
|
|
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerHeader));
|
|
|
|
boost::json::object const entry;
|
|
|
|
auto const vault = createVault(
|
|
kACCOUNT,
|
|
kACCOUNT,
|
|
kRANGE_MAX,
|
|
"XRP",
|
|
ripple::toBase58(ripple::xrpAccount()),
|
|
ripple::uint192(0),
|
|
0,
|
|
ripple::uint256{1},
|
|
0
|
|
);
|
|
|
|
auto const vaultKey =
|
|
ripple::keylet::vault(ripple::parseBase58<ripple::AccountID>(kACCOUNT).value(), kRANGE_MAX).key;
|
|
|
|
ripple::STLedgerEntry const sle{
|
|
ripple::SerialIter{vault.getSerializer().peekData().data(), vault.getSerializer().peekData().size()}, vaultKey
|
|
};
|
|
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(vaultKey, testing::_, testing::_))
|
|
.WillOnce(Return(vault.getSerializer().peekData()));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"binary": false,
|
|
"vault": {{
|
|
"owner": "{}",
|
|
"seq": {}
|
|
}}
|
|
}})JSON",
|
|
kACCOUNT,
|
|
kRANGE_MAX
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_TRUE(output);
|
|
|
|
EXPECT_EQ(output.result->at("node").at("Owner").as_string(), kACCOUNT);
|
|
EXPECT_EQ(output.result->at("node").at("Sequence").as_int64(), kRANGE_MAX);
|
|
});
|
|
}
|
|
|
|
TEST_F(RPCLedgerEntryTest, UnexpectedLedgerType)
|
|
{
|
|
// return valid ledgerHeader
|
|
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerHeader));
|
|
|
|
// return valid ledger entry which can be deserialized
|
|
auto const ledgerEntry = createPaymentChannelLedgerObject(kACCOUNT, kACCOUNT2, 100, 200, 300, kINDEX1, 400);
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillRepeatedly(Return(ledgerEntry.getSerializer().peekData()));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"check": "{}"
|
|
}})JSON",
|
|
kINDEX1
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), "unexpectedLedgerType");
|
|
});
|
|
}
|
|
|
|
TEST_F(RPCLedgerEntryTest, LedgerNotExistViaIntSequence)
|
|
{
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(std::nullopt));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"check": "{}",
|
|
"ledger_index": {}
|
|
}})JSON",
|
|
kINDEX1,
|
|
kRANGE_MAX
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), "lgrNotFound");
|
|
EXPECT_EQ(err.at("error_message").as_string(), "ledgerNotFound");
|
|
});
|
|
}
|
|
|
|
TEST_F(RPCLedgerEntryTest, LedgerNotExistViaStringSequence)
|
|
{
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(std::nullopt));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"check": "{}",
|
|
"ledger_index": "{}"
|
|
}})JSON",
|
|
kINDEX1,
|
|
kRANGE_MAX
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), "lgrNotFound");
|
|
EXPECT_EQ(err.at("error_message").as_string(), "ledgerNotFound");
|
|
});
|
|
}
|
|
|
|
TEST_F(RPCLedgerEntryTest, LedgerNotExistViaHash)
|
|
{
|
|
EXPECT_CALL(*backend_, fetchLedgerByHash(ripple::uint256{kLEDGER_HASH}, _)).WillRepeatedly(Return(std::nullopt));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"check": "{}",
|
|
"ledger_hash": "{}"
|
|
}})JSON",
|
|
kINDEX1,
|
|
kLEDGER_HASH
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), "lgrNotFound");
|
|
EXPECT_EQ(err.at("error_message").as_string(), "ledgerNotFound");
|
|
});
|
|
}
|
|
|
|
TEST_F(RPCLedgerEntryTest, InvalidEntryTypeVersion2)
|
|
{
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(R"JSON({})JSON");
|
|
auto const output = handler.process(req, Context{.yield = yield, .apiVersion = 2});
|
|
ASSERT_FALSE(output);
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), "invalidParams");
|
|
EXPECT_EQ(err.at("error_message").as_string(), "Invalid parameters.");
|
|
});
|
|
}
|
|
|
|
TEST_F(RPCLedgerEntryTest, InvalidEntryTypeVersion1)
|
|
{
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(R"JSON({})JSON");
|
|
auto const output = handler.process(req, Context{.yield = yield, .apiVersion = 1});
|
|
ASSERT_FALSE(output);
|
|
auto const err = rpc::makeError(output.result.error());
|
|
EXPECT_EQ(err.at("error").as_string(), "unknownOption");
|
|
EXPECT_EQ(err.at("error_message").as_string(), "Unknown option.");
|
|
});
|
|
}
|
|
|
|
TEST(RPCLedgerEntrySpecTest, DeprecatedFields)
|
|
{
|
|
boost::json::value const json{{"ledger", 2}};
|
|
auto const spec = LedgerEntryHandler::spec(2);
|
|
auto const warnings = spec.check(json);
|
|
ASSERT_EQ(warnings.size(), 1);
|
|
ASSERT_TRUE(warnings[0].is_object());
|
|
auto const& warning = warnings[0].as_object();
|
|
ASSERT_TRUE(warning.contains("id"));
|
|
ASSERT_TRUE(warning.contains("message"));
|
|
EXPECT_EQ(warning.at("id").as_int64(), static_cast<int64_t>(rpc::WarningCode::WarnRpcDeprecated));
|
|
EXPECT_NE(warning.at("message").as_string().find("Field 'ledger' is deprecated."), std::string::npos) << warning;
|
|
}
|
|
|
|
// Same as BinaryFalse with include_deleted set to true
|
|
// Expected Result: same as BinaryFalse
|
|
TEST_F(RPCLedgerEntryTest, BinaryFalseIncludeDeleted)
|
|
{
|
|
static constexpr auto kOUT = R"JSON({
|
|
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
|
"ledger_index": 30,
|
|
"validated": true,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"node": {
|
|
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
|
"Amount": "100",
|
|
"Balance": "200",
|
|
"Destination": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
|
|
"Flags": 0,
|
|
"LedgerEntryType": "PayChannel",
|
|
"OwnerNode": "0",
|
|
"PreviousTxnID": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"PreviousTxnLgrSeq": 400,
|
|
"PublicKey": "020000000000000000000000000000000000000000000000000000000000000000",
|
|
"SettleDelay": 300,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD"
|
|
}
|
|
})JSON";
|
|
|
|
// return valid ledgerinfo
|
|
auto const ledgerinfo = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerinfo));
|
|
|
|
// return valid ledger entry which can be deserialized
|
|
auto const ledgerEntry = createPaymentChannelLedgerObject(kACCOUNT, kACCOUNT2, 100, 200, 300, kINDEX1, 400);
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillRepeatedly(Return(ledgerEntry.getSerializer().peekData()));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"index": "{}",
|
|
"include_deleted": true
|
|
}})JSON",
|
|
kINDEX1
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_TRUE(output);
|
|
EXPECT_EQ(*output.result, json::parse(kOUT));
|
|
});
|
|
}
|
|
|
|
// Test for object is deleted in the latest sequence
|
|
// Expected Result: return the latest object that is not deleted
|
|
TEST_F(RPCLedgerEntryTest, LedgerEntryDeleted)
|
|
{
|
|
static constexpr auto kOUT = R"JSON({
|
|
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
|
"ledger_index": 30,
|
|
"validated": true,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"deleted_ledger_index": 30,
|
|
"node": {
|
|
"Amount": "123",
|
|
"Flags": 0,
|
|
"LedgerEntryType": "NFTokenOffer",
|
|
"NFTokenID": "00010000A7CAD27B688D14BA1A9FA5366554D6ADCF9CE0875B974D9F00000004",
|
|
"NFTokenOfferNode": "0",
|
|
"Owner": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
|
"OwnerNode": "0",
|
|
"PreviousTxnID": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
"PreviousTxnLgrSeq": 0,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD"
|
|
}
|
|
})JSON";
|
|
auto const ledgerinfo = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerinfo));
|
|
// return valid ledger entry which can be deserialized
|
|
auto const offer = createNftBuyOffer(kNFT_ID, kACCOUNT);
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillOnce(Return(std::optional<Blob>{}));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObjectSeq(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillOnce(Return(uint32_t{kRANGE_MAX}));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX - 1, _))
|
|
.WillOnce(Return(offer.getSerializer().peekData()));
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"index": "{}",
|
|
"include_deleted": true
|
|
}})JSON",
|
|
kINDEX1
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_TRUE(output);
|
|
EXPECT_EQ(*output.result, json::parse(kOUT));
|
|
});
|
|
}
|
|
|
|
// Test for object not exist in database
|
|
// Expected Result: return entryNotFound error
|
|
TEST_F(RPCLedgerEntryTest, LedgerEntryNotExist)
|
|
{
|
|
auto const ledgerinfo = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerinfo));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillOnce(Return(std::optional<Blob>{}));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObjectSeq(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillOnce(Return(uint32_t{kRANGE_MAX}));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX - 1, _))
|
|
.WillOnce(Return(std::optional<Blob>{}));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"index": "{}",
|
|
"include_deleted": true
|
|
}})JSON",
|
|
kINDEX1
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
auto const err = rpc::makeError(output.result.error());
|
|
auto const myerr = err.at("error").as_string();
|
|
EXPECT_EQ(myerr, "entryNotFound");
|
|
});
|
|
}
|
|
|
|
// Same as BinaryFalse with include_deleted set to false
|
|
// Expected Result: same as BinaryFalse
|
|
TEST_F(RPCLedgerEntryTest, BinaryFalseIncludeDeleteFalse)
|
|
{
|
|
static constexpr auto kOUT = R"JSON({
|
|
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
|
"ledger_index": 30,
|
|
"validated": true,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"node": {
|
|
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
|
"Amount": "100",
|
|
"Balance": "200",
|
|
"Destination": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
|
|
"Flags": 0,
|
|
"LedgerEntryType": "PayChannel",
|
|
"OwnerNode": "0",
|
|
"PreviousTxnID": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"PreviousTxnLgrSeq": 400,
|
|
"PublicKey": "020000000000000000000000000000000000000000000000000000000000000000",
|
|
"SettleDelay": 300,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD"
|
|
}
|
|
})JSON";
|
|
|
|
// return valid ledgerinfo
|
|
auto const ledgerinfo = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerinfo));
|
|
|
|
// return valid ledger entry which can be deserialized
|
|
auto const ledgerEntry = createPaymentChannelLedgerObject(kACCOUNT, kACCOUNT2, 100, 200, 300, kINDEX1, 400);
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillRepeatedly(Return(ledgerEntry.getSerializer().peekData()));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"payment_channel": "{}",
|
|
"include_deleted": false
|
|
}})JSON",
|
|
kINDEX1
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_TRUE(output);
|
|
EXPECT_EQ(*output.result, json::parse(kOUT));
|
|
});
|
|
}
|
|
|
|
// Test when an object is updated and include_deleted is set to true
|
|
// Expected Result: return the latest object that is not deleted (latest object in this test)
|
|
TEST_F(RPCLedgerEntryTest, ObjectUpdateIncludeDelete)
|
|
{
|
|
static constexpr auto kOUT = R"JSON({
|
|
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
|
"ledger_index": 30,
|
|
"validated": true,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"node": {
|
|
"Balance": {
|
|
"currency": "USD",
|
|
"issuer": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
|
|
"value": "10"
|
|
},
|
|
"Flags": 0,
|
|
"HighLimit": {
|
|
"currency": "USD",
|
|
"issuer": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
|
|
"value": "200"
|
|
},
|
|
"LedgerEntryType": "RippleState",
|
|
"LowLimit": {
|
|
"currency": "USD",
|
|
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
|
"value": "100"
|
|
},
|
|
"PreviousTxnID": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"PreviousTxnLgrSeq": 123,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD"
|
|
}
|
|
})JSON";
|
|
|
|
// return valid ledgerinfo
|
|
auto const ledgerinfo = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerinfo));
|
|
|
|
// return valid ledger entry which can be deserialized
|
|
auto const line1 = createRippleStateLedgerObject("USD", kACCOUNT2, 10, kACCOUNT, 100, kACCOUNT2, 200, kTXN_ID, 123);
|
|
auto const line2 = createRippleStateLedgerObject("USD", kACCOUNT, 10, kACCOUNT2, 100, kACCOUNT, 200, kTXN_ID, 123);
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillRepeatedly(Return(line1.getSerializer().peekData()));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX - 1, _))
|
|
.WillRepeatedly(Return(line2.getSerializer().peekData()));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"index": "{}",
|
|
"include_deleted": true
|
|
}})JSON",
|
|
kINDEX1
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_TRUE(output);
|
|
EXPECT_EQ(*output.result, json::parse(kOUT));
|
|
});
|
|
}
|
|
|
|
// Test when an object is deleted several sequence ago and include_deleted is set to true
|
|
// Expected Result: return the latest object that is not deleted
|
|
TEST_F(RPCLedgerEntryTest, ObjectDeletedPreviously)
|
|
{
|
|
static constexpr auto kOUT = R"JSON({
|
|
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
|
"ledger_index": 30,
|
|
"validated": true,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD",
|
|
"deleted_ledger_index": 26,
|
|
"node": {
|
|
"Amount": "123",
|
|
"Flags": 0,
|
|
"LedgerEntryType": "NFTokenOffer",
|
|
"NFTokenID": "00010000A7CAD27B688D14BA1A9FA5366554D6ADCF9CE0875B974D9F00000004",
|
|
"NFTokenOfferNode": "0",
|
|
"Owner": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
|
"OwnerNode": "0",
|
|
"PreviousTxnID": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
"PreviousTxnLgrSeq": 0,
|
|
"index": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD"
|
|
}
|
|
})JSON";
|
|
auto const ledgerinfo = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerinfo));
|
|
// return valid ledger entry which can be deserialized
|
|
auto const offer = createNftBuyOffer(kNFT_ID, kACCOUNT);
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillOnce(Return(std::optional<Blob>{}));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObjectSeq(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillOnce(Return(uint32_t{kRANGE_MAX - 4}));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX - 5, _))
|
|
.WillOnce(Return(offer.getSerializer().peekData()));
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"index": "{}",
|
|
"include_deleted": true
|
|
}})JSON",
|
|
kINDEX1
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_TRUE(output);
|
|
EXPECT_EQ(*output.result, json::parse(kOUT));
|
|
});
|
|
}
|
|
|
|
// Test for object seq not exist in database
|
|
// Expected Result: return entryNotFound error
|
|
TEST_F(RPCLedgerEntryTest, ObjectSeqNotExist)
|
|
{
|
|
auto const ledgerinfo = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerinfo));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillOnce(Return(std::optional<Blob>{}));
|
|
EXPECT_CALL(*backend_, doFetchLedgerObjectSeq(ripple::uint256{kINDEX1}, kRANGE_MAX, _))
|
|
.WillOnce(Return(std::nullopt));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"index": "{}",
|
|
"include_deleted": true
|
|
}})JSON",
|
|
kINDEX1
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_FALSE(output);
|
|
auto const err = rpc::makeError(output.result.error());
|
|
auto const myerr = err.at("error").as_string();
|
|
EXPECT_EQ(myerr, "entryNotFound");
|
|
});
|
|
}
|
|
|
|
// this testcase will test the if response includes synthetic mpt_issuance_id
|
|
TEST_F(RPCLedgerEntryTest, SyntheticMPTIssuanceID)
|
|
{
|
|
static constexpr auto kOUT = R"JSON({
|
|
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
|
"ledger_index": 30,
|
|
"validated": true,
|
|
"index": "FD7E7EFAE2A20E75850D0E0590B205E2F74DC472281768CD6E03988069816336",
|
|
"node": {
|
|
"Flags": 0,
|
|
"Issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
|
"LedgerEntryType": "MPTokenIssuance",
|
|
"MPTokenMetadata": "6D65746164617461",
|
|
"MaximumAmount": "0",
|
|
"OutstandingAmount": "0",
|
|
"OwnerNode": "0",
|
|
"PreviousTxnID": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
"PreviousTxnLgrSeq": 0,
|
|
"Sequence": 2,
|
|
"index": "FD7E7EFAE2A20E75850D0E0590B205E2F74DC472281768CD6E03988069816336",
|
|
"mpt_issuance_id": "000000024B4E9C06F24296074F7BC48F92A97916C6DC5EA9"
|
|
}
|
|
})JSON";
|
|
|
|
auto const mptId = ripple::makeMptID(2, getAccountIdWithString(kACCOUNT));
|
|
|
|
// return valid ledgerHeader
|
|
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kRANGE_MAX);
|
|
EXPECT_CALL(*backend_, fetchLedgerBySequence(kRANGE_MAX, _)).WillRepeatedly(Return(ledgerHeader));
|
|
|
|
// return valid ledger entry which can be deserialized
|
|
auto const ledgerEntry = createMptIssuanceObject(kACCOUNT, 2, "metadata");
|
|
EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::keylet::mptIssuance(mptId).key, kRANGE_MAX, _))
|
|
.WillRepeatedly(Return(ledgerEntry.getSerializer().peekData()));
|
|
|
|
runSpawn([&, this](auto yield) {
|
|
auto const handler = AnyHandler{LedgerEntryHandler{backend_}};
|
|
auto const req = json::parse(
|
|
fmt::format(
|
|
R"JSON({{
|
|
"mpt_issuance": "{}"
|
|
}})JSON",
|
|
ripple::to_string(mptId)
|
|
)
|
|
);
|
|
auto const output = handler.process(req, Context{yield});
|
|
ASSERT_TRUE(output);
|
|
EXPECT_EQ(*output.result, json::parse(kOUT));
|
|
});
|
|
}
|