rippled
Loading...
Searching...
No Matches
MPTokenIssuanceCreateTests.cpp
1// Auto-generated unit tests for transaction MPTokenIssuanceCreate
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/MPTokenIssuanceCreate.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(TransactionsMPTokenIssuanceCreateTests, BuilderSettersRoundTrip)
21{
22 // Generate a deterministic keypair for signing
23 auto const [publicKey, secretKey] =
24 generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceCreate"));
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 assetScaleValue = canonical_UINT8();
33 auto const transferFeeValue = canonical_UINT16();
34 auto const maximumAmountValue = canonical_UINT64();
35 auto const mPTokenMetadataValue = canonical_VL();
36 auto const domainIDValue = canonical_UINT256();
37 auto const mutableFlagsValue = canonical_UINT32();
38
40 accountValue,
41 sequenceValue,
42 feeValue
43 };
44
45 // Set optional fields
46 builder.setAssetScale(assetScaleValue);
47 builder.setTransferFee(transferFeeValue);
48 builder.setMaximumAmount(maximumAmountValue);
49 builder.setMPTokenMetadata(mPTokenMetadataValue);
50 builder.setDomainID(domainIDValue);
51 builder.setMutableFlags(mutableFlagsValue);
52
53 auto tx = builder.build(publicKey, secretKey);
54
55 std::string reason;
56 EXPECT_TRUE(tx.validate(reason)) << reason;
57
58 // Verify signing was applied
59 EXPECT_FALSE(tx.getSigningPubKey().empty());
60 EXPECT_TRUE(tx.hasTxnSignature());
61
62 // Verify common fields
63 EXPECT_EQ(tx.getAccount(), accountValue);
64 EXPECT_EQ(tx.getSequence(), sequenceValue);
65 EXPECT_EQ(tx.getFee(), feeValue);
66
67 // Verify required fields
68 // Verify optional fields
69 {
70 auto const& expected = assetScaleValue;
71 auto const actualOpt = tx.getAssetScale();
72 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetScale should be present";
73 expectEqualField(expected, *actualOpt, "sfAssetScale");
74 EXPECT_TRUE(tx.hasAssetScale());
75 }
76
77 {
78 auto const& expected = transferFeeValue;
79 auto const actualOpt = tx.getTransferFee();
80 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present";
81 expectEqualField(expected, *actualOpt, "sfTransferFee");
82 EXPECT_TRUE(tx.hasTransferFee());
83 }
84
85 {
86 auto const& expected = maximumAmountValue;
87 auto const actualOpt = tx.getMaximumAmount();
88 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMaximumAmount should be present";
89 expectEqualField(expected, *actualOpt, "sfMaximumAmount");
90 EXPECT_TRUE(tx.hasMaximumAmount());
91 }
92
93 {
94 auto const& expected = mPTokenMetadataValue;
95 auto const actualOpt = tx.getMPTokenMetadata();
96 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present";
97 expectEqualField(expected, *actualOpt, "sfMPTokenMetadata");
98 EXPECT_TRUE(tx.hasMPTokenMetadata());
99 }
100
101 {
102 auto const& expected = domainIDValue;
103 auto const actualOpt = tx.getDomainID();
104 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present";
105 expectEqualField(expected, *actualOpt, "sfDomainID");
106 EXPECT_TRUE(tx.hasDomainID());
107 }
108
109 {
110 auto const& expected = mutableFlagsValue;
111 auto const actualOpt = tx.getMutableFlags();
112 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMutableFlags should be present";
113 expectEqualField(expected, *actualOpt, "sfMutableFlags");
114 EXPECT_TRUE(tx.hasMutableFlags());
115 }
116
117}
118
119// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper,
120// and verify all fields match.
121TEST(TransactionsMPTokenIssuanceCreateTests, BuilderFromStTxRoundTrip)
122{
123 // Generate a deterministic keypair for signing
124 auto const [publicKey, secretKey] =
125 generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceCreateFromTx"));
126
127 // Common transaction fields
128 auto const accountValue = calcAccountID(publicKey);
129 std::uint32_t const sequenceValue = 2;
130 auto const feeValue = canonical_AMOUNT();
131
132 // Transaction-specific field values
133 auto const assetScaleValue = canonical_UINT8();
134 auto const transferFeeValue = canonical_UINT16();
135 auto const maximumAmountValue = canonical_UINT64();
136 auto const mPTokenMetadataValue = canonical_VL();
137 auto const domainIDValue = canonical_UINT256();
138 auto const mutableFlagsValue = canonical_UINT32();
139
140 // Build an initial transaction
141 MPTokenIssuanceCreateBuilder initialBuilder{
142 accountValue,
143 sequenceValue,
144 feeValue
145 };
146
147 initialBuilder.setAssetScale(assetScaleValue);
148 initialBuilder.setTransferFee(transferFeeValue);
149 initialBuilder.setMaximumAmount(maximumAmountValue);
150 initialBuilder.setMPTokenMetadata(mPTokenMetadataValue);
151 initialBuilder.setDomainID(domainIDValue);
152 initialBuilder.setMutableFlags(mutableFlagsValue);
153
154 auto initialTx = initialBuilder.build(publicKey, secretKey);
155
156 // Create builder from existing STTx
157 MPTokenIssuanceCreateBuilder builderFromTx{initialTx.getSTTx()};
158
159 auto rebuiltTx = builderFromTx.build(publicKey, secretKey);
160
161 std::string reason;
162 EXPECT_TRUE(rebuiltTx.validate(reason)) << reason;
163
164 // Verify common fields
165 EXPECT_EQ(rebuiltTx.getAccount(), accountValue);
166 EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue);
167 EXPECT_EQ(rebuiltTx.getFee(), feeValue);
168
169 // Verify required fields
170 // Verify optional fields
171 {
172 auto const& expected = assetScaleValue;
173 auto const actualOpt = rebuiltTx.getAssetScale();
174 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetScale should be present";
175 expectEqualField(expected, *actualOpt, "sfAssetScale");
176 }
177
178 {
179 auto const& expected = transferFeeValue;
180 auto const actualOpt = rebuiltTx.getTransferFee();
181 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present";
182 expectEqualField(expected, *actualOpt, "sfTransferFee");
183 }
184
185 {
186 auto const& expected = maximumAmountValue;
187 auto const actualOpt = rebuiltTx.getMaximumAmount();
188 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMaximumAmount should be present";
189 expectEqualField(expected, *actualOpt, "sfMaximumAmount");
190 }
191
192 {
193 auto const& expected = mPTokenMetadataValue;
194 auto const actualOpt = rebuiltTx.getMPTokenMetadata();
195 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present";
196 expectEqualField(expected, *actualOpt, "sfMPTokenMetadata");
197 }
198
199 {
200 auto const& expected = domainIDValue;
201 auto const actualOpt = rebuiltTx.getDomainID();
202 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present";
203 expectEqualField(expected, *actualOpt, "sfDomainID");
204 }
205
206 {
207 auto const& expected = mutableFlagsValue;
208 auto const actualOpt = rebuiltTx.getMutableFlags();
209 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMutableFlags should be present";
210 expectEqualField(expected, *actualOpt, "sfMutableFlags");
211 }
212
213}
214
215// 3) Verify wrapper throws when constructed from wrong transaction type.
216TEST(TransactionsMPTokenIssuanceCreateTests, WrapperThrowsOnWrongTxType)
217{
218 // Build a valid transaction of a different type
219 auto const [pk, sk] =
221 auto const account = calcAccountID(pk);
222
223 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
224 auto wrongTx = wrongBuilder.build(pk, sk);
225
226 EXPECT_THROW(MPTokenIssuanceCreate{wrongTx.getSTTx()}, std::runtime_error);
227}
228
229// 4) Verify builder throws when constructed from wrong transaction type.
230TEST(TransactionsMPTokenIssuanceCreateTests, BuilderThrowsOnWrongTxType)
231{
232 // Build a valid transaction of a different type
233 auto const [pk, sk] =
234 generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder"));
235 auto const account = calcAccountID(pk);
236
237 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
238 auto wrongTx = wrongBuilder.build(pk, sk);
239
240 EXPECT_THROW(MPTokenIssuanceCreateBuilder{wrongTx.getSTTx()}, std::runtime_error);
241}
242
243// 5) Build with only required fields and verify optional fields return nullopt.
244TEST(TransactionsMPTokenIssuanceCreateTests, OptionalFieldsReturnNullopt)
245{
246 // Generate a deterministic keypair for signing
247 auto const [publicKey, secretKey] =
248 generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceCreateNullopt"));
249
250 // Common transaction fields
251 auto const accountValue = calcAccountID(publicKey);
252 std::uint32_t const sequenceValue = 3;
253 auto const feeValue = canonical_AMOUNT();
254
255 // Transaction-specific required field values
256
258 accountValue,
259 sequenceValue,
260 feeValue
261 };
262
263 // Do NOT set optional fields
264
265 auto tx = builder.build(publicKey, secretKey);
266
267 // Verify optional fields are not present
268 EXPECT_FALSE(tx.hasAssetScale());
269 EXPECT_FALSE(tx.getAssetScale().has_value());
270 EXPECT_FALSE(tx.hasTransferFee());
271 EXPECT_FALSE(tx.getTransferFee().has_value());
272 EXPECT_FALSE(tx.hasMaximumAmount());
273 EXPECT_FALSE(tx.getMaximumAmount().has_value());
274 EXPECT_FALSE(tx.hasMPTokenMetadata());
275 EXPECT_FALSE(tx.getMPTokenMetadata().has_value());
276 EXPECT_FALSE(tx.hasDomainID());
277 EXPECT_FALSE(tx.getDomainID().has_value());
278 EXPECT_FALSE(tx.hasMutableFlags());
279 EXPECT_FALSE(tx.getMutableFlags().has_value());
280}
281
282}
MPTokenIssuanceCreate build(PublicKey const &publicKey, SecretKey const &secretKey)
Build and return the MPTokenIssuanceCreate wrapper.
std::shared_ptr< STTx const > getSTTx() const
Get the underlying STTx object.
TEST(TransactionsAccountDeleteTests, BuilderSettersRoundTrip)
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition Seed.cpp:57
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)