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