diff --git a/src/test/rpc/AccountObjects_test.cpp b/src/test/rpc/AccountObjects_test.cpp index 31b20b37d4c..33d4fe3bda1 100644 --- a/src/test/rpc/AccountObjects_test.cpp +++ b/src/test/rpc/AccountObjects_test.cpp @@ -1350,6 +1350,86 @@ class AccountObjects_test : public beast::unit_test::Suite } } + void + testAccountObjectDoesntShowCancelledOffers() + { + testcase("AccountObjectDoesntShowCancelledOffers"); + + using namespace jtx; + Env env(*this); + + Account const alice{"alice"}; + Account const bob{"bob"}; + auto const eur = bob["EUR"]; + env.fund(XRP(10000), alice, bob); + env.close(); + + auto const rpcAccountObjects = [&](std::optional limit = std::nullopt) { + json::Value params; + params[jss::account] = alice.human(); + if (limit.has_value()) + { + params[jss::limit] = *limit; + } + return env.rpc("json", "account_objects", to_string(params)); + }; + + auto const numEntries = 33; + std::vector seqs; + seqs.reserve(numEntries); + for ([[maybe_unused]] auto _ : std::ranges::iota_view{0, numEntries}) + { + json::Value params; + params[jss::secret] = toBase58(generateSeed("alice")); + params[jss::tx_json] = offer(alice, eur(1), XRP(2)); + auto const res = env.rpc("json", "submit", to_string(params))[jss::result]; + BEAST_EXPECT(res[jss::status].asString() == "success"); + seqs.push_back(env.seq(alice)); + } + + auto res = rpcAccountObjects(); + BEAST_EXPECT(res[jss::result][jss::account_objects].size() == numEntries); + BEAST_EXPECT(not res[jss::result].isMember(jss::limit)); + BEAST_EXPECT(not res[jss::result].isMember(jss::marker)); + + for (auto const s : std::views::all(seqs) | std::views::take(numEntries - 1)) + { + json::Value params; + params[jss::secret] = toBase58(generateSeed("alice")); + params[jss::tx_json] = offerCancel(alice, s - 1); + auto const res = env.rpc("json", "submit", to_string(params))[jss::result]; + BEAST_EXPECT(res[jss::status].asString() == "success"); + } + + res = rpcAccountObjects(); + BEAST_EXPECT(res[jss::result][jss::account_objects].size() == 1); + BEAST_EXPECT(not res[jss::result].isMember(jss::limit)); + BEAST_EXPECT(not res[jss::result].isMember(jss::marker)); + + { + json::Value params; + params[jss::secret] = toBase58(generateSeed("alice")); + json::Value txJson; + txJson[jss::TransactionType] = jss::NFTokenMint; + txJson[jss::Account] = to_string(alice.id()); + txJson["NFTokenTaxon"] = 1; + params[jss::tx_json] = txJson; + auto const res = env.rpc("json", "submit", to_string(params))[jss::result]; + BEAST_EXPECT(res[jss::status].asString() == "success"); + } + env.close(); + + res = rpcAccountObjects(); + BEAST_EXPECT(res[jss::result][jss::account_objects].size() == 2); + BEAST_EXPECT(not res[jss::result].isMember(jss::limit)); + BEAST_EXPECT(not res[jss::result].isMember(jss::marker)); + + res = rpcAccountObjects(1); + BEAST_EXPECT(res[jss::result][jss::account_objects].size() == 1); + BEAST_EXPECT(res[jss::result][jss::limit].asUInt() == 1); + BEAST_EXPECT(res[jss::result].isMember(jss::marker)); + } + void run() override { @@ -1360,6 +1440,7 @@ class AccountObjects_test : public beast::unit_test::Suite testNFTsMarker(); testAccountNFTs(); testAccountObjectMarker(); + testAccountObjectDoesntShowCancelledOffers(); } };