Skip to content

Commit ea3dcea

Browse files
committed
remove extra blank lines, added test coverage for DefaultDefinitionsProvider, added javadoc
1 parent bd1b597 commit ea3dcea

File tree

3 files changed

+203
-2
lines changed

3 files changed

+203
-2
lines changed

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/definitions/DefaultDefinitionsProvider.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131
import java.util.Map;
3232
import java.util.Objects;
3333

34+
/**
35+
* Default implementation of the {@link DefinitionsProvider} interface. This class is responsible for loading and
36+
* providing {@link Definitions} data from a JSON file, while also programmatically generating additional permission
37+
* values based on the loaded data.
38+
*
39+
* The definitions file is expected to be located at '/definitions.json' as a resource, and is parsed using the
40+
* specified {@link ObjectMapper}. Lazily initializes and memoizes the loaded {@link Definitions} data for improved
41+
* performance.
42+
*/
3443
public class DefaultDefinitionsProvider implements DefinitionsProvider {
3544

3645
private final Supplier<Definitions> supplier;
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package org.xrpl.xrpl4j.codec.binary.definitions;
2+
3+
/*-
4+
* ========================LICENSE_START=================================
5+
* xrpl4j :: binary-codec
6+
* %%
7+
* Copyright (C) 2020 - 2022 XRPL Foundation and its contributors
8+
* %%
9+
* Licensed under the Apache License, Version 2.0 (the "License");
10+
* you may not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS,
17+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
* =========================LICENSE_END==================================
21+
*/
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
25+
import com.fasterxml.jackson.databind.ObjectMapper;
26+
import org.junit.jupiter.api.BeforeEach;
27+
import org.junit.jupiter.api.Test;
28+
import org.xrpl.xrpl4j.model.jackson.ObjectMapperFactory;
29+
import org.xrpl.xrpl4j.model.transactions.GranularPermission;
30+
31+
import java.util.Map;
32+
33+
/**
34+
* Unit test for {@link DefaultDefinitionsProvider}.
35+
*/
36+
class DefaultDefinitionsProviderTest {
37+
38+
private DefaultDefinitionsProvider provider;
39+
private Definitions definitions;
40+
41+
@BeforeEach
42+
void setUp() {
43+
ObjectMapper objectMapper = ObjectMapperFactory.create();
44+
provider = new DefaultDefinitionsProvider(objectMapper);
45+
definitions = provider.get();
46+
}
47+
48+
@Test
49+
void getReturnsDefinitions() {
50+
assertThat(definitions).isNotNull();
51+
assertThat(definitions.types()).isNotEmpty();
52+
assertThat(definitions.fields()).isNotEmpty();
53+
assertThat(definitions.ledgerEntryTypes()).isNotEmpty();
54+
assertThat(definitions.transactionTypes()).isNotEmpty();
55+
assertThat(definitions.transactionResults()).isNotEmpty();
56+
assertThat(definitions.permissionValues()).isNotEmpty();
57+
}
58+
59+
@Test
60+
void permissionValuesContainsAllGranularPermissions() {
61+
Map<String, Integer> permissionValues = definitions.permissionValues();
62+
63+
// Verify all granular permissions are present with correct values
64+
assertThat(permissionValues).containsEntry("TrustlineAuthorize", 65537);
65+
assertThat(permissionValues).containsEntry("TrustlineFreeze", 65538);
66+
assertThat(permissionValues).containsEntry("TrustlineUnfreeze", 65539);
67+
assertThat(permissionValues).containsEntry("AccountDomainSet", 65540);
68+
assertThat(permissionValues).containsEntry("AccountEmailHashSet", 65541);
69+
assertThat(permissionValues).containsEntry("AccountMessageKeySet", 65542);
70+
assertThat(permissionValues).containsEntry("AccountTransferRateSet", 65543);
71+
assertThat(permissionValues).containsEntry("AccountTickSizeSet", 65544);
72+
assertThat(permissionValues).containsEntry("PaymentMint", 65545);
73+
assertThat(permissionValues).containsEntry("PaymentBurn", 65546);
74+
assertThat(permissionValues).containsEntry("MPTokenIssuanceLock", 65547);
75+
assertThat(permissionValues).containsEntry("MPTokenIssuanceUnlock", 65548);
76+
77+
// Verify count matches GranularPermission enum
78+
int granularPermissionCount = GranularPermission.values().length;
79+
long granularPermissionsInMap = permissionValues.entrySet().stream()
80+
.filter(entry -> entry.getValue() >= 65537)
81+
.count();
82+
assertThat(granularPermissionsInMap).isEqualTo(granularPermissionCount);
83+
}
84+
85+
@Test
86+
void permissionValuesContainsTransactionTypePermissions() {
87+
Map<String, Integer> permissionValues = definitions.permissionValues();
88+
Map<String, Integer> transactionTypes = definitions.transactionTypes();
89+
90+
// Verify transaction type permissions are transaction type code + 1
91+
// For example, if Payment has code 0, its permission value should be 1
92+
transactionTypes.forEach((txType, txCode) -> {
93+
if (txCode >= 0) {
94+
// Skip Invalid (-1), all others should be present
95+
assertThat(permissionValues).containsEntry(txType, txCode + 1);
96+
}
97+
});
98+
}
99+
100+
@Test
101+
void permissionValuesExcludesInvalidTransactionType() {
102+
Map<String, Integer> permissionValues = definitions.permissionValues();
103+
Map<String, Integer> transactionTypes = definitions.transactionTypes();
104+
105+
// Find Invalid transaction type (should have code -1)
106+
transactionTypes.forEach((txType, txCode) -> {
107+
if (txCode == -1) {
108+
// Invalid should not be in permission values
109+
assertThat(permissionValues).doesNotContainKey(txType);
110+
}
111+
});
112+
}
113+
114+
115+
116+
@Test
117+
void permissionValuesDoesNotContainNegativeTransactionCodes() {
118+
Map<String, Integer> permissionValues = definitions.permissionValues();
119+
120+
// All permission values should be positive
121+
permissionValues.forEach((name, value) -> {
122+
assertThat(value).isGreaterThan(0);
123+
});
124+
}
125+
126+
@Test
127+
void permissionValuesHasCorrectSize() {
128+
Map<String, Integer> permissionValues = definitions.permissionValues();
129+
Map<String, Integer> transactionTypes = definitions.transactionTypes();
130+
131+
// Count valid transaction types (code >= 0)
132+
long validTransactionTypes = transactionTypes.values().stream()
133+
.filter(code -> code >= 0)
134+
.count();
135+
136+
// Total should be granular permissions + valid transaction types
137+
int expectedSize = GranularPermission.values().length + (int) validTransactionTypes;
138+
assertThat(permissionValues).hasSize(expectedSize);
139+
}
140+
141+
@Test
142+
void getReturnsSameInstanceOnMultipleCalls() {
143+
// Verify memoization - should return the same instance
144+
Definitions first = provider.get();
145+
Definitions second = provider.get();
146+
assertThat(first).isSameAs(second);
147+
}
148+
149+
@Test
150+
void permissionValuesContainsCommonTransactionTypes() {
151+
Map<String, Integer> permissionValues = definitions.permissionValues();
152+
153+
// Verify some common transaction types are present
154+
// Payment is typically transaction type 0, so permission should be 1
155+
assertThat(permissionValues).containsKey("Payment");
156+
assertThat(permissionValues.get("Payment")).isGreaterThan(0);
157+
158+
// TrustSet is typically transaction type 20, so permission should be 21
159+
assertThat(permissionValues).containsKey("TrustSet");
160+
assertThat(permissionValues.get("TrustSet")).isGreaterThan(0);
161+
162+
// OfferCreate is typically transaction type 7, so permission should be 8
163+
assertThat(permissionValues).containsKey("OfferCreate");
164+
assertThat(permissionValues.get("OfferCreate")).isGreaterThan(0);
165+
}
166+
167+
@Test
168+
void granularPermissionsStartAt65537() {
169+
Map<String, Integer> permissionValues = definitions.permissionValues();
170+
171+
// All granular permissions should be >= 65537
172+
for (GranularPermission permission : GranularPermission.values()) {
173+
Integer value = permissionValues.get(permission.value());
174+
assertThat(value).isNotNull();
175+
assertThat(value).isGreaterThanOrEqualTo(65537);
176+
}
177+
}
178+
179+
@Test
180+
void transactionTypePermissionsAreLessThan65537() {
181+
Map<String, Integer> permissionValues = definitions.permissionValues();
182+
Map<String, Integer> transactionTypes = definitions.transactionTypes();
183+
184+
// All transaction type permissions should be < 65537
185+
transactionTypes.forEach((txType, txCode) -> {
186+
if (txCode >= 0) {
187+
Integer permissionValue = permissionValues.get(txType);
188+
assertThat(permissionValue).isNotNull();
189+
assertThat(permissionValue).isLessThan(65537);
190+
assertThat(permissionValue).isEqualTo(txCode + 1);
191+
}
192+
});
193+
}
194+
}

xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/DelegateIT.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,6 @@ public void testPaymentWithDelegate() throws JsonRpcClientErrorException, JsonPr
184184
() -> this.getValidatedAccountInfo(delegateKeyPair.publicKey().deriveAddress())
185185
);
186186

187-
188-
189187
// Now send a Payment transaction with the Delegate field
190188
// The delegate signs the transaction, but the Account field is the delegating account
191189
XrpCurrencyAmount amount = XrpCurrencyAmount.ofDrops(12345);

0 commit comments

Comments
 (0)