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);
45 auto const sleCred = env.le(credKey);
46 BEAST_EXPECT(
static_cast<bool>(sleCred));
50 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == subject.id());
51 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
52 BEAST_EXPECT(!sleCred->getFieldU32(sfFlags));
55 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
56 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
59 jle.isObject() && jle.isMember(jss::result) &&
60 !jle[jss::result].isMember(jss::error) &&
61 jle[jss::result].isMember(jss::node) &&
62 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
63 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
64 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
65 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
66 jle[jss::result][jss::node][
"CredentialType"] ==
75 auto const sleCred = env.le(credKey);
76 BEAST_EXPECT(
static_cast<bool>(sleCred));
80 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == subject.id());
81 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
84 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
85 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
86 BEAST_EXPECT(sleCred->getFieldU32(sfFlags) == lsfAccepted);
92 BEAST_EXPECT(!env.le(credKey));
99 jle.isObject() && jle.isMember(jss::result) &&
100 jle[jss::result].isMember(jss::error) &&
101 jle[jss::result][jss::error] ==
"entryNotFound");
113 auto const sleCred = env.le(credKey);
114 BEAST_EXPECT(
static_cast<bool>(sleCred));
118 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == issuer.id());
119 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
120 BEAST_EXPECT((sleCred->getFieldU32(sfFlags) & lsfAccepted));
122 sleCred->getFieldU64(sfIssuerNode) == sleCred->getFieldU64(sfSubjectNode));
124 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
125 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
128 jle.isObject() && jle.isMember(jss::result) &&
129 !jle[jss::result].isMember(jss::error) &&
130 jle[jss::result].isMember(jss::node) &&
131 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
132 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
133 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
134 jle[jss::result][jss::node][jss::Subject] == issuer.human() &&
135 jle[jss::result][jss::node][
"CredentialType"] ==
142 BEAST_EXPECT(!env.le(credKey));
148 jle.isObject() && jle.isMember(jss::result) &&
149 jle[jss::result].isMember(jss::error) &&
150 jle[jss::result][jss::error] ==
"entryNotFound");
158 using namespace test::jtx;
160 char const credType[] =
"abcde";
162 Account const issuer{
"issuer"};
163 Account const subject{
"subject"};
166 Env env{*
this, features};
169 env.fund(
XRP(5000), issuer, subject, other);
173 testcase(
"Delete issuer before accept");
181 int const delta = env.seq(issuer) + 255;
182 for (
int i = 0; i < delta; ++i)
184 auto const acctDelFee{
drops(env.current()->fees().increment)};
191 BEAST_EXPECT(!env.le(credKey));
197 jle.isObject() && jle.isMember(jss::result) &&
198 jle[jss::result].isMember(jss::error) &&
199 jle[jss::result][jss::error] ==
"entryNotFound");
203 env.fund(
XRP(5000), issuer);
208 testcase(
"Delete issuer after accept");
218 int const delta = env.seq(issuer) + 255;
219 for (
int i = 0; i < delta; ++i)
221 auto const acctDelFee{
drops(env.current()->fees().increment)};
228 BEAST_EXPECT(!env.le(credKey));
234 jle.isObject() && jle.isMember(jss::result) &&
235 jle[jss::result].isMember(jss::error) &&
236 jle[jss::result][jss::error] ==
"entryNotFound");
240 env.fund(
XRP(5000), issuer);
245 testcase(
"Delete subject before accept");
253 int const delta = env.seq(subject) + 255;
254 for (
int i = 0; i < delta; ++i)
256 auto const acctDelFee{
drops(env.current()->fees().increment)};
263 BEAST_EXPECT(!env.le(credKey));
269 jle.isObject() && jle.isMember(jss::result) &&
270 jle[jss::result].isMember(jss::error) &&
271 jle[jss::result][jss::error] ==
"entryNotFound");
275 env.fund(
XRP(5000), subject);
280 testcase(
"Delete subject after accept");
290 int const delta = env.seq(subject) + 255;
291 for (
int i = 0; i < delta; ++i)
293 auto const acctDelFee{
drops(env.current()->fees().increment)};
300 BEAST_EXPECT(!env.le(credKey));
306 jle.isObject() && jle.isMember(jss::result) &&
307 jle[jss::result].isMember(jss::error) &&
308 jle[jss::result][jss::error] ==
"entryNotFound");
312 env.fund(
XRP(5000), subject);
321 uint32_t
const t = env.current()->header().parentCloseTime.time_since_epoch().count();
322 jv[sfExpiration.jsonName] = t + 20;
336 BEAST_EXPECT(!env.le(credKey));
343 jle.isObject() && jle.isMember(jss::result) &&
344 jle[jss::result].isMember(jss::error) &&
345 jle[jss::result][jss::error] ==
"entryNotFound");
360 BEAST_EXPECT(!env.le(credKey));
365 jle.isObject() && jle.isMember(jss::result) &&
366 jle[jss::result].isMember(jss::error) &&
367 jle[jss::result][jss::error] ==
"entryNotFound");
380 BEAST_EXPECT(!env.le(credKey));
385 jle.isObject() && jle.isMember(jss::result) &&
386 jle[jss::result].isMember(jss::error) &&
387 jle[jss::result][jss::error] ==
"entryNotFound");
395 using namespace test::jtx;
397 char const credType[] =
"abcde";
399 Account const issuer{
"issuer"};
400 Account const subject{
"subject"};
404 Env env{*
this, features};
406 env.fund(
XRP(5000), subject, issuer);
410 testcase(
"Credentials fail, no subject param.");
412 jv.removeMember(jss::Subject);
423 testcase(
"Credentials fail, no credentialType param.");
425 jv.removeMember(sfCredentialType.jsonName);
430 testcase(
"Credentials fail, empty credentialType param.");
437 "Credentials fail, credentialType length > "
438 "maxCredentialTypeLength.");
440 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
441 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p";
448 testcase(
"Credentials fail, URI length > 256.");
450 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
451 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p "
452 "9hfup;wDJFBVSD8f72 "
454 "djvbldafghwpEFHdjfaidfgio84763tfysgdvhjasbd "
455 "vujhgWQIE7F6WEUYFGWUKEYFVQW87FGWOEFWEFUYWVEF8723GFWEFB"
457 "fv28o37gfwEFB3872TFO8GSDSDVD";
465 testcase(
"Credentials fail, URI empty.");
472 testcase(
"Credentials fail, expiration in the past.");
476 env.current()->header().parentCloseTime.time_since_epoch().count() - 1;
477 jv[sfExpiration.jsonName] = t;
482 testcase(
"Credentials fail, invalid fee.");
490 testcase(
"Credentials fail, duplicate.");
500 jle.isObject() && jle.isMember(jss::result) &&
501 !jle[jss::result].isMember(jss::error) &&
502 jle[jss::result].isMember(jss::node) &&
503 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
504 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
505 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
506 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
507 jle[jss::result][jss::node][
"CredentialType"] ==
512 testcase(
"Credentials fail, directory full");
548 Env env{*
this, features};
550 env.fund(
XRP(5000), issuer);
554 testcase(
"Credentials fail, subject doesn't exist.");
562 Env env{*
this, features};
564 auto const reserve =
drops(env.current()->fees().reserve);
565 env.fund(
reserve, subject, issuer);
568 testcase(
"Credentials fail, not enough reserve.");
582 char const credType[] =
"abcde";
583 Account const issuer{
"issuer"};
584 Account const subject{
"subject"};
588 Env env{*
this, features};
590 env.fund(
XRP(5000), subject, issuer);
593 testcase(
"CredentialsAccept fail, Credential doesn't exist.");
599 testcase(
"CredentialsAccept fail, invalid Issuer account.");
607 testcase(
"CredentialsAccept fail, invalid credentialType param.");
614 Env env{*
this, features};
616 env.fund(
drops(env.current()->fees().accountReserve(1)), issuer);
617 env.fund(
drops(env.current()->fees().accountReserve(0)), subject);
621 testcase(
"CredentialsAccept fail, not enough reserve.");
631 jle.isObject() && jle.isMember(jss::result) &&
632 !jle[jss::result].isMember(jss::error) &&
633 jle[jss::result].isMember(jss::node) &&
634 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
635 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
636 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
637 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
638 jle[jss::result][jss::node][
"CredentialType"] ==
645 Env env{*
this, features};
647 env.fund(
XRP(5000), subject, issuer);
654 testcase(
"CredentialsAccept fail, invalid fee.");
659 testcase(
"CredentialsAccept fail, lsfAccepted already set.");
668 jle.isObject() && jle.isMember(jss::result) &&
669 !jle[jss::result].isMember(jss::error) &&
670 jle[jss::result].isMember(jss::node) &&
671 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
672 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
673 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
674 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
675 jle[jss::result][jss::node][
"CredentialType"] ==
680 char const credType2[] =
"efghi";
682 testcase(
"CredentialsAccept fail, expired credentials.");
685 env.current()->header().parentCloseTime.time_since_epoch().count();
686 jv[sfExpiration.jsonName] = t;
697 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
698 jDelCred[jss::result].isMember(jss::error) &&
699 jDelCred[jss::result][jss::error] ==
"entryNotFound");
708 Env env{*
this, features};
710 env.fund(
XRP(5000), issuer, subject, other);
714 testcase(
"CredentialsAccept fail, issuer doesn't exist.");
720 int const delta = env.seq(issuer) + 255;
721 for (
int i = 0; i < delta; ++i)
723 auto const acctDelFee{
drops(env.current()->fees().increment)};
734 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
735 jDelCred[jss::result].isMember(jss::error) &&
736 jDelCred[jss::result][jss::error] ==
"entryNotFound");
744 using namespace test::jtx;
746 char const credType[] =
"abcde";
747 Account const issuer{
"issuer"};
748 Account const subject{
"subject"};
753 Env env{*
this, features};
755 env.fund(
XRP(5000), subject, issuer, other);
759 testcase(
"CredentialsDelete fail, no Credentials.");
765 testcase(
"CredentialsDelete fail, invalid Subject account.");
773 testcase(
"CredentialsDelete fail, invalid Issuer account.");
781 testcase(
"CredentialsDelete fail, invalid credentialType param.");
787 char const credType2[] =
"fghij";
800 jle.isObject() && jle.isMember(jss::result) &&
801 !jle[jss::result].isMember(jss::error) &&
802 jle[jss::result].isMember(jss::node) &&
803 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
804 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
805 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
806 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
807 jle[jss::result][jss::node][
"CredentialType"] ==
812 testcase(
"CredentialsDelete fail, time not expired yet.");
817 env.current()->header().parentCloseTime.time_since_epoch().count() + 1000;
818 jv[sfExpiration.jsonName] = t;
830 jle.isObject() && jle.isMember(jss::result) &&
831 !jle[jss::result].isMember(jss::error) &&
832 jle[jss::result].isMember(jss::node) &&
833 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
834 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
835 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
836 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
837 jle[jss::result][jss::node][
"CredentialType"] ==
842 testcase(
"CredentialsDelete fail, no Issuer and Subject.");
845 jv.removeMember(jss::Subject);
846 jv.removeMember(jss::Issuer);
852 testcase(
"CredentialsDelete fail, invalid fee.");
861 testcase(
"deleteSLE fail, bad SLE.");
898 using namespace test::jtx;
900 char const credType[] =
"abcde";
901 Account const issuer{
"issuer"};
902 Account const subject{
"subject"};
908 env.
fund(
XRP(5000), subject, issuer);
922 params[jss::account] = subject.human();
923 auto const jv = env.rpc(
"json",
"account_tx",
to_string(params))[jss::result];
925 BEAST_EXPECT(jv[jss::transactions].size() == 4);
926 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
927 BEAST_EXPECT(tx0[jss::TransactionType] == jss::CredentialAccept);
928 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
929 BEAST_EXPECT(tx1[jss::TransactionType] == jss::CredentialCreate);
930 txHash0 = tx0[jss::hash].asString();
931 txHash1 = tx1[jss::hash].asString();
936 params[jss::account] = issuer.human();
937 auto const jv = env.rpc(
"json",
"account_tx",
to_string(params))[jss::result];
939 BEAST_EXPECT(jv[jss::transactions].size() == 4);
940 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
941 BEAST_EXPECT(tx0[jss::TransactionType] == jss::CredentialAccept);
942 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
943 BEAST_EXPECT(tx1[jss::TransactionType] == jss::CredentialCreate);
945 BEAST_EXPECT(txHash0 == tx0[jss::hash].asString());
946 BEAST_EXPECT(txHash1 == tx1[jss::hash].asString());
953 params[jss::account] = subject.human();
954 auto jv = env.rpc(
"json",
"account_objects",
to_string(params))[jss::result];
956 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
957 auto const& object(jv[jss::account_objects][0u]);
959 BEAST_EXPECT(
object[
"LedgerEntryType"].asString() == jss::Credential);
960 objectIdx =
object[jss::index].asString();
965 params[jss::account] = issuer.human();
966 auto jv = env.rpc(
"json",
"account_objects",
to_string(params))[jss::result];
968 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
969 auto const& object(jv[jss::account_objects][0u]);
971 BEAST_EXPECT(
object[
"LedgerEntryType"].asString() == jss::Credential);
972 BEAST_EXPECT(objectIdx ==
object[jss::index].asString());