rippled
Loading...
Searching...
No Matches
OwnerInfo_test.cpp
1#include <test/jtx.h>
2
3#include <xrpl/beast/unit_test.h>
4#include <xrpl/protocol/AccountID.h>
5#include <xrpl/protocol/STAmount.h>
6#include <xrpl/protocol/jss.h>
7
8namespace xrpl {
9
11{
12 void
14 {
15 testcase("Bad input to owner_info");
16
17 using namespace test::jtx;
18 Env env{*this};
19
20 auto const alice = Account{"alice"};
21 env.fund(XRP(10000), alice);
22 env.close();
23
24 { // missing account field
25 auto const result = env.rpc("json", "owner_info", "{}")[jss::result];
26 BEAST_EXPECT(result[jss::error] == "invalidParams");
27 BEAST_EXPECT(result[jss::error_message] == "Missing field 'account'.");
28 }
29
30 { // ask for empty account
31 Json::Value params;
32 params[jss::account] = "";
33 auto const result = env.rpc("json", "owner_info", to_string(params))[jss::result];
34 if (BEAST_EXPECT(result.isMember(jss::accepted) && result.isMember(jss::current)))
35 {
36 BEAST_EXPECT(result[jss::accepted][jss::error] == "actMalformed");
37 BEAST_EXPECT(result[jss::accepted][jss::error_message] == "Account malformed.");
38 BEAST_EXPECT(result[jss::current][jss::error] == "actMalformed");
39 BEAST_EXPECT(result[jss::current][jss::error_message] == "Account malformed.");
40 }
41 }
42
43 { // ask for nonexistent account
44 // this seems like it should be an error, but current impl
45 // (deprecated) does not return an error, just empty fields.
46 Json::Value params;
47 params[jss::account] = Account{"bob"}.human();
48 auto const result = env.rpc("json", "owner_info", to_string(params))[jss::result];
49 BEAST_EXPECT(result[jss::accepted] == Json::objectValue);
50 BEAST_EXPECT(result[jss::current] == Json::objectValue);
51 BEAST_EXPECT(result[jss::status] == "success");
52 }
53 }
54
55 void
57 {
58 testcase("Basic request for owner_info");
59
60 using namespace test::jtx;
61 Env env{*this};
62
63 auto const alice = Account{"alice"};
64 auto const gw = Account{"gateway"};
65 env.fund(XRP(10000), alice, gw);
66 env.close();
67 auto const USD = gw["USD"];
68 auto const CNY = gw["CNY"];
69 env(trust(alice, USD(1000)));
70 env(trust(alice, CNY(1000)));
71 env(offer(alice, USD(1), XRP(1000)));
72 env.close();
73
74 env(pay(gw, alice, USD(50)));
75 env(pay(gw, alice, CNY(50)));
76 env(offer(alice, CNY(2), XRP(1000)));
77
78 Json::Value params;
79 params[jss::account] = alice.human();
80 auto const result = env.rpc("json", "owner_info", to_string(params))[jss::result];
81 if (!BEAST_EXPECT(result.isMember(jss::accepted) && result.isMember(jss::current)))
82 {
83 return;
84 }
85
86 // accepted ledger entry
87 if (!BEAST_EXPECT(result[jss::accepted].isMember(jss::ripple_lines)))
88 return;
89 auto lines = result[jss::accepted][jss::ripple_lines];
90 if (!BEAST_EXPECT(lines.isArray() && lines.size() == 2))
91 return;
92
93 BEAST_EXPECT(
94 lines[0u][sfBalance.fieldName] ==
95 (STAmount{Issue{to_currency("CNY"), noAccount()}, 0}.value().getJson(JsonOptions::none)));
96 BEAST_EXPECT(lines[0u][sfHighLimit.fieldName] == alice["CNY"](1000).value().getJson(JsonOptions::none));
97 BEAST_EXPECT(lines[0u][sfLowLimit.fieldName] == gw["CNY"](0).value().getJson(JsonOptions::none));
98
99 BEAST_EXPECT(
100 lines[1u][sfBalance.fieldName] ==
101 (STAmount{Issue{to_currency("USD"), noAccount()}, 0}.value().getJson(JsonOptions::none)));
102 BEAST_EXPECT(lines[1u][sfHighLimit.fieldName] == alice["USD"](1000).value().getJson(JsonOptions::none));
103 BEAST_EXPECT(lines[1u][sfLowLimit.fieldName] == USD(0).value().getJson(JsonOptions::none));
104
105 if (!BEAST_EXPECT(result[jss::accepted].isMember(jss::offers)))
106 return;
107 auto offers = result[jss::accepted][jss::offers];
108 if (!BEAST_EXPECT(offers.isArray() && offers.size() == 1))
109 return;
110
111 BEAST_EXPECT(offers[0u][jss::Account] == alice.human());
112 BEAST_EXPECT(offers[0u][sfTakerGets.fieldName] == XRP(1000).value().getJson(JsonOptions::none));
113 BEAST_EXPECT(offers[0u][sfTakerPays.fieldName] == USD(1).value().getJson(JsonOptions::none));
114
115 // current ledger entry
116 if (!BEAST_EXPECT(result[jss::current].isMember(jss::ripple_lines)))
117 return;
118 lines = result[jss::current][jss::ripple_lines];
119 if (!BEAST_EXPECT(lines.isArray() && lines.size() == 2))
120 return;
121
122 BEAST_EXPECT(
123 lines[0u][sfBalance.fieldName] ==
124 (STAmount{Issue{to_currency("CNY"), noAccount()}, -50}.value().getJson(JsonOptions::none)));
125 BEAST_EXPECT(lines[0u][sfHighLimit.fieldName] == alice["CNY"](1000).value().getJson(JsonOptions::none));
126 BEAST_EXPECT(lines[0u][sfLowLimit.fieldName] == gw["CNY"](0).value().getJson(JsonOptions::none));
127
128 BEAST_EXPECT(
129 lines[1u][sfBalance.fieldName] ==
130 (STAmount{Issue{to_currency("USD"), noAccount()}, -50}.value().getJson(JsonOptions::none)));
131 BEAST_EXPECT(lines[1u][sfHighLimit.fieldName] == alice["USD"](1000).value().getJson(JsonOptions::none));
132 BEAST_EXPECT(lines[1u][sfLowLimit.fieldName] == gw["USD"](0).value().getJson(JsonOptions::none));
133
134 if (!BEAST_EXPECT(result[jss::current].isMember(jss::offers)))
135 return;
136 offers = result[jss::current][jss::offers];
137 // 1 additional offer in current, (2 total)
138 if (!BEAST_EXPECT(offers.isArray() && offers.size() == 2))
139 return;
140
141 BEAST_EXPECT(offers[1u] == result[jss::accepted][jss::offers][0u]);
142 BEAST_EXPECT(offers[0u][jss::Account] == alice.human());
143 BEAST_EXPECT(offers[0u][sfTakerGets.fieldName] == XRP(1000).value().getJson(JsonOptions::none));
144 BEAST_EXPECT(offers[0u][sfTakerPays.fieldName] == CNY(2).value().getJson(JsonOptions::none));
145 }
146
147public:
148 void
149 run() override
150 {
151 testBadInput();
152 testBasic();
153 }
154};
155
156BEAST_DEFINE_TESTSUITE(OwnerInfo, rpc, xrpl);
157
158} // namespace xrpl
Represents a JSON value.
Definition json_value.h:131
A testsuite class.
Definition suite.h:52
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:148
void run() override
Runs the suite.
STAmount const & value() const noexcept
Definition STAmount.h:561
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:27
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:90
owner_count< ltOFFER > offers
Match the number of offers in the account's owner directory.
Definition owners.h:67
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:598