41 using namespace test::jtx;
43 char const credType[] =
"abcde";
44 char const uri[] =
"uri";
47 Account const subject{
"subject"};
50 Env env{*
this, features};
57 env.fund(
XRP(5000), subject, issuer, other);
65 auto const sleCred = env.le(credKey);
66 BEAST_EXPECT(
static_cast<bool>(sleCred));
70 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == subject.id());
71 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
72 BEAST_EXPECT(!sleCred->getFieldU32(sfFlags));
75 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
76 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
80 jle.isObject() && jle.isMember(jss::result) &&
81 !jle[jss::result].isMember(jss::error) &&
82 jle[jss::result].isMember(jss::node) &&
83 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
84 jle[jss::result][jss::node][
"LedgerEntryType"] ==
86 jle[jss::result][jss::node][jss::Issuer] ==
88 jle[jss::result][jss::node][jss::Subject] ==
90 jle[jss::result][jss::node][
"CredentialType"] ==
99 auto const sleCred = env.le(credKey);
100 BEAST_EXPECT(
static_cast<bool>(sleCred));
104 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == subject.id());
105 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
108 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
109 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
110 BEAST_EXPECT(sleCred->getFieldU32(sfFlags) ==
lsfAccepted);
116 BEAST_EXPECT(!env.le(credKey));
124 jle.isObject() && jle.isMember(jss::result) &&
125 jle[jss::result].isMember(jss::error) &&
126 jle[jss::result][jss::error] ==
"entryNotFound");
139 auto const sleCred = env.le(credKey);
140 BEAST_EXPECT(
static_cast<bool>(sleCred));
144 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == issuer.id());
145 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
146 BEAST_EXPECT((sleCred->getFieldU32(sfFlags) &
lsfAccepted));
148 sleCred->getFieldU64(sfIssuerNode) ==
149 sleCred->getFieldU64(sfSubjectNode));
151 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
152 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
156 jle.isObject() && jle.isMember(jss::result) &&
157 !jle[jss::result].isMember(jss::error) &&
158 jle[jss::result].isMember(jss::node) &&
159 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
160 jle[jss::result][jss::node][
"LedgerEntryType"] ==
162 jle[jss::result][jss::node][jss::Issuer] ==
164 jle[jss::result][jss::node][jss::Subject] ==
166 jle[jss::result][jss::node][
"CredentialType"] ==
173 BEAST_EXPECT(!env.le(credKey));
180 jle.isObject() && jle.isMember(jss::result) &&
181 jle[jss::result].isMember(jss::error) &&
182 jle[jss::result][jss::error] ==
"entryNotFound");
190 using namespace test::jtx;
192 char const credType[] =
"abcde";
194 Account const issuer{
"issuer"};
195 Account const subject{
"subject"};
198 Env env{*
this, features};
201 env.fund(
XRP(5000), issuer, subject, other);
205 testcase(
"Delete issuer before accept");
213 int const delta = env.seq(issuer) + 255;
214 for (
int i = 0; i < delta; ++i)
216 auto const acctDelFee{
drops(env.current()->fees().increment)};
223 BEAST_EXPECT(!env.le(credKey));
230 jle.isObject() && jle.isMember(jss::result) &&
231 jle[jss::result].isMember(jss::error) &&
232 jle[jss::result][jss::error] ==
"entryNotFound");
236 env.fund(
XRP(5000), issuer);
241 testcase(
"Delete issuer after accept");
251 int const delta = env.seq(issuer) + 255;
252 for (
int i = 0; i < delta; ++i)
254 auto const acctDelFee{
drops(env.current()->fees().increment)};
261 BEAST_EXPECT(!env.le(credKey));
268 jle.isObject() && jle.isMember(jss::result) &&
269 jle[jss::result].isMember(jss::error) &&
270 jle[jss::result][jss::error] ==
"entryNotFound");
274 env.fund(
XRP(5000), issuer);
279 testcase(
"Delete subject before accept");
287 int const delta = env.seq(subject) + 255;
288 for (
int i = 0; i < delta; ++i)
290 auto const acctDelFee{
drops(env.current()->fees().increment)};
297 BEAST_EXPECT(!env.le(credKey));
304 jle.isObject() && jle.isMember(jss::result) &&
305 jle[jss::result].isMember(jss::error) &&
306 jle[jss::result][jss::error] ==
"entryNotFound");
310 env.fund(
XRP(5000), subject);
315 testcase(
"Delete subject after accept");
325 int const delta = env.seq(subject) + 255;
326 for (
int i = 0; i < delta; ++i)
328 auto const acctDelFee{
drops(env.current()->fees().increment)};
335 BEAST_EXPECT(!env.le(credKey));
342 jle.isObject() && jle.isMember(jss::result) &&
343 jle[jss::result].isMember(jss::error) &&
344 jle[jss::result][jss::error] ==
"entryNotFound");
348 env.fund(
XRP(5000), subject);
357 uint32_t
const t = env.current()
359 .parentCloseTime.time_since_epoch()
361 jv[sfExpiration.jsonName] = t + 20;
375 BEAST_EXPECT(!env.le(credKey));
383 jle.isObject() && jle.isMember(jss::result) &&
384 jle[jss::result].isMember(jss::error) &&
385 jle[jss::result][jss::error] ==
"entryNotFound");
401 BEAST_EXPECT(!env.le(credKey));
407 jle.isObject() && jle.isMember(jss::result) &&
408 jle[jss::result].isMember(jss::error) &&
409 jle[jss::result][jss::error] ==
"entryNotFound");
423 BEAST_EXPECT(!env.le(credKey));
429 jle.isObject() && jle.isMember(jss::result) &&
430 jle[jss::result].isMember(jss::error) &&
431 jle[jss::result][jss::error] ==
"entryNotFound");
439 using namespace test::jtx;
441 char const credType[] =
"abcde";
443 Account const issuer{
"issuer"};
444 Account const subject{
"subject"};
448 Env env{*
this, features};
450 env.fund(
XRP(5000), subject, issuer);
454 testcase(
"Credentials fail, no subject param.");
456 jv.removeMember(jss::Subject);
467 testcase(
"Credentials fail, no credentialType param.");
469 jv.removeMember(sfCredentialType.jsonName);
474 testcase(
"Credentials fail, empty credentialType param.");
481 "Credentials fail, credentialType length > "
482 "maxCredentialTypeLength.");
484 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
485 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p";
492 testcase(
"Credentials fail, URI length > 256.");
494 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
495 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p "
496 "9hfup;wDJFBVSD8f72 "
498 "djvbldafghwpEFHdjfaidfgio84763tfysgdvhjasbd "
499 "vujhgWQIE7F6WEUYFGWUKEYFVQW87FGWOEFWEFUYWVEF8723GFWEFB"
501 "fv28o37gfwEFB3872TFO8GSDSDVD";
509 testcase(
"Credentials fail, URI empty.");
516 testcase(
"Credentials fail, expiration in the past.");
519 uint32_t
const t = env.current()
521 .parentCloseTime.time_since_epoch()
524 jv[sfExpiration.jsonName] = t;
529 testcase(
"Credentials fail, invalid fee.");
537 testcase(
"Credentials fail, duplicate.");
548 jle.isObject() && jle.isMember(jss::result) &&
549 !jle[jss::result].isMember(jss::error) &&
550 jle[jss::result].isMember(jss::node) &&
551 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
552 jle[jss::result][jss::node][
"LedgerEntryType"] ==
554 jle[jss::result][jss::node][jss::Issuer] ==
556 jle[jss::result][jss::node][jss::Subject] ==
558 jle[jss::result][jss::node][
"CredentialType"] ==
565 Env env{*
this, features};
567 env.fund(
XRP(5000), issuer);
571 testcase(
"Credentials fail, subject doesn't exist.");
579 Env env{*
this, features};
581 auto const reserve =
drops(env.current()->fees().accountReserve(0));
582 env.fund(
reserve, subject, issuer);
585 testcase(
"Credentials fail, not enough reserve.");
599 char const credType[] =
"abcde";
600 Account const issuer{
"issuer"};
601 Account const subject{
"subject"};
605 Env env{*
this, features};
607 env.fund(
XRP(5000), subject, issuer);
610 testcase(
"CredentialsAccept fail, Credential doesn't exist.");
617 testcase(
"CredentialsAccept fail, invalid Issuer account.");
626 "CredentialsAccept fail, invalid credentialType param.");
633 Env env{*
this, features};
635 env.fund(
drops(env.current()->fees().accountReserve(1)), issuer);
636 env.fund(
drops(env.current()->fees().accountReserve(0)), subject);
640 testcase(
"CredentialsAccept fail, not enough reserve.");
652 jle.isObject() && jle.isMember(jss::result) &&
653 !jle[jss::result].isMember(jss::error) &&
654 jle[jss::result].isMember(jss::node) &&
655 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
656 jle[jss::result][jss::node][
"LedgerEntryType"] ==
658 jle[jss::result][jss::node][jss::Issuer] ==
660 jle[jss::result][jss::node][jss::Subject] ==
662 jle[jss::result][jss::node][
"CredentialType"] ==
669 Env env{*
this, features};
671 env.fund(
XRP(5000), subject, issuer);
678 testcase(
"CredentialsAccept fail, invalid fee.");
683 testcase(
"CredentialsAccept fail, lsfAccepted already set.");
694 jle.isObject() && jle.isMember(jss::result) &&
695 !jle[jss::result].isMember(jss::error) &&
696 jle[jss::result].isMember(jss::node) &&
697 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
698 jle[jss::result][jss::node][
"LedgerEntryType"] ==
700 jle[jss::result][jss::node][jss::Issuer] ==
702 jle[jss::result][jss::node][jss::Subject] ==
704 jle[jss::result][jss::node][
"CredentialType"] ==
709 char const credType2[] =
"efghi";
711 testcase(
"CredentialsAccept fail, expired credentials.");
713 uint32_t
const t = env.current()
715 .parentCloseTime.time_since_epoch()
717 jv[sfExpiration.jsonName] = t;
727 auto const jDelCred =
730 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
731 jDelCred[jss::result].isMember(jss::error) &&
732 jDelCred[jss::result][jss::error] ==
"entryNotFound");
741 Env env{*
this, features};
743 env.fund(
XRP(5000), issuer, subject, other);
747 testcase(
"CredentialsAccept fail, issuer doesn't exist.");
753 int const delta = env.seq(issuer) + 255;
754 for (
int i = 0; i < delta; ++i)
756 auto const acctDelFee{
drops(env.current()->fees().increment)};
765 auto const jDelCred =
768 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
769 jDelCred[jss::result].isMember(jss::error) &&
770 jDelCred[jss::result][jss::error] ==
"entryNotFound");
778 using namespace test::jtx;
780 char const credType[] =
"abcde";
781 Account const issuer{
"issuer"};
782 Account const subject{
"subject"};
787 Env env{*
this, features};
789 env.fund(
XRP(5000), subject, issuer, other);
793 testcase(
"CredentialsDelete fail, no Credentials.");
800 testcase(
"CredentialsDelete fail, invalid Subject account.");
809 testcase(
"CredentialsDelete fail, invalid Issuer account.");
819 "CredentialsDelete fail, invalid credentialType param.");
825 char const credType2[] =
"fghij";
839 jle.isObject() && jle.isMember(jss::result) &&
840 !jle[jss::result].isMember(jss::error) &&
841 jle[jss::result].isMember(jss::node) &&
842 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
843 jle[jss::result][jss::node][
"LedgerEntryType"] ==
845 jle[jss::result][jss::node][jss::Issuer] ==
847 jle[jss::result][jss::node][jss::Subject] ==
849 jle[jss::result][jss::node][
"CredentialType"] ==
854 testcase(
"CredentialsDelete fail, time not expired yet.");
858 uint32_t
const t = env.current()
860 .parentCloseTime.time_since_epoch()
863 jv[sfExpiration.jsonName] = t;
876 jle.isObject() && jle.isMember(jss::result) &&
877 !jle[jss::result].isMember(jss::error) &&
878 jle[jss::result].isMember(jss::node) &&
879 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
880 jle[jss::result][jss::node][
"LedgerEntryType"] ==
882 jle[jss::result][jss::node][jss::Issuer] ==
884 jle[jss::result][jss::node][jss::Subject] ==
886 jle[jss::result][jss::node][
"CredentialType"] ==
891 testcase(
"CredentialsDelete fail, no Issuer and Subject.");
895 jv.removeMember(jss::Subject);
896 jv.removeMember(jss::Issuer);
902 testcase(
"CredentialsDelete fail, invalid fee.");
912 testcase(
"deleteSLE fail, bad SLE.");
953 using namespace test::jtx;
955 char const credType[] =
"abcde";
956 Account const issuer{
"issuer"};
957 Account const subject{
"subject"};
963 env.
fund(
XRP(5000), subject, issuer);
977 params[jss::account] = subject.human();
978 auto const jv = env.rpc(
979 "json",
"account_tx",
to_string(params))[jss::result];
981 BEAST_EXPECT(jv[jss::transactions].size() == 4);
982 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
984 tx0[jss::TransactionType] == jss::CredentialAccept);
985 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
987 tx1[jss::TransactionType] == jss::CredentialCreate);
988 txHash0 = tx0[jss::hash].asString();
989 txHash1 = tx1[jss::hash].asString();
994 params[jss::account] = issuer.human();
995 auto const jv = env.rpc(
996 "json",
"account_tx",
to_string(params))[jss::result];
998 BEAST_EXPECT(jv[jss::transactions].size() == 4);
999 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
1001 tx0[jss::TransactionType] == jss::CredentialAccept);
1002 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
1004 tx1[jss::TransactionType] == jss::CredentialCreate);
1006 BEAST_EXPECT(txHash0 == tx0[jss::hash].asString());
1007 BEAST_EXPECT(txHash1 == tx1[jss::hash].asString());
1014 params[jss::account] = subject.human();
1016 "json",
"account_objects",
to_string(params))[jss::result];
1018 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
1019 auto const& object(jv[jss::account_objects][0u]);
1022 object[
"LedgerEntryType"].asString() == jss::Credential);
1023 objectIdx =
object[jss::index].asString();
1028 params[jss::account] = issuer.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 BEAST_EXPECT(objectIdx ==
object[jss::index].asString());