Unify json (#992)

Fix #962
This commit is contained in:
cyan317
2023-11-20 13:09:28 +00:00
committed by GitHub
parent 1bacad9e49
commit db08de466a
16 changed files with 976 additions and 149 deletions

View File

@@ -418,3 +418,54 @@ TEST_F(RPCHelpersTest, DeliverMaxAliasV2)
)
);
}
TEST_F(RPCHelpersTest, LedgerHeaderJson)
{
auto const ledgerHeader = CreateLedgerInfo(INDEX1, 30);
auto const binJson = toJson(ledgerHeader, true);
auto constexpr EXPECTBIN = R"({
"ledger_data": "0000001E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"closed": true
})";
EXPECT_EQ(binJson, boost::json::parse(EXPECTBIN));
auto const EXPECTJSON = fmt::format(
R"({{
"account_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"close_flags": 0,
"close_time": 0,
"close_time_resolution": 0,
"close_time_iso": "2000-01-01T00:00:00Z",
"ledger_hash": "{}",
"ledger_index": "{}",
"parent_close_time": 0,
"parent_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"total_coins": "0",
"transaction_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"closed": true
}})",
INDEX1,
30
);
auto json = toJson(ledgerHeader, false);
// remove platform-related close_time_human field
json.erase(JS(close_time_human));
EXPECT_EQ(json, boost::json::parse(EXPECTJSON));
}
TEST_F(RPCHelpersTest, TransactionAndMetadataBinaryJsonV1)
{
auto const txMeta = CreateAcceptNFTOfferTxWithMetadata(ACCOUNT, 30, 1, INDEX1);
auto const json = toJsonWithBinaryTx(txMeta, 1);
EXPECT_TRUE(json.contains(JS(tx_blob)));
EXPECT_TRUE(json.contains(JS(meta)));
}
TEST_F(RPCHelpersTest, TransactionAndMetadataBinaryJsonV2)
{
auto const txMeta = CreateAcceptNFTOfferTxWithMetadata(ACCOUNT, 30, 1, INDEX1);
auto const json = toJsonWithBinaryTx(txMeta, 2);
EXPECT_TRUE(json.contains(JS(tx_blob)));
EXPECT_TRUE(json.contains(JS(meta_blob)));
}

View File

@@ -670,6 +670,64 @@ TEST_F(RPCAccountTxHandlerTest, BinaryTrue)
});
}
TEST_F(RPCAccountTxHandlerTest, BinaryTrueV2)
{
mockBackendPtr->updateRange(MINSEQ); // min
mockBackendPtr->updateRange(MAXSEQ); // max
MockBackend* rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
ASSERT_NE(rawBackendPtr, nullptr);
auto const transactions = genTransactions(MINSEQ + 1, MAXSEQ - 1);
auto const transCursor = TransactionsAndCursor{transactions, TransactionsCursor{12, 34}};
EXPECT_CALL(
*rawBackendPtr,
fetchAccountTransactions(
testing::_,
testing::_,
false,
testing::Optional(testing::Eq(TransactionsCursor{MAXSEQ, INT32_MAX})),
testing::_
)
)
.WillOnce(Return(transCursor));
runSpawn([&, this](auto yield) {
auto const handler = AnyHandler{AccountTxHandler{mockBackendPtr}};
auto const static input = json::parse(fmt::format(
R"({{
"account": "{}",
"ledger_index_min": {},
"ledger_index_max": {},
"binary": true
}})",
ACCOUNT,
-1,
-1
));
auto const output = handler.process(input, Context{.yield = yield, .apiVersion = 2u});
ASSERT_TRUE(output);
EXPECT_EQ(output->at("account").as_string(), ACCOUNT);
EXPECT_EQ(output->at("ledger_index_min").as_uint64(), MINSEQ);
EXPECT_EQ(output->at("ledger_index_max").as_uint64(), MAXSEQ);
EXPECT_EQ(output->at("marker").as_object(), json::parse(R"({"ledger": 12, "seq": 34})"));
EXPECT_EQ(output->at("transactions").as_array().size(), 2);
EXPECT_EQ(
output->at("transactions").as_array()[0].as_object().at("meta_blob").as_string(),
"201C00000000F8E5110061E762400000000000001681144B4E9C06F24296074F7B"
"C48F92A97916C6DC5EA9E1E1E5110061E76240000000000000178114D31252CF90"
"2EF8DD8451243869B38667CBD89DF3E1E1F1031000"
);
EXPECT_EQ(
output->at("transactions").as_array()[0].as_object().at("tx_blob").as_string(),
"120000240000002061400000000000000168400000000000000173047465737481"
"144B4E9C06F24296074F7BC48F92A97916C6DC5EA98314D31252CF902EF8DD8451"
"243869B38667CBD89DF3"
);
EXPECT_FALSE(output->at("transactions").as_array()[0].as_object().contains("date"));
EXPECT_FALSE(output->at("transactions").as_array()[0].as_object().contains("inLedger"));
EXPECT_FALSE(output->as_object().contains("limit"));
});
}
TEST_F(RPCAccountTxHandlerTest, LimitAndMarker)
{
mockBackendPtr->updateRange(MINSEQ); // min
@@ -1287,7 +1345,11 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
"TransactionResult": "tesSUCCESS",
"nftoken_id": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DF"
},
"tx":
"hash": "C74463F49CFDCBEF3E9902672719918CDE5042DC7E7660BEBD1D1105C4B6DFF4",
"ledger_index": 11,
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"close_time_iso": "2000-01-01T00:00:00Z",
"tx_json":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee": "50",
@@ -1295,7 +1357,6 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
"Sequence": 1,
"SigningPubKey": "74657374",
"TransactionType": "NFTokenMint",
"hash": "C74463F49CFDCBEF3E9902672719918CDE5042DC7E7660BEBD1D1105C4B6DFF4",
"ledger_index": 11,
"date": 1
},
@@ -1321,7 +1382,11 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
"TransactionResult": "tesSUCCESS",
"nftoken_id": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DA"
},
"tx":
"hash": "7682BE6BCDE62F8142915DD852936623B68FC3839A8A424A6064B898702B0CDF",
"ledger_index": 11,
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"close_time_iso": "2000-01-01T00:00:00Z",
"tx_json":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee": "50",
@@ -1329,7 +1394,6 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
"Sequence": 1,
"SigningPubKey": "74657374",
"TransactionType": "NFTokenAcceptOffer",
"hash": "7682BE6BCDE62F8142915DD852936623B68FC3839A8A424A6064B898702B0CDF",
"ledger_index": 11,
"date": 2
},
@@ -1368,7 +1432,11 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
"15FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DF"
]
},
"tx":
"hash": "9F82743EEB30065FB9CB92C61F0F064B5859C5A590FA811FAAAD9C988E5B47DB",
"ledger_index": 11,
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"close_time_iso": "2000-01-01T00:00:00Z",
"tx_json":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee": "50",
@@ -1380,7 +1448,6 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
"Sequence": 1,
"SigningPubKey": "74657374",
"TransactionType": "NFTokenCancelOffer",
"hash": "9F82743EEB30065FB9CB92C61F0F064B5859C5A590FA811FAAAD9C988E5B47DB",
"ledger_index": 11,
"date": 3
},
@@ -1403,7 +1470,11 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
"TransactionResult": "tesSUCCESS",
"offer_id": "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DA"
},
"tx":
"hash": "ECB1837EB7C7C0AC22ECDCCE59FDD4795C70E0B9D8F4E1C9A9408BB7EC75DA5C",
"ledger_index": 11,
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"close_time_iso": "2000-01-01T00:00:00Z",
"tx_json":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Amount": "123",
@@ -1412,7 +1483,6 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
"Sequence": 1,
"SigningPubKey": "74657374",
"TransactionType": "NFTokenCreateOffer",
"hash": "ECB1837EB7C7C0AC22ECDCCE59FDD4795C70E0B9D8F4E1C9A9408BB7EC75DA5C",
"ledger_index": 11,
"date": 4
},
@@ -1441,6 +1511,9 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
)
.Times(1);
auto const ledgerInfo = CreateLedgerInfo(LEDGERHASH, 11);
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).Times(transactions.size()).WillRepeatedly(Return(ledgerInfo));
runSpawn([&, this](auto yield) {
auto const handler = AnyHandler{AccountTxHandler{mockBackendPtr}};
auto const static input = json::parse(fmt::format(
@@ -1738,6 +1811,10 @@ generateTransactionTypeTestValues()
})",
R"([
{
"hash": "51D2AAA6B8E4E16EF22F6424854283D8391B56875858A711B8CE4D5B9A422CC2",
"ledger_index": 30,
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"close_time_iso": "2000-01-01T00:00:00Z",
"meta": {
"AffectedNodes": [
{
@@ -1762,7 +1839,7 @@ generateTransactionTypeTestValues()
"TransactionResult": "tesSUCCESS",
"delivered_amount": "unavailable"
},
"tx": {
"tx_json": {
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"DeliverMax": "1",
"Destination": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
@@ -1770,7 +1847,6 @@ generateTransactionTypeTestValues()
"Sequence": 32,
"SigningPubKey": "74657374",
"TransactionType": "Payment",
"hash": "51D2AAA6B8E4E16EF22F6424854283D8391B56875858A711B8CE4D5B9A422CC2",
"ledger_index": 30,
"date": 1
},
@@ -1860,8 +1936,8 @@ TEST_P(AccountTxTransactionTypeTest, SpecificTransactionType)
.Times(1);
auto const ledgerinfo = CreateLedgerInfo(LEDGERHASH, MAXSEQ);
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).Times(1);
ON_CALL(*rawBackendPtr, fetchLedgerBySequence(MAXSEQ, _)).WillByDefault(Return(ledgerinfo));
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence(MAXSEQ, _)).Times(Between(1, 2));
auto const testBundle = GetParam();
runSpawn([&, this](auto yield) {

View File

@@ -229,6 +229,7 @@ TEST_F(RPCLedgerDataHandlerTest, NoMarker)
"close_flags":0,
"close_time":0,
"close_time_resolution":0,
"close_time_iso":"2000-01-01T00:00:00Z",
"ledger_hash":"4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index":"30",
"parent_close_time":0,
@@ -291,6 +292,7 @@ TEST_F(RPCLedgerDataHandlerTest, TypeFilter)
"close_flags":0,
"close_time":0,
"close_time_resolution":0,
"close_time_iso":"2000-01-01T00:00:00Z",
"ledger_hash":"4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index":"30",
"parent_close_time":0,
@@ -356,6 +358,7 @@ TEST_F(RPCLedgerDataHandlerTest, TypeFilterAMM)
"close_flags":0,
"close_time":0,
"close_time_resolution":0,
"close_time_iso":"2000-01-01T00:00:00Z",
"ledger_hash":"4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index":"30",
"parent_close_time":0,
@@ -418,6 +421,7 @@ TEST_F(RPCLedgerDataHandlerTest, OutOfOrder)
"close_flags":0,
"close_time":0,
"close_time_resolution":0,
"close_time_iso":"2000-01-01T00:00:00Z",
"ledger_hash":"4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index":"30",
"parent_close_time":0,

View File

@@ -263,6 +263,7 @@ TEST_F(RPCLedgerHandlerTest, Default)
"close_time":0,
"close_time_resolution":0,
"closed":true,
"close_time_iso":"2000-01-01T00:00:00Z",
"ledger_hash":"4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index":"30",
"parent_close_time":0,
@@ -445,6 +446,60 @@ TEST_F(RPCLedgerHandlerTest, TransactionsExpandBinary)
});
}
TEST_F(RPCLedgerHandlerTest, TransactionsExpandBinaryV2)
{
static auto constexpr expectedOut =
R"({
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index": 30,
"validated": true,
"ledger":{
"ledger_data": "0000001E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"closed": true,
"transactions": [
{
"hash": "70436A9332F7CD928FAEC1A41269A677739D8B11F108CE23AE23CBF0C9113F8C",
"tx_blob": "120000240000001E61400000000000006468400000000000000373047465737481144B4E9C06F24296074F7BC48F92A97916C6DC5EA98314D31252CF902EF8DD8451243869B38667CBD89DF3",
"meta_blob": "201C00000000F8E5110061E762400000000000006E81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9E1E1E5110061E762400000000000001E8114D31252CF902EF8DD8451243869B38667CBD89DF3E1E1F1031000"
},
{
"hash": "70436A9332F7CD928FAEC1A41269A677739D8B11F108CE23AE23CBF0C9113F8C",
"tx_blob": "120000240000001E61400000000000006468400000000000000373047465737481144B4E9C06F24296074F7BC48F92A97916C6DC5EA98314D31252CF902EF8DD8451243869B38667CBD89DF3",
"meta_blob": "201C00000000F8E5110061E762400000000000006E81144B4E9C06F24296074F7BC48F92A97916C6DC5EA9E1E1E5110061E762400000000000001E8114D31252CF902EF8DD8451243869B38667CBD89DF3E1E1F1031000"
}
]
}
})";
auto const rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
ASSERT_NE(rawBackendPtr, nullptr);
mockBackendPtr->updateRange(RANGEMIN);
mockBackendPtr->updateRange(RANGEMAX);
auto const ledgerinfo = CreateLedgerInfo(LEDGERHASH, RANGEMAX);
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence(RANGEMAX, _)).WillOnce(Return(ledgerinfo));
TransactionAndMetadata t1;
t1.transaction = CreatePaymentTransactionObject(ACCOUNT, ACCOUNT2, 100, 3, RANGEMAX).getSerializer().peekData();
t1.metadata = CreatePaymentTransactionMetaObject(ACCOUNT, ACCOUNT2, 110, 30).getSerializer().peekData();
t1.ledgerSequence = RANGEMAX;
EXPECT_CALL(*rawBackendPtr, fetchAllTransactionsInLedger(RANGEMAX, _)).WillOnce(Return(std::vector{t1, t1}));
runSpawn([&, this](auto yield) {
auto const handler = AnyHandler{LedgerHandler{mockBackendPtr}};
auto const req = json::parse(
R"({
"binary": true,
"expand": true,
"transactions": true
})"
);
auto const output = handler.process(req, Context{.yield = yield, .apiVersion = 2u});
ASSERT_TRUE(output);
EXPECT_EQ(*output, json::parse(expectedOut));
});
}
TEST_F(RPCLedgerHandlerTest, TransactionsExpandNotBinary)
{
static auto constexpr expectedOut =
@@ -461,6 +516,7 @@ TEST_F(RPCLedgerHandlerTest, TransactionsExpandNotBinary)
"ledger_hash":"4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index":"30",
"parent_close_time":0,
"close_time_iso":"2000-01-01T00:00:00Z",
"parent_hash":"0000000000000000000000000000000000000000000000000000000000000000",
"total_coins":"0",
"transaction_hash":"0000000000000000000000000000000000000000000000000000000000000000",
@@ -538,6 +594,108 @@ TEST_F(RPCLedgerHandlerTest, TransactionsExpandNotBinary)
});
}
TEST_F(RPCLedgerHandlerTest, TransactionsExpandNotBinaryV2)
{
static auto constexpr expectedOut =
R"({
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index": 30,
"validated": true,
"ledger":{
"account_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"close_flags": 0,
"close_time": 0,
"close_time_resolution": 0,
"closed": true,
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index": "30",
"parent_close_time": 0,
"close_time_iso": "2000-01-01T00:00:00Z",
"parent_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"total_coins": "0",
"transaction_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"transactions":[
{
"validated": true,
"close_time_iso": "2000-01-01T00:00:00Z",
"hash": "70436A9332F7CD928FAEC1A41269A677739D8B11F108CE23AE23CBF0C9113F8C",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index": "30",
"tx_json":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"DeliverMax": "100",
"Destination": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Fee": "3",
"Sequence": 30,
"SigningPubKey": "74657374",
"TransactionType": "Payment"
},
"meta":{
"AffectedNodes":[
{
"ModifiedNode":
{
"FinalFields":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Balance": "110"
},
"LedgerEntryType": "AccountRoot"
}
},
{
"ModifiedNode":
{
"FinalFields":
{
"Account": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Balance": "30"
},
"LedgerEntryType": "AccountRoot"
}
}
],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS",
"delivered_amount": "unavailable"
}
}
]
}
})";
auto const rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
ASSERT_NE(rawBackendPtr, nullptr);
mockBackendPtr->updateRange(RANGEMIN);
mockBackendPtr->updateRange(RANGEMAX);
auto const ledgerinfo = CreateLedgerInfo(LEDGERHASH, RANGEMAX);
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence(RANGEMAX, _)).WillOnce(Return(ledgerinfo));
TransactionAndMetadata t1;
t1.transaction = CreatePaymentTransactionObject(ACCOUNT, ACCOUNT2, 100, 3, RANGEMAX).getSerializer().peekData();
t1.metadata = CreatePaymentTransactionMetaObject(ACCOUNT, ACCOUNT2, 110, 30).getSerializer().peekData();
t1.ledgerSequence = RANGEMAX;
EXPECT_CALL(*rawBackendPtr, fetchAllTransactionsInLedger(RANGEMAX, _)).WillOnce(Return(std::vector{t1}));
runSpawn([&, this](auto yield) {
auto const handler = AnyHandler{LedgerHandler{mockBackendPtr}};
auto const req = json::parse(
R"({
"binary": false,
"expand": true,
"transactions": true
})"
);
auto output = handler.process(req, Context{.yield = yield, .apiVersion = 2u});
ASSERT_TRUE(output);
// remove human readable time, it is sightly different cross the platform
EXPECT_EQ(output->as_object().at("ledger").as_object().erase("close_time_human"), 1);
EXPECT_EQ(*output, json::parse(expectedOut));
});
}
TEST_F(RPCLedgerHandlerTest, TransactionsNotExpand)
{
auto const rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
@@ -689,6 +847,7 @@ TEST_F(RPCLedgerHandlerTest, OwnerFundsEmtpy)
"ledger_hash":"4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index":"30",
"parent_close_time":0,
"close_time_iso":"2000-01-01T00:00:00Z",
"parent_hash":"0000000000000000000000000000000000000000000000000000000000000000",
"total_coins":"0",
"transaction_hash":"0000000000000000000000000000000000000000000000000000000000000000",
@@ -780,6 +939,7 @@ TEST_F(RPCLedgerHandlerTest, OwnerFundsTrueBinaryFalse)
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index": "30",
"parent_close_time": 0,
"close_time_iso": "2000-01-01T00:00:00Z",
"parent_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"total_coins": "0",
"transaction_hash": "0000000000000000000000000000000000000000000000000000000000000000",

View File

@@ -285,8 +285,110 @@ TEST_F(RPCNFTHistoryHandlerTest, IndexSpecificForwardTrue)
});
}
TEST_F(RPCNFTHistoryHandlerTest, IndexSpecificForwardFalse)
TEST_F(RPCNFTHistoryHandlerTest, IndexSpecificForwardFalseV1)
{
auto constexpr OUTPUT = R"({
"nft_id": "00010000A7CAD27B688D14BA1A9FA5366554D6ADCF9CE0875B974D9F00000004",
"ledger_index_min": 11,
"ledger_index_max": 29,
"transactions":
[
{
"meta":
{
"AffectedNodes":
[
{
"ModifiedNode":{
"FinalFields":{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Balance": "22"
},
"LedgerEntryType": "AccountRoot"
}
},
{
"ModifiedNode":{
"FinalFields":{
"Account": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Balance": "23"
},
"LedgerEntryType": "AccountRoot"
}
}
],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS",
"delivered_amount": "unavailable"
},
"tx":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Amount": "1",
"Destination": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Fee": "1",
"Sequence": 32,
"SigningPubKey": "74657374",
"TransactionType": "Payment",
"hash": "51D2AAA6B8E4E16EF22F6424854283D8391B56875858A711B8CE4D5B9A422CC2",
"DeliverMax": "1",
"ledger_index": 11,
"date": 1
},
"validated": true
},
{
"meta":
{
"AffectedNodes":
[
{
"ModifiedNode":{
"FinalFields":{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Balance": "22"
},
"LedgerEntryType": "AccountRoot"
}
},
{
"ModifiedNode":{
"FinalFields":{
"Account": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Balance": "23"
},
"LedgerEntryType": "AccountRoot"
}
}
],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS",
"delivered_amount": "unavailable"
},
"tx":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Amount": "1",
"Destination": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Fee": "1",
"Sequence": 32,
"SigningPubKey": "74657374",
"TransactionType": "Payment",
"hash": "51D2AAA6B8E4E16EF22F6424854283D8391B56875858A711B8CE4D5B9A422CC2",
"DeliverMax": "1",
"ledger_index": 29,
"date": 2
},
"validated": true
}
],
"validated": true,
"marker":
{
"ledger": 12,
"seq": 34
}
})";
mockBackendPtr->updateRange(MINSEQ); // min
mockBackendPtr->updateRange(MAXSEQ); // max
MockBackend* rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
@@ -321,12 +423,164 @@ TEST_F(RPCNFTHistoryHandlerTest, IndexSpecificForwardFalse)
));
auto const output = handler.process(input, Context{yield});
ASSERT_TRUE(output);
EXPECT_EQ(output->at("nft_id").as_string(), NFTID);
EXPECT_EQ(output->at("ledger_index_min").as_uint64(), MINSEQ + 1);
EXPECT_EQ(output->at("ledger_index_max").as_uint64(), MAXSEQ - 1);
EXPECT_EQ(output->at("marker").as_object(), json::parse(R"({"ledger":12,"seq":34})"));
EXPECT_EQ(output->at("transactions").as_array().size(), 2);
EXPECT_FALSE(output->as_object().contains("limit"));
EXPECT_EQ(output.value(), boost::json::parse(OUTPUT));
});
}
TEST_F(RPCNFTHistoryHandlerTest, IndexSpecificForwardFalseV2)
{
auto constexpr OUTPUT = R"({
"nft_id": "00010000A7CAD27B688D14BA1A9FA5366554D6ADCF9CE0875B974D9F00000004",
"ledger_index_min": 11,
"ledger_index_max": 29,
"transactions":
[
{
"meta":
{
"AffectedNodes":
[
{
"ModifiedNode":
{
"FinalFields":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Balance": "22"
},
"LedgerEntryType": "AccountRoot"
}
},
{
"ModifiedNode":
{
"FinalFields":
{
"Account": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Balance": "23"
},
"LedgerEntryType": "AccountRoot"
}
}
],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS",
"delivered_amount": "unavailable"
},
"tx_json":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Destination": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Fee": "1",
"Sequence": 32,
"SigningPubKey": "74657374",
"TransactionType": "Payment",
"DeliverMax": "1",
"ledger_index": 11,
"date": 1
},
"hash": "51D2AAA6B8E4E16EF22F6424854283D8391B56875858A711B8CE4D5B9A422CC2",
"ledger_index": 11,
"close_time_iso": "2000-01-01T00:00:00Z",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"validated": true
},
{
"meta":
{
"AffectedNodes":
[
{
"ModifiedNode":
{
"FinalFields":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Balance": "22"
},
"LedgerEntryType": "AccountRoot"
}
},
{
"ModifiedNode":
{
"FinalFields":
{
"Account": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Balance": "23"
},
"LedgerEntryType": "AccountRoot"
}
}
],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS",
"delivered_amount": "unavailable"
},
"tx_json":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Destination": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"Fee": "1",
"Sequence": 32,
"SigningPubKey": "74657374",
"TransactionType": "Payment",
"DeliverMax": "1",
"ledger_index": 29,
"date": 2
},
"hash": "51D2AAA6B8E4E16EF22F6424854283D8391B56875858A711B8CE4D5B9A422CC2",
"ledger_index": 29,
"close_time_iso": "2000-01-01T00:00:00Z",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"validated": true
}
],
"validated": true,
"marker":
{
"ledger": 12,
"seq": 34
}
})";
mockBackendPtr->updateRange(MINSEQ); // min
mockBackendPtr->updateRange(MAXSEQ); // max
MockBackend* rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
ASSERT_NE(rawBackendPtr, nullptr);
auto const transactions = genTransactions(MINSEQ + 1, MAXSEQ - 1);
auto const transCursor = TransactionsAndCursor{transactions, TransactionsCursor{12, 34}};
EXPECT_CALL(
*rawBackendPtr,
fetchNFTTransactions(
testing::_,
testing::_,
false,
testing::Optional(testing::Eq(TransactionsCursor{MAXSEQ - 1, INT32_MAX})),
testing::_
)
)
.WillOnce(Return(transCursor));
auto const ledgerinfo = CreateLedgerInfo(LEDGERHASH, MAXSEQ);
ON_CALL(*rawBackendPtr, fetchLedgerBySequence).WillByDefault(Return(ledgerinfo));
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).Times(2);
runSpawn([&, this](auto yield) {
auto const handler = AnyHandler{NFTHistoryHandler{mockBackendPtr}};
auto const static input = json::parse(fmt::format(
R"({{
"nft_id":"{}",
"ledger_index_min": {},
"ledger_index_max": {},
"forward": false
}})",
NFTID,
MINSEQ + 1,
MAXSEQ - 1
));
auto const output = handler.process(input, Context{.yield = yield, .apiVersion = 2u});
ASSERT_TRUE(output);
EXPECT_EQ(output.value(), boost::json::parse(OUTPUT));
});
}
@@ -416,7 +670,7 @@ TEST_F(RPCNFTHistoryHandlerTest, IndexNotSpecificForwardFalse)
});
}
TEST_F(RPCNFTHistoryHandlerTest, BinaryTrue)
TEST_F(RPCNFTHistoryHandlerTest, BinaryTrueV1)
{
mockBackendPtr->updateRange(MINSEQ); // min
mockBackendPtr->updateRange(MAXSEQ); // max
@@ -475,6 +729,64 @@ TEST_F(RPCNFTHistoryHandlerTest, BinaryTrue)
});
}
TEST_F(RPCNFTHistoryHandlerTest, BinaryTrueV2)
{
mockBackendPtr->updateRange(MINSEQ); // min
mockBackendPtr->updateRange(MAXSEQ); // max
MockBackend* rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
ASSERT_NE(rawBackendPtr, nullptr);
auto const transactions = genTransactions(MINSEQ + 1, MAXSEQ - 1);
auto const transCursor = TransactionsAndCursor{transactions, TransactionsCursor{12, 34}};
EXPECT_CALL(
*rawBackendPtr,
fetchNFTTransactions(
testing::_,
testing::_,
false,
testing::Optional(testing::Eq(TransactionsCursor{MAXSEQ, INT32_MAX})),
testing::_
)
)
.WillOnce(Return(transCursor));
runSpawn([&, this](auto yield) {
auto const handler = AnyHandler{NFTHistoryHandler{mockBackendPtr}};
auto const static input = json::parse(fmt::format(
R"({{
"nft_id":"{}",
"ledger_index_min": {},
"ledger_index_max": {},
"binary": true
}})",
NFTID,
-1,
-1
));
auto const output = handler.process(input, Context{.yield = yield, .apiVersion = 2u});
ASSERT_TRUE(output);
EXPECT_EQ(output->at("nft_id").as_string(), NFTID);
EXPECT_EQ(output->at("ledger_index_min").as_uint64(), MINSEQ);
EXPECT_EQ(output->at("ledger_index_max").as_uint64(), MAXSEQ);
EXPECT_EQ(output->at("marker").as_object(), json::parse(R"({"ledger":12,"seq":34})"));
EXPECT_EQ(output->at("transactions").as_array().size(), 2);
EXPECT_EQ(
output->at("transactions").as_array()[0].as_object().at("meta_blob").as_string(),
"201C00000000F8E5110061E762400000000000001681144B4E9C06F24296074F7B"
"C48F92A97916C6DC5EA9E1E1E5110061E76240000000000000178114D31252CF90"
"2EF8DD8451243869B38667CBD89DF3E1E1F1031000"
);
EXPECT_EQ(
output->at("transactions").as_array()[0].as_object().at("tx_blob").as_string(),
"120000240000002061400000000000000168400000000000000173047465737481"
"144B4E9C06F24296074F7BC48F92A97916C6DC5EA98314D31252CF902EF8DD8451"
"243869B38667CBD89DF3"
);
EXPECT_EQ(output->at("transactions").as_array()[0].as_object().at("date").as_uint64(), 1);
EXPECT_FALSE(output->as_object().contains("limit"));
});
}
TEST_F(RPCNFTHistoryHandlerTest, LimitAndMarker)
{
mockBackendPtr->updateRange(MINSEQ); // min

View File

@@ -179,48 +179,49 @@ TEST_F(RPCTransactionEntryHandlerTest, LedgerSeqNotMatch)
TEST_F(RPCTransactionEntryHandlerTest, NormalPath)
{
static auto constexpr OUTPUT = R"({
"metadata":{
"metadata":
{
"AffectedNodes":
[
{
"CreatedNode":
{
"LedgerEntryType":"Offer",
"LedgerEntryType": "Offer",
"NewFields":
{
"TakerGets":"200",
"TakerGets": "200",
"TakerPays":
{
"currency":"0158415500000000C1F76FF6ECB0BAC600000000",
"issuer":"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"value":"300"
"currency": "0158415500000000C1F76FF6ECB0BAC600000000",
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"value": "300"
}
}
}
}
],
"TransactionIndex":100,
"TransactionResult":"tesSUCCESS"
"TransactionIndex": 100,
"TransactionResult": "tesSUCCESS"
},
"tx_json":
{
"Account":"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee":"2",
"Sequence":100,
"SigningPubKey":"74657374",
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee": "2",
"Sequence": 100,
"SigningPubKey": "74657374",
"TakerGets":
{
"currency":"0158415500000000C1F76FF6ECB0BAC600000000",
"issuer":"rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"value":"200"
"currency": "0158415500000000C1F76FF6ECB0BAC600000000",
"issuer": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"value": "200"
},
"TakerPays":"300",
"TransactionType":"OfferCreate",
"hash":"2E2FBAAFF767227FE4381C4BE9855986A6B9F96C62F6E443731AB36F7BBB8A08"
"TakerPays": "300",
"TransactionType": "OfferCreate",
"hash": "2E2FBAAFF767227FE4381C4BE9855986A6B9F96C62F6E443731AB36F7BBB8A08"
},
"ledger_index":30,
"ledger_hash":"E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC322",
"validated":true
"ledger_index": 30,
"ledger_hash": "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC322",
"validated": true
})";
auto const rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
ASSERT_NE(rawBackendPtr, nullptr);
@@ -253,3 +254,81 @@ TEST_F(RPCTransactionEntryHandlerTest, NormalPath)
EXPECT_EQ(json::parse(OUTPUT), *output);
});
}
TEST_F(RPCTransactionEntryHandlerTest, NormalPathV2)
{
static auto constexpr OUTPUT = R"({
"meta":
{
"AffectedNodes":
[
{
"CreatedNode":
{
"LedgerEntryType": "Offer",
"NewFields":
{
"TakerGets": "200",
"TakerPays":
{
"currency": "0158415500000000C1F76FF6ECB0BAC600000000",
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"value": "300"
}
}
}
}
],
"TransactionIndex": 100,
"TransactionResult": "tesSUCCESS"
},
"tx_json":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee": "2",
"Sequence": 100,
"SigningPubKey": "74657374",
"TakerGets":
{
"currency": "0158415500000000C1F76FF6ECB0BAC600000000",
"issuer": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"value": "200"
},
"TakerPays": "300",
"TransactionType": "OfferCreate"
},
"ledger_index": 30,
"ledger_hash": "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC322",
"close_time_iso": "2000-01-01T00:00:00Z",
"hash": "2E2FBAAFF767227FE4381C4BE9855986A6B9F96C62F6E443731AB36F7BBB8A08",
"validated": true
})";
auto const rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
ASSERT_NE(rawBackendPtr, nullptr);
TransactionAndMetadata tx;
tx.metadata = CreateMetaDataForCreateOffer(CURRENCY, ACCOUNT, 100, 200, 300).getSerializer().peekData();
tx.transaction =
CreateCreateOfferTransactionObject(ACCOUNT, 2, 100, CURRENCY, ACCOUNT2, 200, 300).getSerializer().peekData();
tx.date = 123456;
tx.ledgerSequence = 30;
EXPECT_CALL(*rawBackendPtr, fetchTransaction(ripple::uint256{TXNID}, _)).WillOnce(Return(tx));
mockBackendPtr->updateRange(10); // min
mockBackendPtr->updateRange(tx.ledgerSequence); // max
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).WillOnce(Return(CreateLedgerInfo(INDEX, tx.ledgerSequence)));
runSpawn([&, this](auto yield) {
auto const handler = AnyHandler{TransactionEntryHandler{mockBackendPtr}};
auto const req = json::parse(fmt::format(
R"({{
"tx_hash": "{}",
"ledger_index": {}
}})",
TXNID,
tx.ledgerSequence
));
auto const output = handler.process(req, Context{.yield = yield, .apiVersion = 2});
ASSERT_TRUE(output);
EXPECT_EQ(json::parse(OUTPUT), *output);
});
}

View File

@@ -33,12 +33,13 @@ using TestTxHandler = BaseTxHandler<MockETLService>;
auto constexpr static TXNID = "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD";
auto constexpr static NFTID = "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DF";
auto constexpr static NFTID2 = "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DA";
constexpr static auto LEDGERHASH = "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652";
auto constexpr static ACCOUNT = "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn";
auto constexpr static ACCOUNT2 = "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun";
auto constexpr static CURRENCY = "0158415500000000C1F76FF6ECB0BAC600000000";
constexpr static auto CTID = "C002807000010002"; // seq 163952 txindex 1 netid 2
constexpr static auto SEQ_FROM_CTID = 163952;
auto constexpr static DEFAULT_OUT = R"({
auto constexpr static DEFAULT_OUT_1 = R"({
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee": "2",
"Sequence": 100,
@@ -72,6 +73,49 @@ auto constexpr static DEFAULT_OUT = R"({
},
"date": 123456,
"ledger_index": 100,
"inLedger": 100,
"validated": true
})";
auto constexpr static DEFAULT_OUT_2 = R"({
"hash": "2E2FBAAFF767227FE4381C4BE9855986A6B9F96C62F6E443731AB36F7BBB8A08",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index": 100,
"meta": {
"AffectedNodes": [
{
"CreatedNode": {
"LedgerEntryType": "Offer",
"NewFields": {
"TakerGets": "200",
"TakerPays": {
"currency": "0158415500000000C1F76FF6ECB0BAC600000000",
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"value": "300"
}
}
}
}
],
"TransactionIndex": 100,
"TransactionResult": "tesSUCCESS"
},
"tx_json": {
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"date": 123456,
"Fee": "2",
"ledger_index": 100,
"Sequence": 100,
"SigningPubKey": "74657374",
"TakerGets": {
"currency": "0158415500000000C1F76FF6ECB0BAC600000000",
"issuer": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"value": "200"
},
"TakerPays": "300",
"TransactionType": "OfferCreate"
},
"close_time_iso": "2000-01-01T00:00:00Z",
"validated": true
})";
@@ -282,9 +326,7 @@ TEST_F(RPCTxTest, DefaultParameter_API_v1)
auto const output = handler.process(req, Context{.yield = yield, .apiVersion = 1u});
ASSERT_TRUE(output);
auto v1Output = json::parse(DEFAULT_OUT);
v1Output.as_object()[JS(inLedger)] = v1Output.as_object()[JS(ledger_index)];
EXPECT_EQ(*output, v1Output);
EXPECT_EQ(*output, json::parse(DEFAULT_OUT_1));
});
}
@@ -333,6 +375,7 @@ TEST_F(RPCTxTest, PaymentTx_API_v2)
tx.ledgerSequence = 100;
EXPECT_CALL(*rawBackendPtr, fetchTransaction(ripple::uint256{TXNID}, _)).WillOnce(Return(tx));
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence(tx.ledgerSequence, _)).WillOnce(Return(std::nullopt));
auto const rawETLPtr = dynamic_cast<MockETLService*>(mockETLServicePtr.get());
ASSERT_NE(rawETLPtr, nullptr);
@@ -349,8 +392,9 @@ TEST_F(RPCTxTest, PaymentTx_API_v2)
));
auto const output = handler.process(req, Context{.yield = yield, .apiVersion = 2u});
ASSERT_TRUE(output);
EXPECT_TRUE(output->as_object().contains("DeliverMax"));
EXPECT_FALSE(output->as_object().contains("Amount"));
EXPECT_TRUE(output->as_object().contains("tx_json"));
EXPECT_TRUE(output->as_object().at("tx_json").as_object().contains("DeliverMax"));
EXPECT_FALSE(output->as_object().at("tx_json").as_object().contains("Amount"));
});
}
@@ -367,6 +411,8 @@ TEST_F(RPCTxTest, DefaultParameter_API_v2)
tx.ledgerSequence = 100;
EXPECT_CALL(*rawBackendPtr, fetchTransaction(ripple::uint256{TXNID}, _)).WillOnce(Return(tx));
auto const ledgerinfo = CreateLedgerInfo(LEDGERHASH, tx.ledgerSequence);
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence(tx.ledgerSequence, _)).WillOnce(Return(ledgerinfo));
auto const rawETLPtr = dynamic_cast<MockETLService*>(mockETLServicePtr.get());
ASSERT_NE(rawETLPtr, nullptr);
@@ -383,7 +429,7 @@ TEST_F(RPCTxTest, DefaultParameter_API_v2)
));
auto const output = handler.process(req, Context{.yield = yield, .apiVersion = 2u});
ASSERT_TRUE(output);
EXPECT_EQ(*output, json::parse(DEFAULT_OUT));
EXPECT_EQ(*output, json::parse(DEFAULT_OUT_2));
});
}