xrpld
Loading...
Searching...
No Matches
MPTokenIssuanceSetTests.cpp
1// Auto-generated unit tests for transaction MPTokenIssuanceSet
2
3
4#include <gtest/gtest.h>
5
6#include <protocol_autogen/TestHelpers.h>
7
8#include <xrpl/protocol/SecretKey.h>
9#include <xrpl/protocol/Seed.h>
10#include <xrpl/protocol/STTx.h>
11#include <xrpl/protocol_autogen/transactions/MPTokenIssuanceSet.h>
12#include <xrpl/protocol_autogen/transactions/AccountSet.h>
13
14#include <string>
15
16namespace xrpl::transactions {
17
18// 1 & 4) Set fields via builder setters, build, then read them back via
19// wrapper getters. After build(), validate() should succeed.
20TEST(TransactionsMPTokenIssuanceSetTests, BuilderSettersRoundTrip)
21{
22 // Generate a deterministic keypair for signing
23 auto const [publicKey, secretKey] =
24 generateKeyPair(KeyType::Secp256k1, generateSeed("testMPTokenIssuanceSet"));
25
26 // Common transaction fields
27 auto const accountValue = calcAccountID(publicKey);
28 std::uint32_t const sequenceValue = 1;
29 auto const feeValue = canonical_AMOUNT();
30
31 // Transaction-specific field values
32 auto const mPTokenIssuanceIDValue = canonical_UINT192();
33 auto const holderValue = canonical_ACCOUNT();
34 auto const domainIDValue = canonical_UINT256();
35 auto const mPTokenMetadataValue = canonical_VL();
36 auto const transferFeeValue = canonical_UINT16();
37 auto const mutableFlagsValue = canonical_UINT32();
38 auto const issuerEncryptionKeyValue = canonical_VL();
39 auto const auditorEncryptionKeyValue = canonical_VL();
40
42 accountValue,
43 mPTokenIssuanceIDValue,
44 sequenceValue,
45 feeValue
46 };
47
48 // Set optional fields
49 builder.setHolder(holderValue);
50 builder.setDomainID(domainIDValue);
51 builder.setMPTokenMetadata(mPTokenMetadataValue);
52 builder.setTransferFee(transferFeeValue);
53 builder.setMutableFlags(mutableFlagsValue);
54 builder.setIssuerEncryptionKey(issuerEncryptionKeyValue);
55 builder.setAuditorEncryptionKey(auditorEncryptionKeyValue);
56
57 auto tx = builder.build(publicKey, secretKey);
58
59 std::string reason;
60 EXPECT_TRUE(tx.validate(reason)) << reason;
61
62 // Verify signing was applied
63 EXPECT_FALSE(tx.getSigningPubKey().empty());
64 EXPECT_TRUE(tx.hasTxnSignature());
65
66 // Verify common fields
67 EXPECT_EQ(tx.getAccount(), accountValue);
68 EXPECT_EQ(tx.getSequence(), sequenceValue);
69 EXPECT_EQ(tx.getFee(), feeValue);
70
71 // Verify required fields
72 {
73 auto const& expected = mPTokenIssuanceIDValue;
74 auto const actual = tx.getMPTokenIssuanceID();
75 expectEqualField(expected, actual, "sfMPTokenIssuanceID");
76 }
77
78 // Verify optional fields
79 {
80 auto const& expected = holderValue;
81 auto const actualOpt = tx.getHolder();
82 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolder should be present";
83 expectEqualField(expected, *actualOpt, "sfHolder");
84 EXPECT_TRUE(tx.hasHolder());
85 }
86
87 {
88 auto const& expected = domainIDValue;
89 auto const actualOpt = tx.getDomainID();
90 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present";
91 expectEqualField(expected, *actualOpt, "sfDomainID");
92 EXPECT_TRUE(tx.hasDomainID());
93 }
94
95 {
96 auto const& expected = mPTokenMetadataValue;
97 auto const actualOpt = tx.getMPTokenMetadata();
98 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present";
99 expectEqualField(expected, *actualOpt, "sfMPTokenMetadata");
100 EXPECT_TRUE(tx.hasMPTokenMetadata());
101 }
102
103 {
104 auto const& expected = transferFeeValue;
105 auto const actualOpt = tx.getTransferFee();
106 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present";
107 expectEqualField(expected, *actualOpt, "sfTransferFee");
108 EXPECT_TRUE(tx.hasTransferFee());
109 }
110
111 {
112 auto const& expected = mutableFlagsValue;
113 auto const actualOpt = tx.getMutableFlags();
114 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMutableFlags should be present";
115 expectEqualField(expected, *actualOpt, "sfMutableFlags");
116 EXPECT_TRUE(tx.hasMutableFlags());
117 }
118
119 {
120 auto const& expected = issuerEncryptionKeyValue;
121 auto const actualOpt = tx.getIssuerEncryptionKey();
122 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfIssuerEncryptionKey should be present";
123 expectEqualField(expected, *actualOpt, "sfIssuerEncryptionKey");
124 EXPECT_TRUE(tx.hasIssuerEncryptionKey());
125 }
126
127 {
128 auto const& expected = auditorEncryptionKeyValue;
129 auto const actualOpt = tx.getAuditorEncryptionKey();
130 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuditorEncryptionKey should be present";
131 expectEqualField(expected, *actualOpt, "sfAuditorEncryptionKey");
132 EXPECT_TRUE(tx.hasAuditorEncryptionKey());
133 }
134
135}
136
137// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper,
138// and verify all fields match.
139TEST(TransactionsMPTokenIssuanceSetTests, BuilderFromStTxRoundTrip)
140{
141 // Generate a deterministic keypair for signing
142 auto const [publicKey, secretKey] =
143 generateKeyPair(KeyType::Secp256k1, generateSeed("testMPTokenIssuanceSetFromTx"));
144
145 // Common transaction fields
146 auto const accountValue = calcAccountID(publicKey);
147 std::uint32_t const sequenceValue = 2;
148 auto const feeValue = canonical_AMOUNT();
149
150 // Transaction-specific field values
151 auto const mPTokenIssuanceIDValue = canonical_UINT192();
152 auto const holderValue = canonical_ACCOUNT();
153 auto const domainIDValue = canonical_UINT256();
154 auto const mPTokenMetadataValue = canonical_VL();
155 auto const transferFeeValue = canonical_UINT16();
156 auto const mutableFlagsValue = canonical_UINT32();
157 auto const issuerEncryptionKeyValue = canonical_VL();
158 auto const auditorEncryptionKeyValue = canonical_VL();
159
160 // Build an initial transaction
161 MPTokenIssuanceSetBuilder initialBuilder{
162 accountValue,
163 mPTokenIssuanceIDValue,
164 sequenceValue,
165 feeValue
166 };
167
168 initialBuilder.setHolder(holderValue);
169 initialBuilder.setDomainID(domainIDValue);
170 initialBuilder.setMPTokenMetadata(mPTokenMetadataValue);
171 initialBuilder.setTransferFee(transferFeeValue);
172 initialBuilder.setMutableFlags(mutableFlagsValue);
173 initialBuilder.setIssuerEncryptionKey(issuerEncryptionKeyValue);
174 initialBuilder.setAuditorEncryptionKey(auditorEncryptionKeyValue);
175
176 auto initialTx = initialBuilder.build(publicKey, secretKey);
177
178 // Create builder from existing STTx
179 MPTokenIssuanceSetBuilder builderFromTx{initialTx.getSTTx()};
180
181 auto rebuiltTx = builderFromTx.build(publicKey, secretKey);
182
183 std::string reason;
184 EXPECT_TRUE(rebuiltTx.validate(reason)) << reason;
185
186 // Verify common fields
187 EXPECT_EQ(rebuiltTx.getAccount(), accountValue);
188 EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue);
189 EXPECT_EQ(rebuiltTx.getFee(), feeValue);
190
191 // Verify required fields
192 {
193 auto const& expected = mPTokenIssuanceIDValue;
194 auto const actual = rebuiltTx.getMPTokenIssuanceID();
195 expectEqualField(expected, actual, "sfMPTokenIssuanceID");
196 }
197
198 // Verify optional fields
199 {
200 auto const& expected = holderValue;
201 auto const actualOpt = rebuiltTx.getHolder();
202 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolder should be present";
203 expectEqualField(expected, *actualOpt, "sfHolder");
204 }
205
206 {
207 auto const& expected = domainIDValue;
208 auto const actualOpt = rebuiltTx.getDomainID();
209 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present";
210 expectEqualField(expected, *actualOpt, "sfDomainID");
211 }
212
213 {
214 auto const& expected = mPTokenMetadataValue;
215 auto const actualOpt = rebuiltTx.getMPTokenMetadata();
216 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present";
217 expectEqualField(expected, *actualOpt, "sfMPTokenMetadata");
218 }
219
220 {
221 auto const& expected = transferFeeValue;
222 auto const actualOpt = rebuiltTx.getTransferFee();
223 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present";
224 expectEqualField(expected, *actualOpt, "sfTransferFee");
225 }
226
227 {
228 auto const& expected = mutableFlagsValue;
229 auto const actualOpt = rebuiltTx.getMutableFlags();
230 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMutableFlags should be present";
231 expectEqualField(expected, *actualOpt, "sfMutableFlags");
232 }
233
234 {
235 auto const& expected = issuerEncryptionKeyValue;
236 auto const actualOpt = rebuiltTx.getIssuerEncryptionKey();
237 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfIssuerEncryptionKey should be present";
238 expectEqualField(expected, *actualOpt, "sfIssuerEncryptionKey");
239 }
240
241 {
242 auto const& expected = auditorEncryptionKeyValue;
243 auto const actualOpt = rebuiltTx.getAuditorEncryptionKey();
244 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuditorEncryptionKey should be present";
245 expectEqualField(expected, *actualOpt, "sfAuditorEncryptionKey");
246 }
247
248}
249
250// 3) Verify wrapper throws when constructed from wrong transaction type.
251TEST(TransactionsMPTokenIssuanceSetTests, WrapperThrowsOnWrongTxType)
252{
253 // Build a valid transaction of a different type
254 auto const [pk, sk] =
256 auto const account = calcAccountID(pk);
257
258 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
259 auto wrongTx = wrongBuilder.build(pk, sk);
260
261 EXPECT_THROW(MPTokenIssuanceSet{wrongTx.getSTTx()}, std::runtime_error);
262}
263
264// 4) Verify builder throws when constructed from wrong transaction type.
265TEST(TransactionsMPTokenIssuanceSetTests, BuilderThrowsOnWrongTxType)
266{
267 // Build a valid transaction of a different type
268 auto const [pk, sk] =
269 generateKeyPair(KeyType::Secp256k1, generateSeed("testWrongTypeBuilder"));
270 auto const account = calcAccountID(pk);
271
272 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
273 auto wrongTx = wrongBuilder.build(pk, sk);
274
275 EXPECT_THROW(MPTokenIssuanceSetBuilder{wrongTx.getSTTx()}, std::runtime_error);
276}
277
278// 5) Build with only required fields and verify optional fields return nullopt.
279TEST(TransactionsMPTokenIssuanceSetTests, OptionalFieldsReturnNullopt)
280{
281 // Generate a deterministic keypair for signing
282 auto const [publicKey, secretKey] =
283 generateKeyPair(KeyType::Secp256k1, generateSeed("testMPTokenIssuanceSetNullopt"));
284
285 // Common transaction fields
286 auto const accountValue = calcAccountID(publicKey);
287 std::uint32_t const sequenceValue = 3;
288 auto const feeValue = canonical_AMOUNT();
289
290 // Transaction-specific required field values
291 auto const mPTokenIssuanceIDValue = canonical_UINT192();
292
294 accountValue,
295 mPTokenIssuanceIDValue,
296 sequenceValue,
297 feeValue
298 };
299
300 // Do NOT set optional fields
301
302 auto tx = builder.build(publicKey, secretKey);
303
304 // Verify optional fields are not present
305 EXPECT_FALSE(tx.hasHolder());
306 EXPECT_FALSE(tx.getHolder().has_value());
307 EXPECT_FALSE(tx.hasDomainID());
308 EXPECT_FALSE(tx.getDomainID().has_value());
309 EXPECT_FALSE(tx.hasMPTokenMetadata());
310 EXPECT_FALSE(tx.getMPTokenMetadata().has_value());
311 EXPECT_FALSE(tx.hasTransferFee());
312 EXPECT_FALSE(tx.getTransferFee().has_value());
313 EXPECT_FALSE(tx.hasMutableFlags());
314 EXPECT_FALSE(tx.getMutableFlags().has_value());
315 EXPECT_FALSE(tx.hasIssuerEncryptionKey());
316 EXPECT_FALSE(tx.getIssuerEncryptionKey().has_value());
317 EXPECT_FALSE(tx.hasAuditorEncryptionKey());
318 EXPECT_FALSE(tx.getAuditorEncryptionKey().has_value());
319}
320
321}
AccountSet build(PublicKey const &publicKey, SecretKey const &secretKey)
Build and return the AccountSet wrapper.
MPTokenIssuanceSetBuilder & setIssuerEncryptionKey(std::decay_t< typename SF_VL::type::value_type > const &value)
Set sfIssuerEncryptionKey (SoeOptional).
MPTokenIssuanceSetBuilder & setMPTokenMetadata(std::decay_t< typename SF_VL::type::value_type > const &value)
Set sfMPTokenMetadata (SoeOptional).
MPTokenIssuanceSetBuilder & setMutableFlags(std::decay_t< typename SF_UINT32::type::value_type > const &value)
Set sfMutableFlags (SoeOptional).
MPTokenIssuanceSetBuilder & setAuditorEncryptionKey(std::decay_t< typename SF_VL::type::value_type > const &value)
Set sfAuditorEncryptionKey (SoeOptional).
MPTokenIssuanceSetBuilder & setHolder(std::decay_t< typename SF_ACCOUNT::type::value_type > const &value)
Set sfHolder (SoeOptional).
MPTokenIssuanceSet build(PublicKey const &publicKey, SecretKey const &secretKey)
Build and return the MPTokenIssuanceSet wrapper.
MPTokenIssuanceSetBuilder & setTransferFee(std::decay_t< typename SF_UINT16::type::value_type > const &value)
Set sfTransferFee (SoeOptional).
MPTokenIssuanceSetBuilder & setDomainID(std::decay_t< typename SF_UINT256::type::value_type > const &value)
Set sfDomainID (SoeOptional).
TEST(TransactionsAccountDeleteTests, BuilderSettersRoundTrip)
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition Seed.cpp:58
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
AccountID calcAccountID(PublicKey const &pk)
void expectEqualField(T const &expected, T const &actual, char const *fieldName)