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) && !jle[jss::result].isMember(jss::error) &&
60 jle[jss::result].isMember(jss::node) && jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
61 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
62 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
63 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
72 auto const sleCred = env.le(credKey);
73 BEAST_EXPECT(
static_cast<bool>(sleCred));
77 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == subject.id());
78 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
81 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
82 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
83 BEAST_EXPECT(sleCred->getFieldU32(sfFlags) ==
lsfAccepted);
89 BEAST_EXPECT(!env.le(credKey));
96 jle.isObject() && jle.isMember(jss::result) && jle[jss::result].isMember(jss::error) &&
97 jle[jss::result][jss::error] ==
"entryNotFound");
109 auto const sleCred = env.le(credKey);
110 BEAST_EXPECT(
static_cast<bool>(sleCred));
114 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == issuer.id());
115 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.id());
116 BEAST_EXPECT((sleCred->getFieldU32(sfFlags) &
lsfAccepted));
117 BEAST_EXPECT(sleCred->getFieldU64(sfIssuerNode) == sleCred->getFieldU64(sfSubjectNode));
119 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
120 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
123 jle.isObject() && jle.isMember(jss::result) && !jle[jss::result].isMember(jss::error) &&
124 jle[jss::result].isMember(jss::node) && jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
125 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
126 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
127 jle[jss::result][jss::node][jss::Subject] == issuer.human() &&
134 BEAST_EXPECT(!env.le(credKey));
140 jle.isObject() && jle.isMember(jss::result) && jle[jss::result].isMember(jss::error) &&
141 jle[jss::result][jss::error] ==
"entryNotFound");
149 using namespace test::jtx;
151 char const credType[] =
"abcde";
153 Account const issuer{
"issuer"};
154 Account const subject{
"subject"};
157 Env env{*
this, features};
160 env.fund(
XRP(5000), issuer, subject, other);
164 testcase(
"Delete issuer before accept");
172 int const delta = env.seq(issuer) + 255;
173 for (
int i = 0; i < delta; ++i)
175 auto const acctDelFee{
drops(env.current()->fees().increment)};
182 BEAST_EXPECT(!env.le(credKey));
188 jle.isObject() && jle.isMember(jss::result) && jle[jss::result].isMember(jss::error) &&
189 jle[jss::result][jss::error] ==
"entryNotFound");
193 env.fund(
XRP(5000), issuer);
198 testcase(
"Delete issuer after accept");
208 int const delta = env.seq(issuer) + 255;
209 for (
int i = 0; i < delta; ++i)
211 auto const acctDelFee{
drops(env.current()->fees().increment)};
218 BEAST_EXPECT(!env.le(credKey));
224 jle.isObject() && jle.isMember(jss::result) && jle[jss::result].isMember(jss::error) &&
225 jle[jss::result][jss::error] ==
"entryNotFound");
229 env.fund(
XRP(5000), issuer);
234 testcase(
"Delete subject before accept");
242 int const delta = env.seq(subject) + 255;
243 for (
int i = 0; i < delta; ++i)
245 auto const acctDelFee{
drops(env.current()->fees().increment)};
252 BEAST_EXPECT(!env.le(credKey));
258 jle.isObject() && jle.isMember(jss::result) && jle[jss::result].isMember(jss::error) &&
259 jle[jss::result][jss::error] ==
"entryNotFound");
263 env.fund(
XRP(5000), subject);
268 testcase(
"Delete subject after accept");
278 int const delta = env.seq(subject) + 255;
279 for (
int i = 0; i < delta; ++i)
281 auto const acctDelFee{
drops(env.current()->fees().increment)};
288 BEAST_EXPECT(!env.le(credKey));
294 jle.isObject() && jle.isMember(jss::result) && jle[jss::result].isMember(jss::error) &&
295 jle[jss::result][jss::error] ==
"entryNotFound");
299 env.fund(
XRP(5000), subject);
308 uint32_t
const t = env.current()->header().parentCloseTime.time_since_epoch().count();
309 jv[sfExpiration.jsonName] = t + 20;
323 BEAST_EXPECT(!env.le(credKey));
330 jle.isObject() && jle.isMember(jss::result) && jle[jss::result].isMember(jss::error) &&
331 jle[jss::result][jss::error] ==
"entryNotFound");
346 BEAST_EXPECT(!env.le(credKey));
351 jle.isObject() && jle.isMember(jss::result) && jle[jss::result].isMember(jss::error) &&
352 jle[jss::result][jss::error] ==
"entryNotFound");
365 BEAST_EXPECT(!env.le(credKey));
370 jle.isObject() && jle.isMember(jss::result) && jle[jss::result].isMember(jss::error) &&
371 jle[jss::result][jss::error] ==
"entryNotFound");
379 using namespace test::jtx;
381 char const credType[] =
"abcde";
383 Account const issuer{
"issuer"};
384 Account const subject{
"subject"};
388 Env env{*
this, features};
390 env.fund(
XRP(5000), subject, issuer);
394 testcase(
"Credentials fail, no subject param.");
396 jv.removeMember(jss::Subject);
407 testcase(
"Credentials fail, no credentialType param.");
409 jv.removeMember(sfCredentialType.jsonName);
414 testcase(
"Credentials fail, empty credentialType param.");
421 "Credentials fail, credentialType length > "
422 "maxCredentialTypeLength.");
424 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
425 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p";
432 testcase(
"Credentials fail, URI length > 256.");
434 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
435 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p "
436 "9hfup;wDJFBVSD8f72 "
438 "djvbldafghwpEFHdjfaidfgio84763tfysgdvhjasbd "
439 "vujhgWQIE7F6WEUYFGWUKEYFVQW87FGWOEFWEFUYWVEF8723GFWEFB"
441 "fv28o37gfwEFB3872TFO8GSDSDVD";
447 testcase(
"Credentials fail, URI empty.");
452 testcase(
"Credentials fail, expiration in the past.");
455 uint32_t
const t = env.current()->header().parentCloseTime.time_since_epoch().count() - 1;
456 jv[sfExpiration.jsonName] = t;
461 testcase(
"Credentials fail, invalid fee.");
469 testcase(
"Credentials fail, duplicate.");
479 jle.isObject() && jle.isMember(jss::result) && !jle[jss::result].isMember(jss::error) &&
480 jle[jss::result].isMember(jss::node) && jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
481 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
482 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
483 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
488 testcase(
"Credentials fail, directory full");
517 Env env{*
this, features};
519 env.fund(
XRP(5000), issuer);
523 testcase(
"Credentials fail, subject doesn't exist.");
531 Env env{*
this, features};
533 auto const reserve =
drops(env.current()->fees().reserve);
534 env.fund(
reserve, subject, issuer);
537 testcase(
"Credentials fail, not enough reserve.");
551 char const credType[] =
"abcde";
552 Account const issuer{
"issuer"};
553 Account const subject{
"subject"};
557 Env env{*
this, features};
559 env.fund(
XRP(5000), subject, issuer);
562 testcase(
"CredentialsAccept fail, Credential doesn't exist.");
568 testcase(
"CredentialsAccept fail, invalid Issuer account.");
576 testcase(
"CredentialsAccept fail, invalid credentialType param.");
583 Env env{*
this, features};
585 env.fund(
drops(env.current()->fees().accountReserve(1)), issuer);
586 env.fund(
drops(env.current()->fees().accountReserve(0)), subject);
590 testcase(
"CredentialsAccept fail, not enough reserve.");
600 jle.isObject() && jle.isMember(jss::result) && !jle[jss::result].isMember(jss::error) &&
601 jle[jss::result].isMember(jss::node) && jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
602 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
603 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
604 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
611 Env env{*
this, features};
613 env.fund(
XRP(5000), subject, issuer);
620 testcase(
"CredentialsAccept fail, invalid fee.");
625 testcase(
"CredentialsAccept fail, lsfAccepted already set.");
634 jle.isObject() && jle.isMember(jss::result) && !jle[jss::result].isMember(jss::error) &&
635 jle[jss::result].isMember(jss::node) && jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
636 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
637 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
638 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
643 char const credType2[] =
"efghi";
645 testcase(
"CredentialsAccept fail, expired credentials.");
647 uint32_t
const t = env.current()->header().parentCloseTime.time_since_epoch().count();
648 jv[sfExpiration.jsonName] = t;
659 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
660 jDelCred[jss::result].isMember(jss::error) && jDelCred[jss::result][jss::error] ==
"entryNotFound");
669 Env env{*
this, features};
671 env.fund(
XRP(5000), issuer, subject, other);
675 testcase(
"CredentialsAccept fail, issuer doesn't exist.");
681 int const delta = env.seq(issuer) + 255;
682 for (
int i = 0; i < delta; ++i)
684 auto const acctDelFee{
drops(env.current()->fees().increment)};
695 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
696 jDelCred[jss::result].isMember(jss::error) && jDelCred[jss::result][jss::error] ==
"entryNotFound");
704 using namespace test::jtx;
706 char const credType[] =
"abcde";
707 Account const issuer{
"issuer"};
708 Account const subject{
"subject"};
713 Env env{*
this, features};
715 env.fund(
XRP(5000), subject, issuer, other);
719 testcase(
"CredentialsDelete fail, no Credentials.");
725 testcase(
"CredentialsDelete fail, invalid Subject account.");
733 testcase(
"CredentialsDelete fail, invalid Issuer account.");
741 testcase(
"CredentialsDelete fail, invalid credentialType param.");
747 char const credType2[] =
"fghij";
759 jle.isObject() && jle.isMember(jss::result) && !jle[jss::result].isMember(jss::error) &&
760 jle[jss::result].isMember(jss::node) && jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
761 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
762 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
763 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
768 testcase(
"CredentialsDelete fail, time not expired yet.");
772 uint32_t
const t = env.current()->header().parentCloseTime.time_since_epoch().count() + 1000;
773 jv[sfExpiration.jsonName] = t;
784 jle.isObject() && jle.isMember(jss::result) && !jle[jss::result].isMember(jss::error) &&
785 jle[jss::result].isMember(jss::node) && jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
786 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
787 jle[jss::result][jss::node][jss::Issuer] == issuer.human() &&
788 jle[jss::result][jss::node][jss::Subject] == subject.human() &&
793 testcase(
"CredentialsDelete fail, no Issuer and Subject.");
796 jv.removeMember(jss::Subject);
797 jv.removeMember(jss::Issuer);
803 testcase(
"CredentialsDelete fail, invalid fee.");
812 testcase(
"deleteSLE fail, bad SLE.");
848 using namespace test::jtx;
850 char const credType[] =
"abcde";
851 Account const issuer{
"issuer"};
852 Account const subject{
"subject"};
858 env.
fund(
XRP(5000), subject, issuer);
872 params[jss::account] = subject.human();
873 auto const jv = env.rpc(
"json",
"account_tx",
to_string(params))[jss::result];
875 BEAST_EXPECT(jv[jss::transactions].size() == 4);
876 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
877 BEAST_EXPECT(tx0[jss::TransactionType] == jss::CredentialAccept);
878 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
879 BEAST_EXPECT(tx1[jss::TransactionType] == jss::CredentialCreate);
880 txHash0 = tx0[jss::hash].asString();
881 txHash1 = tx1[jss::hash].asString();
886 params[jss::account] = issuer.human();
887 auto const jv = env.rpc(
"json",
"account_tx",
to_string(params))[jss::result];
889 BEAST_EXPECT(jv[jss::transactions].size() == 4);
890 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
891 BEAST_EXPECT(tx0[jss::TransactionType] == jss::CredentialAccept);
892 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
893 BEAST_EXPECT(tx1[jss::TransactionType] == jss::CredentialCreate);
895 BEAST_EXPECT(txHash0 == tx0[jss::hash].asString());
896 BEAST_EXPECT(txHash1 == tx1[jss::hash].asString());
903 params[jss::account] = subject.human();
904 auto jv = env.rpc(
"json",
"account_objects",
to_string(params))[jss::result];
906 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
907 auto const& object(jv[jss::account_objects][0u]);
909 BEAST_EXPECT(
object[
"LedgerEntryType"].asString() == jss::Credential);
910 objectIdx =
object[jss::index].asString();
915 params[jss::account] = issuer.human();
916 auto jv = env.rpc(
"json",
"account_objects",
to_string(params))[jss::result];
918 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
919 auto const& object(jv[jss::account_objects][0u]);
921 BEAST_EXPECT(
object[
"LedgerEntryType"].asString() == jss::Credential);
922 BEAST_EXPECT(objectIdx ==
object[jss::index].asString());