22 using namespace test::jtx;
24 char const credType[] =
"abcde";
25 char const uri[] =
"uri";
28 Account const subject{
"subject"};
31 Env env{*
this, features};
38 env.fund(
XRP(5000), subject, issuer, other);
46 auto const sleCred = env.le(credKey);
47 BEAST_EXPECT(
static_cast<bool>(sleCred));
51 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == subject.id());
52 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
53 BEAST_EXPECT(!sleCred->getFieldU32(sfFlags));
56 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
57 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
61 jle.isObject() && jle.isMember(jss::result) &&
62 !jle[jss::result].isMember(jss::error) &&
63 jle[jss::result].isMember(jss::node) &&
64 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
65 jle[jss::result][jss::node][
"LedgerEntryType"] ==
67 jle[jss::result][jss::node][jss::Issuer] ==
69 jle[jss::result][jss::node][jss::Subject] ==
71 jle[jss::result][jss::node][
"CredentialType"] ==
80 auto const sleCred = env.le(credKey);
81 BEAST_EXPECT(
static_cast<bool>(sleCred));
85 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == subject.id());
86 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
89 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
90 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
91 BEAST_EXPECT(sleCred->getFieldU32(sfFlags) ==
lsfAccepted);
97 BEAST_EXPECT(!env.le(credKey));
105 jle.isObject() && jle.isMember(jss::result) &&
106 jle[jss::result].isMember(jss::error) &&
107 jle[jss::result][jss::error] ==
"entryNotFound");
120 auto const sleCred = env.le(credKey);
121 BEAST_EXPECT(
static_cast<bool>(sleCred));
125 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == issuer.id());
126 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
127 BEAST_EXPECT((sleCred->getFieldU32(sfFlags) &
lsfAccepted));
129 sleCred->getFieldU64(sfIssuerNode) ==
130 sleCred->getFieldU64(sfSubjectNode));
132 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
133 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
137 jle.isObject() && jle.isMember(jss::result) &&
138 !jle[jss::result].isMember(jss::error) &&
139 jle[jss::result].isMember(jss::node) &&
140 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
141 jle[jss::result][jss::node][
"LedgerEntryType"] ==
143 jle[jss::result][jss::node][jss::Issuer] ==
145 jle[jss::result][jss::node][jss::Subject] ==
147 jle[jss::result][jss::node][
"CredentialType"] ==
154 BEAST_EXPECT(!env.le(credKey));
161 jle.isObject() && jle.isMember(jss::result) &&
162 jle[jss::result].isMember(jss::error) &&
163 jle[jss::result][jss::error] ==
"entryNotFound");
171 using namespace test::jtx;
173 char const credType[] =
"abcde";
175 Account const issuer{
"issuer"};
176 Account const subject{
"subject"};
179 Env env{*
this, features};
182 env.fund(
XRP(5000), issuer, subject, other);
186 testcase(
"Delete issuer before accept");
194 int const delta = env.seq(issuer) + 255;
195 for (
int i = 0; i < delta; ++i)
197 auto const acctDelFee{
drops(env.current()->fees().increment)};
204 BEAST_EXPECT(!env.le(credKey));
211 jle.isObject() && jle.isMember(jss::result) &&
212 jle[jss::result].isMember(jss::error) &&
213 jle[jss::result][jss::error] ==
"entryNotFound");
217 env.fund(
XRP(5000), issuer);
222 testcase(
"Delete issuer after accept");
232 int const delta = env.seq(issuer) + 255;
233 for (
int i = 0; i < delta; ++i)
235 auto const acctDelFee{
drops(env.current()->fees().increment)};
242 BEAST_EXPECT(!env.le(credKey));
249 jle.isObject() && jle.isMember(jss::result) &&
250 jle[jss::result].isMember(jss::error) &&
251 jle[jss::result][jss::error] ==
"entryNotFound");
255 env.fund(
XRP(5000), issuer);
260 testcase(
"Delete subject before accept");
268 int const delta = env.seq(subject) + 255;
269 for (
int i = 0; i < delta; ++i)
271 auto const acctDelFee{
drops(env.current()->fees().increment)};
278 BEAST_EXPECT(!env.le(credKey));
285 jle.isObject() && jle.isMember(jss::result) &&
286 jle[jss::result].isMember(jss::error) &&
287 jle[jss::result][jss::error] ==
"entryNotFound");
291 env.fund(
XRP(5000), subject);
296 testcase(
"Delete subject after accept");
306 int const delta = env.seq(subject) + 255;
307 for (
int i = 0; i < delta; ++i)
309 auto const acctDelFee{
drops(env.current()->fees().increment)};
316 BEAST_EXPECT(!env.le(credKey));
323 jle.isObject() && jle.isMember(jss::result) &&
324 jle[jss::result].isMember(jss::error) &&
325 jle[jss::result][jss::error] ==
"entryNotFound");
329 env.fund(
XRP(5000), subject);
338 uint32_t
const t = env.current()
340 .parentCloseTime.time_since_epoch()
342 jv[sfExpiration.jsonName] = t + 20;
356 BEAST_EXPECT(!env.le(credKey));
364 jle.isObject() && jle.isMember(jss::result) &&
365 jle[jss::result].isMember(jss::error) &&
366 jle[jss::result][jss::error] ==
"entryNotFound");
382 BEAST_EXPECT(!env.le(credKey));
388 jle.isObject() && jle.isMember(jss::result) &&
389 jle[jss::result].isMember(jss::error) &&
390 jle[jss::result][jss::error] ==
"entryNotFound");
404 BEAST_EXPECT(!env.le(credKey));
410 jle.isObject() && jle.isMember(jss::result) &&
411 jle[jss::result].isMember(jss::error) &&
412 jle[jss::result][jss::error] ==
"entryNotFound");
420 using namespace test::jtx;
422 char const credType[] =
"abcde";
424 Account const issuer{
"issuer"};
425 Account const subject{
"subject"};
429 Env env{*
this, features};
431 env.fund(
XRP(5000), subject, issuer);
435 testcase(
"Credentials fail, no subject param.");
437 jv.removeMember(jss::Subject);
448 testcase(
"Credentials fail, no credentialType param.");
450 jv.removeMember(sfCredentialType.jsonName);
455 testcase(
"Credentials fail, empty credentialType param.");
462 "Credentials fail, credentialType length > "
463 "maxCredentialTypeLength.");
465 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
466 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p";
473 testcase(
"Credentials fail, URI length > 256.");
475 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
476 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p "
477 "9hfup;wDJFBVSD8f72 "
479 "djvbldafghwpEFHdjfaidfgio84763tfysgdvhjasbd "
480 "vujhgWQIE7F6WEUYFGWUKEYFVQW87FGWOEFWEFUYWVEF8723GFWEFB"
482 "fv28o37gfwEFB3872TFO8GSDSDVD";
490 testcase(
"Credentials fail, URI empty.");
497 testcase(
"Credentials fail, expiration in the past.");
500 uint32_t
const t = env.current()
502 .parentCloseTime.time_since_epoch()
505 jv[sfExpiration.jsonName] = t;
510 testcase(
"Credentials fail, invalid fee.");
518 testcase(
"Credentials fail, duplicate.");
529 jle.isObject() && jle.isMember(jss::result) &&
530 !jle[jss::result].isMember(jss::error) &&
531 jle[jss::result].isMember(jss::node) &&
532 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
533 jle[jss::result][jss::node][
"LedgerEntryType"] ==
535 jle[jss::result][jss::node][jss::Issuer] ==
537 jle[jss::result][jss::node][jss::Subject] ==
539 jle[jss::result][jss::node][
"CredentialType"] ==
544 testcase(
"Credentials fail, directory full");
579 Env env{*
this, features};
581 env.fund(
XRP(5000), issuer);
585 testcase(
"Credentials fail, subject doesn't exist.");
593 Env env{*
this, features};
595 auto const reserve =
drops(env.current()->fees().reserve);
596 env.fund(
reserve, subject, issuer);
599 testcase(
"Credentials fail, not enough reserve.");
613 char const credType[] =
"abcde";
614 Account const issuer{
"issuer"};
615 Account const subject{
"subject"};
619 Env env{*
this, features};
621 env.fund(
XRP(5000), subject, issuer);
624 testcase(
"CredentialsAccept fail, Credential doesn't exist.");
631 testcase(
"CredentialsAccept fail, invalid Issuer account.");
640 "CredentialsAccept fail, invalid credentialType param.");
647 Env env{*
this, features};
649 env.fund(
drops(env.current()->fees().accountReserve(1)), issuer);
650 env.fund(
drops(env.current()->fees().accountReserve(0)), subject);
654 testcase(
"CredentialsAccept fail, not enough reserve.");
666 jle.isObject() && jle.isMember(jss::result) &&
667 !jle[jss::result].isMember(jss::error) &&
668 jle[jss::result].isMember(jss::node) &&
669 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
670 jle[jss::result][jss::node][
"LedgerEntryType"] ==
672 jle[jss::result][jss::node][jss::Issuer] ==
674 jle[jss::result][jss::node][jss::Subject] ==
676 jle[jss::result][jss::node][
"CredentialType"] ==
683 Env env{*
this, features};
685 env.fund(
XRP(5000), subject, issuer);
692 testcase(
"CredentialsAccept fail, invalid fee.");
697 testcase(
"CredentialsAccept fail, lsfAccepted already set.");
708 jle.isObject() && jle.isMember(jss::result) &&
709 !jle[jss::result].isMember(jss::error) &&
710 jle[jss::result].isMember(jss::node) &&
711 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
712 jle[jss::result][jss::node][
"LedgerEntryType"] ==
714 jle[jss::result][jss::node][jss::Issuer] ==
716 jle[jss::result][jss::node][jss::Subject] ==
718 jle[jss::result][jss::node][
"CredentialType"] ==
723 char const credType2[] =
"efghi";
725 testcase(
"CredentialsAccept fail, expired credentials.");
727 uint32_t
const t = env.current()
729 .parentCloseTime.time_since_epoch()
731 jv[sfExpiration.jsonName] = t;
741 auto const jDelCred =
744 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
745 jDelCred[jss::result].isMember(jss::error) &&
746 jDelCred[jss::result][jss::error] ==
"entryNotFound");
755 Env env{*
this, features};
757 env.fund(
XRP(5000), issuer, subject, other);
761 testcase(
"CredentialsAccept fail, issuer doesn't exist.");
767 int const delta = env.seq(issuer) + 255;
768 for (
int i = 0; i < delta; ++i)
770 auto const acctDelFee{
drops(env.current()->fees().increment)};
779 auto const jDelCred =
782 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
783 jDelCred[jss::result].isMember(jss::error) &&
784 jDelCred[jss::result][jss::error] ==
"entryNotFound");
792 using namespace test::jtx;
794 char const credType[] =
"abcde";
795 Account const issuer{
"issuer"};
796 Account const subject{
"subject"};
801 Env env{*
this, features};
803 env.fund(
XRP(5000), subject, issuer, other);
807 testcase(
"CredentialsDelete fail, no Credentials.");
814 testcase(
"CredentialsDelete fail, invalid Subject account.");
823 testcase(
"CredentialsDelete fail, invalid Issuer account.");
833 "CredentialsDelete fail, invalid credentialType param.");
839 char const credType2[] =
"fghij";
853 jle.isObject() && jle.isMember(jss::result) &&
854 !jle[jss::result].isMember(jss::error) &&
855 jle[jss::result].isMember(jss::node) &&
856 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
857 jle[jss::result][jss::node][
"LedgerEntryType"] ==
859 jle[jss::result][jss::node][jss::Issuer] ==
861 jle[jss::result][jss::node][jss::Subject] ==
863 jle[jss::result][jss::node][
"CredentialType"] ==
868 testcase(
"CredentialsDelete fail, time not expired yet.");
872 uint32_t
const t = env.current()
874 .parentCloseTime.time_since_epoch()
877 jv[sfExpiration.jsonName] = t;
890 jle.isObject() && jle.isMember(jss::result) &&
891 !jle[jss::result].isMember(jss::error) &&
892 jle[jss::result].isMember(jss::node) &&
893 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
894 jle[jss::result][jss::node][
"LedgerEntryType"] ==
896 jle[jss::result][jss::node][jss::Issuer] ==
898 jle[jss::result][jss::node][jss::Subject] ==
900 jle[jss::result][jss::node][
"CredentialType"] ==
905 testcase(
"CredentialsDelete fail, no Issuer and Subject.");
909 jv.removeMember(jss::Subject);
910 jv.removeMember(jss::Issuer);
916 testcase(
"CredentialsDelete fail, invalid fee.");
926 testcase(
"deleteSLE fail, bad SLE.");
967 using namespace test::jtx;
969 char const credType[] =
"abcde";
970 Account const issuer{
"issuer"};
971 Account const subject{
"subject"};
977 env.
fund(
XRP(5000), subject, issuer);
991 params[jss::account] = subject.human();
992 auto const jv = env.rpc(
993 "json",
"account_tx",
to_string(params))[jss::result];
995 BEAST_EXPECT(jv[jss::transactions].size() == 4);
996 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
998 tx0[jss::TransactionType] == jss::CredentialAccept);
999 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
1001 tx1[jss::TransactionType] == jss::CredentialCreate);
1002 txHash0 = tx0[jss::hash].asString();
1003 txHash1 = tx1[jss::hash].asString();
1008 params[jss::account] = issuer.human();
1009 auto const jv = env.rpc(
1010 "json",
"account_tx",
to_string(params))[jss::result];
1012 BEAST_EXPECT(jv[jss::transactions].size() == 4);
1013 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
1015 tx0[jss::TransactionType] == jss::CredentialAccept);
1016 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
1018 tx1[jss::TransactionType] == jss::CredentialCreate);
1020 BEAST_EXPECT(txHash0 == tx0[jss::hash].asString());
1021 BEAST_EXPECT(txHash1 == tx1[jss::hash].asString());
1028 params[jss::account] = subject.human();
1030 "json",
"account_objects",
to_string(params))[jss::result];
1032 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
1033 auto const& object(jv[jss::account_objects][0u]);
1036 object[
"LedgerEntryType"].asString() == jss::Credential);
1037 objectIdx =
object[jss::index].asString();
1042 params[jss::account] = issuer.human();
1044 "json",
"account_objects",
to_string(params))[jss::result];
1046 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
1047 auto const& object(jv[jss::account_objects][0u]);
1050 object[
"LedgerEntryType"].asString() == jss::Credential);
1051 BEAST_EXPECT(objectIdx ==
object[jss::index].asString());