20 #include <ripple/protocol/ErrorCodes.h>
21 #include <ripple/protocol/jss.h>
22 #include <ripple/protocol/TxFlags.h>
24 #include <ripple/beast/unit_test.h>
35 testcase (
"acccount_lines");
37 using namespace test::jtx;
41 auto const lines = env.rpc (
"json",
"account_lines",
"{ }");
42 BEAST_EXPECT(lines[jss::result][jss::error_message] ==
47 auto const lines = env.rpc (
"json",
"account_lines",
49 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"})");
50 BEAST_EXPECT(lines[jss::result][jss::error_message] ==
53 Account const alice {
"alice"};
56 auto const lines = env.rpc (
"json",
"account_lines",
57 R
"({"account": ")" + alice.human() + R"("})");
58 BEAST_EXPECT(lines[jss::result][jss::error_message] ==
61 env.fund(XRP(10000), alice);
63 LedgerInfo const ledger3Info = env.closed()->info();
64 BEAST_EXPECT(ledger3Info.
seq == 3);
68 auto const lines = env.rpc (
"json",
"account_lines",
69 R
"({"account": ")" + alice.human() + R"("})");
70 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
71 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 0);
75 auto const lines = env.rpc (
"json",
"account_lines",
76 R
"({"account": ")" + alice.human() + R"(", )"
77 R"("ledger_index": "nonsense"})");
78 BEAST_EXPECT(lines[jss::result][jss::error_message] ==
79 "ledgerIndexMalformed");
83 auto const lines = env.rpc (
"json",
"account_lines",
84 R
"({"account": ")" + alice.human() + R"(", )"
85 R"("ledger_index": 50000})");
86 BEAST_EXPECT(lines[jss::result][jss::error_message] ==
90 Account
const gw1 {
"gw1"};
91 env.fund(XRP(10000), gw1);
94 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
98 gw1[
std::string(
"YA") +
static_cast<char>(
'A' + c)]);
99 IOU
const& gw1Currency = gw1Currencies.
back();
102 env(trust(alice, gw1Currency(100 + c)));
103 env(pay(gw1, alice, gw1Currency(50 + c)));
106 LedgerInfo const ledger4Info = env.closed()->info();
107 BEAST_EXPECT(ledger4Info.
seq == 4);
111 Account
const gw2 {
"gw2"};
112 env.fund(XRP(10000), gw2);
119 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
123 gw2[
std::string(
"ZA") +
static_cast<char>(
'A' + c)]);
124 IOU
const& gw2Currency = gw2Currencies.
back();
127 env(trust(alice, gw2Currency(200 + c)));
128 env(trust(gw2, gw2Currency(0), alice,
tfSetfAuth));
130 env(pay(gw2, alice, gw2Currency(100 + c)));
137 LedgerInfo const ledger58Info = env.closed()->info();
138 BEAST_EXPECT(ledger58Info.
seq == 58);
141 auto testAccountLinesHistory =
142 [
this, &env](Account
const& account,
LedgerInfo const& info,
int count)
145 auto const linesSeq = env.rpc (
"json",
"account_lines",
146 R
"({"account": ")" + account.human() + R"(", )"
148 BEAST_EXPECT(linesSeq[jss::result][jss::lines].isArray());
149 BEAST_EXPECT(linesSeq[jss::result][jss::lines].size() == count);
152 auto const linesHash = env.rpc (
"json",
"account_lines",
153 R
"({"account": ")" + account.human() + R"(", )"
154 R"("ledger_hash": ")" + to_string(info.hash) + R"("})");
155 BEAST_EXPECT(linesHash[jss::result][jss::lines].isArray());
156 BEAST_EXPECT(linesHash[jss::result][jss::lines].size() == count);
160 testAccountLinesHistory (alice, ledger3Info, 0);
163 testAccountLinesHistory (alice, ledger4Info, 26);
166 testAccountLinesHistory (alice, ledger58Info, 52);
171 auto const lines = env.rpc (
"json",
"account_lines",
172 R
"({"account": ")" + alice.human() + R"(", )"
173 R"("ledger_hash": ")" + to_string(ledger4Info.hash) + R"(", )"
175 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
176 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 26);
180 auto const lines = env.rpc (
"json",
"account_lines",
181 R
"({"account": ")" + alice.human() + R"("})");
182 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
183 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 52);
187 auto const lines = env.rpc (
"json",
"account_lines",
188 R
"({"account": ")" + alice.human() + R"(", )"
189 R"("peer": ")" + gw1.human() + R"("})");
190 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
191 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 26);
195 auto const lines = env.rpc (
"json",
"account_lines",
196 R
"({"account": ")" + alice.human() + R"(", )"
198 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"})");
199 BEAST_EXPECT(lines[jss::result][jss::error_message] ==
204 auto const lines = env.rpc (
"json",
"account_lines",
205 R
"({"account": ")" + alice.human() + R"(", )"
207 BEAST_EXPECT(lines[jss::result][jss::error_message] ==
212 auto const linesA = env.rpc (
"json",
"account_lines",
213 R
"({"account": ")" + alice.human() + R"(", )"
215 BEAST_EXPECT(linesA[jss::result][jss::lines].isArray());
216 BEAST_EXPECT(linesA[jss::result][jss::lines].size() == 1);
219 auto marker = linesA[jss::result][jss::marker].asString();
220 auto const linesB = env.rpc (
"json",
"account_lines",
221 R
"({"account": ")" + alice.human() + R"(", )"
222 R"("marker": ")" + marker + R"("})");
223 BEAST_EXPECT(linesB[jss::result][jss::lines].isArray());
224 BEAST_EXPECT(linesB[jss::result][jss::lines].size() == 51);
227 auto const linesC = env.rpc (
"json",
"account_lines",
228 R
"({"account": ")" + alice.human() + R"(", )"
230 R"("marker": ")" + marker + R"("})");
231 BEAST_EXPECT(linesC[jss::result][jss::lines].isArray());
232 BEAST_EXPECT(linesC[jss::result][jss::lines].size() == 3);
235 marker[5] = marker[5] ==
'7' ?
'8' :
'7';
236 auto const linesD = env.rpc (
"json",
"account_lines",
237 R
"({"account": ")" + alice.human() + R"(", )"
238 R"("marker": ")" + marker + R"("})");
239 BEAST_EXPECT(linesD[jss::result][jss::error_message] ==
244 auto const lines = env.rpc (
"json",
"account_lines",
245 R
"({"account": ")" + alice.human() + R"(", )"
246 R"("marker": true})");
247 BEAST_EXPECT(lines[jss::result][jss::error_message] ==
252 auto const lines = env.rpc (
"json",
"account_lines",
253 R
"({"account": ")" + alice.human() + R"(", )"
255 R"("peer": ")" + gw2.human() + R"("})");
256 auto const& line = lines[jss::result][jss::lines][0u];
257 BEAST_EXPECT(line[jss::freeze].asBool() ==
true);
258 BEAST_EXPECT(line[jss::no_ripple].asBool() ==
true);
259 BEAST_EXPECT(line[jss::peer_authorized].asBool() ==
true);
263 auto const linesA = env.rpc (
"json",
"account_lines",
264 R
"({"account": ")" + gw2.human() + R"(", )"
266 R"("peer": ")" + alice.human() + R"("})");
267 auto const& lineA = linesA[jss::result][jss::lines][0u];
268 BEAST_EXPECT(lineA[jss::freeze_peer].asBool() ==
true);
269 BEAST_EXPECT(lineA[jss::no_ripple_peer].asBool() ==
true);
270 BEAST_EXPECT(lineA[jss::authorized].asBool() ==
true);
273 BEAST_EXPECT(linesA[jss::result].isMember(jss::marker));
274 auto const marker = linesA[jss::result][jss::marker].asString();
275 auto const linesB = env.rpc (
"json",
"account_lines",
276 R
"({"account": ")" + gw2.human() + R"(", )"
278 R"("marker": ")" + marker + R"(", )"
279 R"("peer": ")" + alice.human() + R"("})");
280 BEAST_EXPECT(linesB[jss::result][jss::lines].isArray());
281 BEAST_EXPECT(linesB[jss::result][jss::lines].size() == 25);
282 BEAST_EXPECT(! linesB[jss::result].isMember(jss::marker));
286 void testAccountLineDelete()
288 testcase (
"Entry pointed to by marker is removed");
289 using namespace test::jtx;
303 Account
const alice {
"alice"};
304 Account
const becky {
"becky"};
305 Account
const cheri {
"cheri"};
306 Account
const gw1 {
"gw1"};
307 Account
const gw2 {
"gw2"};
308 env.fund(
XRP(10000), alice, becky, cheri, gw1, gw2);
311 auto const USD = gw1[
"USD"];
312 auto const EUR = gw2[
"EUR"];
313 env(
trust(alice, USD(200)));
314 env(
trust(becky, EUR(200)));
315 env(
trust(cheri, EUR(200)));
319 env(
pay(gw2, becky, EUR(100)));
323 env(
offer(alice, EUR(100),
XRP(100)));
327 env(
offer(becky,
XRP(100), EUR(100)));
331 auto const linesBeg = env.rpc (
"json",
"account_lines",
332 R
"({"account": ")" + alice.human() + R"(", )"
334 BEAST_EXPECT(linesBeg[jss::result][jss::lines][0u][jss::currency] == "USD");
335 BEAST_EXPECT(linesBeg[jss::result].isMember(jss::marker));
338 env(
pay(alice, cheri, EUR(100)));
343 auto const linesEnd = env.rpc (
"json",
"account_lines",
344 R
"({"account": ")" + alice.human() + R"(", )"
346 linesBeg[jss::result][jss::marker].asString() + R"("})");
347 BEAST_EXPECT(linesEnd[jss::result][jss::error_message] ==
352 void testAccountLines2()
354 testcase (
"V2: acccount_lines");
356 using namespace test::jtx;
360 auto const lines = env.rpc (
"json2",
"{ "
361 R
"("method" : "account_lines",)"
362 R"("jsonrpc" : "2.0",)"
363 R"("ripplerpc" : "2.0")"
365 BEAST_EXPECT(
lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
366 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
370 auto const lines = env.rpc (
"json2",
"{ "
371 R
"("method" : "account_lines",)"
372 R"("jsonrpc" : "2.0",)"
373 R"("ripplerpc" : "2.0",)"
376 BEAST_EXPECT(lines[jss::error][jss::message] ==
378 BEAST_EXPECT(
lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
379 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
380 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
384 auto const lines = env.rpc (
"json2",
"{ "
385 R
"("method" : "account_lines",)"
386 R"("jsonrpc" : "2.0",)"
387 R"("ripplerpc" : "2.0",)"
391 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"}})");
392 BEAST_EXPECT(lines[jss::error][jss::message] ==
394 BEAST_EXPECT(lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
395 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
396 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
398 Account
const alice {
"alice"};
401 auto const lines = env.rpc (
"json2",
"{ "
402 R
"("method" : "account_lines",)"
403 R"("jsonrpc" : "2.0",)"
404 R"("ripplerpc" : "2.0",)"
407 R"({"account": ")" + alice.human() + R"("}})");
408 BEAST_EXPECT(lines[jss::error][jss::message] ==
410 BEAST_EXPECT(lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
411 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
412 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
414 env.fund(
XRP(10000), alice);
416 LedgerInfo
const ledger3Info = env.closed()->info();
417 BEAST_EXPECT(ledger3Info.seq == 3);
421 auto const lines = env.rpc (
"json2",
"{ "
422 R
"("method" : "account_lines",)"
423 R"("jsonrpc" : "2.0",)"
424 R"("ripplerpc" : "2.0",)"
427 R"({"account": ")" + alice.human() + R"("}})");
428 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
429 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 0);
430 BEAST_EXPECT(lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
431 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
432 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
436 auto const lines = env.rpc (
"json2",
"{ "
437 R
"("method" : "account_lines",)"
438 R"("jsonrpc" : "2.0",)"
439 R"("ripplerpc" : "2.0",)"
442 R"({"account": ")" + alice.human() + R"(", )"
443 R"("ledger_index": "nonsense"}})");
444 BEAST_EXPECT(lines[jss::error][jss::message] ==
445 "ledgerIndexMalformed");
446 BEAST_EXPECT(
lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
447 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
448 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
452 auto const lines = env.rpc (
"json2",
"{ "
453 R
"("method" : "account_lines",)"
454 R"("jsonrpc" : "2.0",)"
455 R"("ripplerpc" : "2.0",)"
458 R"({"account": ")" + alice.human() + R"(", )"
459 R"("ledger_index": 50000}})");
460 BEAST_EXPECT(lines[jss::error][jss::message] ==
462 BEAST_EXPECT(
lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
463 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
464 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
467 Account
const gw1 {
"gw1"};
468 env.fund(
XRP(10000), gw1);
471 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
475 gw1[
std::string(
"YA") +
static_cast<char>(
'A' + c)]);
476 IOU
const& gw1Currency = gw1Currencies.
back();
479 env(
trust(alice, gw1Currency(100 + c)));
480 env(
pay(gw1, alice, gw1Currency(50 + c)));
483 LedgerInfo
const ledger4Info = env.closed()->info();
484 BEAST_EXPECT(ledger4Info.seq == 4);
488 Account
const gw2 {
"gw2"};
489 env.fund(
XRP(10000), gw2);
496 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
500 gw2[
std::string(
"ZA") +
static_cast<char>(
'A' + c)]);
501 IOU
const& gw2Currency = gw2Currencies.
back();
504 env(
trust(alice, gw2Currency(200 + c)));
507 env(
pay(gw2, alice, gw2Currency(100 + c)));
514 LedgerInfo
const ledger58Info = env.closed()->info();
515 BEAST_EXPECT(ledger58Info.seq == 58);
518 auto testAccountLinesHistory =
519 [
this, &env](Account
const& account, LedgerInfo
const& info,
int count)
522 auto const linesSeq = env.rpc (
"json2",
"{ "
523 R
"("method" : "account_lines",)"
524 R"("jsonrpc" : "2.0",)"
525 R"("ripplerpc" : "2.0",)"
528 R"({"account": ")" + account.human() + R"(", )"
530 BEAST_EXPECT(linesSeq[jss::result][jss::lines].isArray());
531 BEAST_EXPECT(linesSeq[jss::result][jss::lines].
size() == count);
532 BEAST_EXPECT(linesSeq.isMember(jss::jsonrpc) && linesSeq[jss::jsonrpc] ==
"2.0");
533 BEAST_EXPECT(linesSeq.isMember(jss::ripplerpc) && linesSeq[jss::ripplerpc] ==
"2.0");
534 BEAST_EXPECT(linesSeq.isMember(jss::id) && linesSeq[jss::id] == 5);
537 auto const linesHash = env.rpc (
"json2",
"{ "
538 R
"("method" : "account_lines",)"
539 R"("jsonrpc" : "2.0",)"
540 R"("ripplerpc" : "2.0",)"
543 R"({"account": ")" + account.human() + R"(", )"
544 R"("ledger_hash": ")" + to_string(info.hash) + R"("}})");
545 BEAST_EXPECT(linesHash[jss::result][jss::lines].isArray());
546 BEAST_EXPECT(linesHash[jss::result][jss::lines].size() == count);
547 BEAST_EXPECT(linesHash.isMember(jss::jsonrpc) && linesHash[jss::jsonrpc] == "2.0");
548 BEAST_EXPECT(linesHash.isMember(jss::ripplerpc) && linesHash[jss::ripplerpc] ==
"2.0");
549 BEAST_EXPECT(linesHash.isMember(jss::id) && linesHash[jss::id] == 5);
553 testAccountLinesHistory (alice, ledger3Info, 0);
556 testAccountLinesHistory (alice, ledger4Info, 26);
559 testAccountLinesHistory (alice, ledger58Info, 52);
564 auto const lines = env.rpc (
"json2",
"{ "
565 R
"("method" : "account_lines",)"
566 R"("jsonrpc" : "2.0",)"
567 R"("ripplerpc" : "2.0",)"
570 R"({"account": ")" + alice.human() + R"(", )"
571 R"("ledger_hash": ")" + to_string(ledger4Info.hash) + R"(", )"
573 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
574 BEAST_EXPECT(lines[jss::result][jss::lines].
size() == 26);
575 BEAST_EXPECT(
lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
576 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
577 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
581 auto const lines = env.rpc (
"json2",
"{ "
582 R
"("method" : "account_lines",)"
583 R"("jsonrpc" : "2.0",)"
584 R"("ripplerpc" : "2.0",)"
587 R"({"account": ")" + alice.human() + R"("}})");
588 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
589 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 52);
590 BEAST_EXPECT(lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
591 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
592 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
596 auto const lines = env.rpc (
"json2",
"{ "
597 R
"("method" : "account_lines",)"
598 R"("jsonrpc" : "2.0",)"
599 R"("ripplerpc" : "2.0",)"
602 R"({"account": ")" + alice.human() + R"(", )"
603 R"("peer": ")" + gw1.human() + R"("}})");
604 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
605 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 26);
606 BEAST_EXPECT(lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
607 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
608 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
612 auto const lines = env.rpc (
"json2",
"{ "
613 R
"("method" : "account_lines",)"
614 R"("jsonrpc" : "2.0",)"
615 R"("ripplerpc" : "2.0",)"
618 R"({"account": ")" + alice.human() + R"(", )"
620 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"}})");
621 BEAST_EXPECT(lines[jss::error][jss::message] ==
623 BEAST_EXPECT(lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
624 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
625 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
629 auto const lines = env.rpc (
"json2",
"{ "
630 R
"("method" : "account_lines",)"
631 R"("jsonrpc" : "2.0",)"
632 R"("ripplerpc" : "2.0",)"
635 R"({"account": ")" + alice.human() + R"(", )"
637 BEAST_EXPECT(lines[jss::error][jss::message] ==
639 BEAST_EXPECT(
lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
640 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
641 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
645 auto const linesA = env.rpc (
"json2",
"{ "
646 R
"("method" : "account_lines",)"
647 R"("jsonrpc" : "2.0",)"
648 R"("ripplerpc" : "2.0",)"
651 R"({"account": ")" + alice.human() + R"(", )"
653 BEAST_EXPECT(linesA[jss::result][jss::lines].isArray());
654 BEAST_EXPECT(linesA[jss::result][jss::lines].size() == 1);
655 BEAST_EXPECT(linesA.isMember(jss::jsonrpc) && linesA[jss::jsonrpc] == "2.0");
656 BEAST_EXPECT(linesA.isMember(jss::ripplerpc) && linesA[jss::ripplerpc] ==
"2.0");
657 BEAST_EXPECT(linesA.isMember(jss::id) && linesA[jss::id] == 5);
660 auto marker = linesA[jss::result][jss::marker].asString();
661 auto const linesB = env.rpc (
"json2",
"{ "
662 R
"("method" : "account_lines",)"
663 R"("jsonrpc" : "2.0",)"
664 R"("ripplerpc" : "2.0",)"
667 R"({"account": ")" + alice.human() + R"(", )"
668 R"("marker": ")" + marker + R"("}})");
669 BEAST_EXPECT(linesB[jss::result][jss::lines].isArray());
670 BEAST_EXPECT(linesB[jss::result][jss::lines].size() == 51);
671 BEAST_EXPECT(linesB.isMember(jss::jsonrpc) && linesB[jss::jsonrpc] == "2.0");
672 BEAST_EXPECT(linesB.isMember(jss::ripplerpc) && linesB[jss::ripplerpc] ==
"2.0");
673 BEAST_EXPECT(linesB.isMember(jss::id) && linesB[jss::id] == 5);
676 auto const linesC = env.rpc (
"json2",
"{ "
677 R
"("method" : "account_lines",)"
678 R"("jsonrpc" : "2.0",)"
679 R"("ripplerpc" : "2.0",)"
682 R"({"account": ")" + alice.human() + R"(", )"
684 R"("marker": ")" + marker + R"("}})");
685 BEAST_EXPECT(linesC[jss::result][jss::lines].isArray());
686 BEAST_EXPECT(linesC[jss::result][jss::lines].size() == 3);
687 BEAST_EXPECT(linesC.isMember(jss::jsonrpc) && linesC[jss::jsonrpc] == "2.0");
688 BEAST_EXPECT(linesC.isMember(jss::ripplerpc) && linesC[jss::ripplerpc] ==
"2.0");
689 BEAST_EXPECT(linesC.isMember(jss::id) && linesC[jss::id] == 5);
692 marker[5] = marker[5] ==
'7' ?
'8' :
'7';
693 auto const linesD = env.rpc (
"json2",
"{ "
694 R
"("method" : "account_lines",)"
695 R"("jsonrpc" : "2.0",)"
696 R"("ripplerpc" : "2.0",)"
699 R"({"account": ")" + alice.human() + R"(", )"
700 R"("marker": ")" + marker + R"("}})");
701 BEAST_EXPECT(linesD[jss::error][jss::message] ==
703 BEAST_EXPECT(linesD.isMember(jss::jsonrpc) && linesD[jss::jsonrpc] == "2.0");
704 BEAST_EXPECT(linesD.isMember(jss::ripplerpc) && linesD[jss::ripplerpc] ==
"2.0");
705 BEAST_EXPECT(linesD.isMember(jss::id) && linesD[jss::id] == 5);
709 auto const lines = env.rpc (
"json2",
"{ "
710 R
"("method" : "account_lines",)"
711 R"("jsonrpc" : "2.0",)"
712 R"("ripplerpc" : "2.0",)"
715 R"({"account": ")" + alice.human() + R"(", )"
716 R"("marker": true}})");
717 BEAST_EXPECT(lines[jss::error][jss::message] ==
719 BEAST_EXPECT(
lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
720 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
721 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
725 auto const lines = env.rpc (
"json2",
"{ "
726 R
"("method" : "account_lines",)"
727 R"("jsonrpc" : "2.0",)"
728 R"("ripplerpc" : "2.0",)"
731 R"({"account": ")" + alice.human() + R"(", )"
733 R"("peer": ")" + gw2.human() + R"("}})");
734 auto const& line =
lines[jss::result][jss::lines][0u];
735 BEAST_EXPECT(line[jss::freeze].asBool() ==
true);
736 BEAST_EXPECT(line[jss::no_ripple].asBool() ==
true);
737 BEAST_EXPECT(line[jss::peer_authorized].asBool() ==
true);
738 BEAST_EXPECT(
lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
739 BEAST_EXPECT(
lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] ==
"2.0");
740 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
744 auto const linesA = env.rpc (
"json2",
"{ "
745 R
"("method" : "account_lines",)"
746 R"("jsonrpc" : "2.0",)"
747 R"("ripplerpc" : "2.0",)"
750 R"({"account": ")" + gw2.human() + R"(", )"
752 R"("peer": ")" + alice.human() + R"("}})");
753 auto const& lineA = linesA[jss::result][jss::lines][0u];
754 BEAST_EXPECT(lineA[jss::freeze_peer].asBool() ==
true);
755 BEAST_EXPECT(lineA[jss::no_ripple_peer].asBool() ==
true);
756 BEAST_EXPECT(lineA[jss::authorized].asBool() ==
true);
757 BEAST_EXPECT(linesA.isMember(jss::jsonrpc) && linesA[jss::jsonrpc] ==
"2.0");
758 BEAST_EXPECT(linesA.isMember(jss::ripplerpc) && linesA[jss::ripplerpc] ==
"2.0");
759 BEAST_EXPECT(linesA.isMember(jss::id) && linesA[jss::id] == 5);
762 BEAST_EXPECT(linesA[jss::result].isMember(jss::marker));
763 auto const marker = linesA[jss::result][jss::marker].asString();
764 auto const linesB = env.rpc (
"json2",
"{ "
765 R
"("method" : "account_lines",)"
766 R"("jsonrpc" : "2.0",)"
767 R"("ripplerpc" : "2.0",)"
770 R"({"account": ")" + gw2.human() + R"(", )"
772 R"("marker": ")" + marker + R"(", )"
773 R"("peer": ")" + alice.human() + R"("}})");
774 BEAST_EXPECT(linesB[jss::result][jss::lines].isArray());
775 BEAST_EXPECT(linesB[jss::result][jss::lines].size() == 25);
776 BEAST_EXPECT(! linesB[jss::result].isMember(jss::marker));
777 BEAST_EXPECT(linesB.isMember(jss::jsonrpc) && linesB[jss::jsonrpc] == "2.0");
778 BEAST_EXPECT(linesB.isMember(jss::ripplerpc) && linesB[jss::ripplerpc] ==
"2.0");
779 BEAST_EXPECT(linesB.isMember(jss::id) && linesB[jss::id] == 5);
784 void testAccountLineDelete2()
786 testcase (
"V2: account_lines with removed marker");
788 using namespace test::jtx;
802 Account
const alice {
"alice"};
803 Account
const becky {
"becky"};
804 Account
const cheri {
"cheri"};
805 Account
const gw1 {
"gw1"};
806 Account
const gw2 {
"gw2"};
807 env.fund(
XRP(10000), alice, becky, cheri, gw1, gw2);
810 auto const USD = gw1[
"USD"];
811 auto const EUR = gw2[
"EUR"];
812 env(
trust(alice, USD(200)));
813 env(
trust(becky, EUR(200)));
814 env(
trust(cheri, EUR(200)));
818 env(
pay(gw2, becky, EUR(100)));
822 env(
offer(alice, EUR(100),
XRP(100)));
826 env(
offer(becky,
XRP(100), EUR(100)));
830 auto const linesBeg = env.rpc (
"json2",
"{ "
831 R
"("method" : "account_lines",)"
832 R"("jsonrpc" : "2.0",)"
833 R"("ripplerpc" : "2.0",)"
836 R"({"account": ")" + alice.human() + R"(", )"
838 BEAST_EXPECT(linesBeg[jss::result][jss::lines][0u][jss::currency] == "USD");
839 BEAST_EXPECT(linesBeg[jss::result].isMember(jss::marker));
840 BEAST_EXPECT(linesBeg.isMember(jss::jsonrpc) && linesBeg[jss::jsonrpc] ==
"2.0");
841 BEAST_EXPECT(linesBeg.isMember(jss::ripplerpc) && linesBeg[jss::ripplerpc] ==
"2.0");
842 BEAST_EXPECT(linesBeg.isMember(jss::id) && linesBeg[jss::id] == 5);
845 env(
pay(alice, cheri, EUR(100)));
850 auto const linesEnd = env.rpc (
"json2",
"{ "
851 R
"("method" : "account_lines",)"
852 R"("jsonrpc" : "2.0",)"
853 R"("ripplerpc" : "2.0",)"
856 R"({"account": ")" + alice.human() + R"(", )"
858 linesBeg[jss::result][jss::marker].asString() + R"("}})");
859 BEAST_EXPECT(linesEnd[jss::error][jss::message] ==
861 BEAST_EXPECT(linesEnd.isMember(jss::jsonrpc) && linesEnd[jss::jsonrpc] == "2.0");
862 BEAST_EXPECT(linesEnd.isMember(jss::ripplerpc) && linesEnd[jss::ripplerpc] ==
"2.0");
863 BEAST_EXPECT(linesEnd.isMember(jss::id) && linesEnd[jss::id] == 5);
869 testAccountLineDelete();
871 testAccountLineDelete2();