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 ripple {
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 =
26 env.rpc("json", "owner_info", "{}")[jss::result];
27 BEAST_EXPECT(result[jss::error] == "invalidParams");
28 BEAST_EXPECT(
29 result[jss::error_message] == "Missing field 'account'.");
30 }
31
32 { // ask for empty account
33 Json::Value params;
34 params[jss::account] = "";
35 auto const result =
36 env.rpc("json", "owner_info", to_string(params))[jss::result];
37 if (BEAST_EXPECT(
38 result.isMember(jss::accepted) &&
39 result.isMember(jss::current)))
40 {
41 BEAST_EXPECT(
42 result[jss::accepted][jss::error] == "actMalformed");
43 BEAST_EXPECT(
44 result[jss::accepted][jss::error_message] ==
45 "Account malformed.");
46 BEAST_EXPECT(
47 result[jss::current][jss::error] == "actMalformed");
48 BEAST_EXPECT(
49 result[jss::current][jss::error_message] ==
50 "Account malformed.");
51 }
52 }
53
54 { // ask for nonexistent account
55 // this seems like it should be an error, but current impl
56 // (deprecated) does not return an error, just empty fields.
57 Json::Value params;
58 params[jss::account] = Account{"bob"}.human();
59 auto const result =
60 env.rpc("json", "owner_info", to_string(params))[jss::result];
61 BEAST_EXPECT(result[jss::accepted] == Json::objectValue);
62 BEAST_EXPECT(result[jss::current] == Json::objectValue);
63 BEAST_EXPECT(result[jss::status] == "success");
64 }
65 }
66
67 void
69 {
70 testcase("Basic request for owner_info");
71
72 using namespace test::jtx;
73 Env env{*this};
74
75 auto const alice = Account{"alice"};
76 auto const gw = Account{"gateway"};
77 env.fund(XRP(10000), alice, gw);
78 env.close();
79 auto const USD = gw["USD"];
80 auto const CNY = gw["CNY"];
81 env(trust(alice, USD(1000)));
82 env(trust(alice, CNY(1000)));
83 env(offer(alice, USD(1), XRP(1000)));
84 env.close();
85
86 env(pay(gw, alice, USD(50)));
87 env(pay(gw, alice, CNY(50)));
88 env(offer(alice, CNY(2), XRP(1000)));
89
90 Json::Value params;
91 params[jss::account] = alice.human();
92 auto const result =
93 env.rpc("json", "owner_info", to_string(params))[jss::result];
94 if (!BEAST_EXPECT(
95 result.isMember(jss::accepted) &&
96 result.isMember(jss::current)))
97 {
98 return;
99 }
100
101 // accepted ledger entry
102 if (!BEAST_EXPECT(result[jss::accepted].isMember(jss::ripple_lines)))
103 return;
104 auto lines = result[jss::accepted][jss::ripple_lines];
105 if (!BEAST_EXPECT(lines.isArray() && lines.size() == 2))
106 return;
107
108 BEAST_EXPECT(
109 lines[0u][sfBalance.fieldName] ==
110 (STAmount{Issue{to_currency("CNY"), noAccount()}, 0}
111 .value()
113 BEAST_EXPECT(
114 lines[0u][sfHighLimit.fieldName] ==
115 alice["CNY"](1000).value().getJson(JsonOptions::none));
116 BEAST_EXPECT(
117 lines[0u][sfLowLimit.fieldName] ==
118 gw["CNY"](0).value().getJson(JsonOptions::none));
119
120 BEAST_EXPECT(
121 lines[1u][sfBalance.fieldName] ==
122 (STAmount{Issue{to_currency("USD"), noAccount()}, 0}
123 .value()
125 BEAST_EXPECT(
126 lines[1u][sfHighLimit.fieldName] ==
127 alice["USD"](1000).value().getJson(JsonOptions::none));
128 BEAST_EXPECT(
129 lines[1u][sfLowLimit.fieldName] ==
130 USD(0).value().getJson(JsonOptions::none));
131
132 if (!BEAST_EXPECT(result[jss::accepted].isMember(jss::offers)))
133 return;
134 auto offers = result[jss::accepted][jss::offers];
135 if (!BEAST_EXPECT(offers.isArray() && offers.size() == 1))
136 return;
137
138 BEAST_EXPECT(offers[0u][jss::Account] == alice.human());
139 BEAST_EXPECT(
140 offers[0u][sfTakerGets.fieldName] ==
141 XRP(1000).value().getJson(JsonOptions::none));
142 BEAST_EXPECT(
143 offers[0u][sfTakerPays.fieldName] ==
144 USD(1).value().getJson(JsonOptions::none));
145
146 // current ledger entry
147 if (!BEAST_EXPECT(result[jss::current].isMember(jss::ripple_lines)))
148 return;
149 lines = result[jss::current][jss::ripple_lines];
150 if (!BEAST_EXPECT(lines.isArray() && lines.size() == 2))
151 return;
152
153 BEAST_EXPECT(
154 lines[0u][sfBalance.fieldName] ==
155 (STAmount{Issue{to_currency("CNY"), noAccount()}, -50}
156 .value()
157 .getJson(JsonOptions::none)));
158 BEAST_EXPECT(
159 lines[0u][sfHighLimit.fieldName] ==
160 alice["CNY"](1000).value().getJson(JsonOptions::none));
161 BEAST_EXPECT(
162 lines[0u][sfLowLimit.fieldName] ==
163 gw["CNY"](0).value().getJson(JsonOptions::none));
164
165 BEAST_EXPECT(
166 lines[1u][sfBalance.fieldName] ==
167 (STAmount{Issue{to_currency("USD"), noAccount()}, -50}
168 .value()
169 .getJson(JsonOptions::none)));
170 BEAST_EXPECT(
171 lines[1u][sfHighLimit.fieldName] ==
172 alice["USD"](1000).value().getJson(JsonOptions::none));
173 BEAST_EXPECT(
174 lines[1u][sfLowLimit.fieldName] ==
175 gw["USD"](0).value().getJson(JsonOptions::none));
176
177 if (!BEAST_EXPECT(result[jss::current].isMember(jss::offers)))
178 return;
179 offers = result[jss::current][jss::offers];
180 // 1 additional offer in current, (2 total)
181 if (!BEAST_EXPECT(offers.isArray() && offers.size() == 2))
182 return;
183
184 BEAST_EXPECT(offers[1u] == result[jss::accepted][jss::offers][0u]);
185 BEAST_EXPECT(offers[0u][jss::Account] == alice.human());
186 BEAST_EXPECT(
187 offers[0u][sfTakerGets.fieldName] ==
188 XRP(1000).value().getJson(JsonOptions::none));
189 BEAST_EXPECT(
190 offers[0u][sfTakerPays.fieldName] ==
191 CNY(2).value().getJson(JsonOptions::none));
192 }
193
194public:
195 void
196 run() override
197 {
198 testBadInput();
199 testBasic();
200 }
201};
202
203BEAST_DEFINE_TESTSUITE(OwnerInfo, rpc, ripple);
204
205} // namespace ripple
Represents a JSON value.
Definition json_value.h:130
A testsuite class.
Definition suite.h:52
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:152
void run() override
Runs the suite.
STAmount const & value() const noexcept
Definition STAmount.h:575
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:26
owner_count< ltOFFER > offers
Match the number of offers in the account's owner directory.
Definition owners.h:73
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:92
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.