From 34b0407c803d3774586af060217e8f232acd9d8a Mon Sep 17 00:00:00 2001 From: shleger Date: Fri, 12 Apr 2024 12:29:25 +0800 Subject: [PATCH] feat:/RA-44 add integration tests (#121) * feat: RA-44 add asserts in BlockIntTest * feat: RA-44 rm poolDeposit from BlockTx* mappers * feat: RA-44 add test to InputToOperation * feat: RA-44 fix todos * feat: RA-44 fix merge compile errors * feat: RA-44 fix rm validate tests * feat: RA-44 refactor after compile error * feat: RA-44 order test owners * feat: RA-44 add comment --- .../api/block/controller/BlockApiImpl.java | 5 +- .../api/block/mapper/AbstractToOperation.java | 34 ++++-- .../block/mapper/BlockToBlockResponse.java | 25 ++--- .../mapper/BlockTxToBlockTxResponse.java | 4 +- .../mapper/BlockTxToRosettaTransaction.java | 3 +- .../api/block/mapper/InputToOperation.java | 19 +--- .../api/block/mapper/OutputToOperation.java | 16 +-- .../mapper/PoolRegistrationToOperation.java | 25 +---- .../mapper/StakeRegistrationToOperation.java | 4 +- .../block/mapper/WithdrawalToOperation.java | 8 +- .../api/block/model/domain/BlockTx.java | 2 +- .../rosetta/api/BaseMapperTest.java | 17 +++ .../rosetta/api/IntegrationTest.java | 2 +- .../block/controller/BlockApiImplTest.java | 2 +- .../mapper/BlockToBlockResponseTest.java | 30 ++--- .../api/block/mapper/BlockToEntityTest.java | 1 - .../mapper/BlockTxToBlockTxResponseTest.java | 3 +- .../BlockTxToRosettaTransactionTest.java | 104 +++++++++++++++--- .../service/BlockServiceImplIntTest.java | 25 +++-- .../mapper/ProtocolParamsToEntityTest.java | 1 - 20 files changed, 195 insertions(+), 135 deletions(-) diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/controller/BlockApiImpl.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/controller/BlockApiImpl.java index 9e0930120..93b382bff 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/controller/BlockApiImpl.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/controller/BlockApiImpl.java @@ -49,10 +49,9 @@ public ResponseEntity blockTransaction( String blockHash = blockReq.getBlockIdentifier().getHash(); String txHash = blockReq.getTransactionIdentifier().getHash(); - BlockTx tx = blockService.getBlockTransaction(blockId, blockHash, txHash); - String poolDeposit = String.valueOf(protocolParamService.getProtocolParameters().getPoolDeposit()); + BlockTx blockTx = blockService.getBlockTransaction(blockId, blockHash, txHash); - return ResponseEntity.ok(mapperToBlockTxResponse.toDto(tx, poolDeposit)); + return ResponseEntity.ok(mapperToBlockTxResponse.toDto(blockTx)); } } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/AbstractToOperation.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/AbstractToOperation.java index 647bb3008..6324fb733 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/AbstractToOperation.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/AbstractToOperation.java @@ -1,5 +1,6 @@ package org.cardanofoundation.rosetta.api.block.mapper; +import java.math.BigInteger; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -8,6 +9,7 @@ import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.mutable.MutableInt; import org.jetbrains.annotations.NotNull; +import org.modelmapper.builder.ConfigurableConditionExpression; import org.openapitools.client.model.Amount; import org.openapitools.client.model.Currency; import org.openapitools.client.model.Operation; @@ -16,10 +18,14 @@ import org.openapitools.client.model.TokenBundleItem; import org.cardanofoundation.rosetta.api.account.model.domain.Amt; +import org.cardanofoundation.rosetta.api.account.model.domain.Utxo; import org.cardanofoundation.rosetta.common.mapper.DataMapper; import org.cardanofoundation.rosetta.common.services.ProtocolParamService; import org.cardanofoundation.rosetta.common.util.Constants; +import static org.cardanofoundation.rosetta.common.util.Constants.ADA; +import static org.cardanofoundation.rosetta.common.util.Constants.ADA_DECIMALS; + public abstract class AbstractToOperation { @Autowired @@ -42,7 +48,7 @@ protected OperationMetadata mapToOperationMetaData(boolean spent, List amou .stream() .flatMap(List::stream) .forEach(amount -> { - operationMetadata.setDepositAmount(getDepositAmount("2000000")); + operationMetadata.setDepositAmount(getDepositAmount()); if (!amount.getAssetName().equals(Constants.LOVELACE)) { TokenBundleItem tokenBundleItem = new TokenBundleItem(); tokenBundleItem.setPolicyId(amount.getPolicyId()); @@ -60,15 +66,29 @@ protected OperationMetadata mapToOperationMetaData(boolean spent, List amou return operationMetadata; } - // TODO saa: need to get this '"2000000", Constants.ADA, Constants.ADA_DECIMALS,' from protocolparams - // Create and inject ProtocolParamServiceImpl to get the stake deposit amount - // see similar implementation in BlockService.getPoolDeposit @NotNull - protected Amount getDepositAmount(String deposit) { - //TODO saa: poolDeposit and delegation ddeposit are equals? -// String deposit = String.valueOf(protocolParamService.getProtocolParameters().getPoolDeposit()); + protected Amount getDepositAmount() { + String deposit = String.valueOf(protocolParamService.getProtocolParameters().getPoolDeposit()); return DataMapper.mapAmount(deposit, Constants.ADA, Constants.ADA_DECIMALS, null); } + @NotNull + protected Amount updateDepositAmount(BigInteger deposit) { + return DataMapper.mapAmount(deposit.toString(), Constants.ADA, Constants.ADA_DECIMALS, null); + } + + //common mappings for InputToOperation and OutputToOperation + protected static void mapOthers(Utxo model, OperationStatus status, int index, + ConfigurableConditionExpression mp) { + mp.map(f -> status.getStatus(), Operation::setStatus); + mp.map(f -> index, (d, v) -> d.getOperationIdentifier().setIndex(v)); + mp.map(Utxo::getOwnerAddr, (d, v) -> d.getAccount().setAddress(v)); + mp.map(Utxo::getLovelaceAmount, (d, v) -> d.getAmount().setValue(String.valueOf(v))); + mp.map(f -> ADA, (d, v) -> d.getAmount().getCurrency().setSymbol(v)); + mp.map(f -> ADA_DECIMALS, (d, v) -> d.getAmount().getCurrency().setDecimals(v)); + mp.map(f -> model.getTxHash() + ":" + model.getOutputIndex(), + (d, v) -> d.getCoinChange().getCoinIdentifier().setIdentifier(v)); + } + } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToBlockResponse.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToBlockResponse.java index 47bb724ff..6c9d933d3 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToBlockResponse.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToBlockResponse.java @@ -7,7 +7,6 @@ import lombok.AllArgsConstructor; import org.modelmapper.ModelMapper; -import org.modelmapper.spi.MappingContext; import org.openapitools.client.model.BlockIdentifier; import org.openapitools.client.model.BlockMetadata; import org.openapitools.client.model.BlockResponse; @@ -46,18 +45,19 @@ public BlockResponse toDto(Block model) { mapper.map(Block::getCreatedAt, (dest, v) -> dest.getBlock().setTimestamp(v)); }) .setPostConverter(ctx -> { + Block source = ctx.getSource(); ctx.getDestination().getBlock().setMetadata( BlockMetadata.builder() - .transactionsCount(source(ctx).getTransactionsCount()) - .createdBy(source(ctx).getCreatedBy()) - .size(source(ctx).getSize()) - .epochNo(source(ctx).getEpochNo()) - .slotNo(source(ctx).getSlotNo()) + .transactionsCount(source.getTransactionsCount()) + .createdBy(source.getCreatedBy()) + .size(source.getSize()) + .epochNo(source.getEpochNo()) + .slotNo(source.getSlotNo()) .build() ); ctx.getDestination().getBlock().setTransactions( - mapToRosettaTransactions(source(ctx).getTransactions(), source(ctx).getPoolDeposit()) + mapToRosettaTransactions(source.getTransactions()) ); return ctx.getDestination(); @@ -65,24 +65,19 @@ public BlockResponse toDto(Block model) { } - private static Block source(MappingContext ctx) { - return ctx.getSource(); - } + /** * Maps a list of Cardano Transactions to a list of Rosetta compatible Transactions. * * @param transactions The transactions to be mapped - * @param poolDeposit The pool deposit * @return The list of Rosetta compatible Transactions */ - public List mapToRosettaTransactions( - List transactions, - String poolDeposit) { + public List mapToRosettaTransactions(List transactions) { List rosettaTransactions = new ArrayList<>(); for (BlockTx tranDto : transactions) { - rosettaTransactions.add(mapToRosettaTransaction.toDto(tranDto, poolDeposit)); + rosettaTransactions.add(mapToRosettaTransaction.toDto(tranDto)); } return rosettaTransactions; } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToBlockTxResponse.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToBlockTxResponse.java index 9ed02be30..c5b2e0a90 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToBlockTxResponse.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToBlockTxResponse.java @@ -19,12 +19,12 @@ public class BlockTxToBlockTxResponse { final BlockTxToRosettaTransaction blockTxToRosettaTx; - public BlockTransactionResponse toDto(BlockTx model, String poolDeposit) { + public BlockTransactionResponse toDto(BlockTx model) { return Optional .ofNullable(modelMapper.getTypeMap(BlockTx.class, BlockTransactionResponse.class)) .orElseGet(() -> modelMapper.createTypeMap(BlockTx.class, BlockTransactionResponse.class)) .setPostConverter(ctx -> { - ctx.getDestination().setTransaction(blockTxToRosettaTx.toDto(model, poolDeposit)); + ctx.getDestination().setTransaction(blockTxToRosettaTx.toDto(model)); return ctx.getDestination(); }).map(model); } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToRosettaTransaction.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToRosettaTransaction.java index b1b8d73dd..386d3917a 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToRosettaTransaction.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToRosettaTransaction.java @@ -41,10 +41,9 @@ public class BlockTxToRosettaTransaction { * Maps a TransactionDto to a Rosetta compatible BlockTx. * * @param model The Cardano transaction to be mapped - * @param poolDeposit The pool deposit //TODO saa: make injectable from the protocol params * @return The Rosetta compatible Transaction */ - public Transaction toDto(BlockTx model, @Deprecated String poolDeposit) { + public Transaction toDto(BlockTx model) { return Optional .ofNullable(modelMapper.getTypeMap(BlockTx.class, Transaction.class)) .orElseGet(() -> modelMapper.createTypeMap(BlockTx.class, Transaction.class)) diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/InputToOperation.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/InputToOperation.java index 00335039d..87d0cf636 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/InputToOperation.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/InputToOperation.java @@ -5,7 +5,6 @@ import lombok.AllArgsConstructor; import org.modelmapper.ModelMapper; -import org.modelmapper.spi.MappingContext; import org.openapitools.client.model.CoinAction; import org.openapitools.client.model.Operation; import org.openapitools.client.model.OperationStatus; @@ -14,8 +13,6 @@ import org.cardanofoundation.rosetta.common.annotation.OpenApiMapper; import org.cardanofoundation.rosetta.common.util.Constants; -import static org.cardanofoundation.rosetta.common.util.Constants.ADA; - @OpenApiMapper @AllArgsConstructor public class InputToOperation extends AbstractToOperation { @@ -28,21 +25,13 @@ public Operation toDto(Utxo model, OperationStatus status, int index) { .ofNullable(modelMapper.getTypeMap(Utxo.class, Operation.class)) .orElseGet(() -> modelMapper.createTypeMap(Utxo.class, Operation.class)) .addMappings(mp -> { - mp.map(f -> Constants.INPUT, Operation::setType); - mp.map(f -> status.getStatus(), Operation::setStatus); - mp.map(Utxo::getOwnerAddr, (d, v) -> d.getAccount().setAddress(v)); - mp.map(Utxo::getLovelaceAmount, (d, v) -> d.getAmount().setValue(String.valueOf(v))); - mp.map(f -> ADA, (d, v) -> d.getAmount().getCurrency().setSymbol(v)); - mp.map(f -> f, - (d, v) -> d.getCoinChange() - .getCoinIdentifier() - .setIdentifier(model.getTxHash() + ":" + model.getOutputIndex())); mp.map(f -> CoinAction.SPENT, (d, v) -> d.getCoinChange().setCoinAction(v)); - mp.map(f-> mapToOperationMetaData(true, model.getAmounts()), Operation::setMetadata); //TODO saa: test it! - + mp.map(f-> mapToOperationMetaData(true, model.getAmounts()), Operation::setMetadata); + mapOthers(model, status, index, mp); }) - .setPostConverter(MappingContext::getDestination) .map(model); } + + } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/OutputToOperation.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/OutputToOperation.java index ac54b4cd3..8eb405e26 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/OutputToOperation.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/OutputToOperation.java @@ -5,7 +5,6 @@ import lombok.AllArgsConstructor; import org.modelmapper.ModelMapper; -import org.modelmapper.spi.MappingContext; import org.openapitools.client.model.CoinAction; import org.openapitools.client.model.Operation; import org.openapitools.client.model.OperationStatus; @@ -14,9 +13,6 @@ import org.cardanofoundation.rosetta.common.annotation.OpenApiMapper; import org.cardanofoundation.rosetta.common.util.Constants; -import static org.cardanofoundation.rosetta.common.util.Constants.ADA; -import static org.cardanofoundation.rosetta.common.util.Constants.ADA_DECIMALS; - @OpenApiMapper @AllArgsConstructor public class OutputToOperation extends AbstractToOperation { @@ -30,20 +26,10 @@ public Operation toDto(Utxo model, OperationStatus status, int index) { .orElseGet(() -> modelMapper.createTypeMap(Utxo.class, Operation.class)) .addMappings(mp -> { mp.map(f -> Constants.OUTPUT, Operation::setType); - mp.map(f -> status.getStatus(), Operation::setStatus); - mp.map(f -> index, (d, v) -> d.getOperationIdentifier().setIndex(v)); - mp.map(Utxo::getOwnerAddr, (d, v) -> d.getAccount().setAddress(v)); - mp.map(Utxo::getLovelaceAmount, (d, v) -> d.getAmount().setValue(String.valueOf(v))); - mp.map(f -> ADA, (d, v) -> d.getAmount().getCurrency().setSymbol(v)); - mp.map(f -> ADA_DECIMALS, (d, v) -> d.getAmount().getCurrency().setDecimals(v)); - mp.map(f -> model.getTxHash() + ":" + model.getOutputIndex(), - (d, v) -> d.getCoinChange().getCoinIdentifier().setIdentifier(v)); mp.map(f -> CoinAction.CREATED, (d, v) -> d.getCoinChange().setCoinAction(v)); mp.map(f-> mapToOperationMetaData(false, model.getAmounts()), Operation::setMetadata); - + mapOthers(model, status, index, mp); }) - //strange but without it method mapToOperationMetaData in above mapper did not work - .setPostConverter(MappingContext::getDestination) .map(model); } } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/PoolRegistrationToOperation.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/PoolRegistrationToOperation.java index 32b271912..190002339 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/PoolRegistrationToOperation.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/PoolRegistrationToOperation.java @@ -5,7 +5,6 @@ import lombok.AllArgsConstructor; import org.modelmapper.ModelMapper; -import org.openapitools.client.model.Amount; import org.openapitools.client.model.Operation; import org.openapitools.client.model.OperationMetadata; import org.openapitools.client.model.OperationStatus; @@ -26,25 +25,6 @@ public Operation toDto(PoolRegistration model, OperationStatus status, int index return Optional .ofNullable(modelMapper.getTypeMap(PoolRegistration.class, Operation.class)) .orElseGet(() -> modelMapper.createTypeMap(PoolRegistration.class, Operation.class)) - .addMappings(mp -> { - mp.skip(Operation::setMetadata); - }) -// .implicitMappings() -// .addMappings(mp ->{ -// mp.map(f -> getDepositAmount("5000"), -// (d, v) -> d.getMetadata().setDepositAmount(v)); -//// mp.map(PoolRegistration::getPledge, -//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setPledge(v)); -//// mp.map(PoolRegistration::getCost, -//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setCost(v)); -//// mp.>map(f->model.getOwners().stream().toList(), -//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setPoolOwners(v)); -//// mp.map(PoolRegistration::getMargin, -//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setMarginPercentage(v)); -//// mp.>map(PoolRegistration::getRelays, -//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setRelays(v)); -// -// }) .addMappings(mp -> { mp.skip(Operation::setMetadata); @@ -60,8 +40,9 @@ public Operation toDto(PoolRegistration model, OperationStatus status, int index Operation d = ctx.getDestination(); d.setMetadata(new OperationMetadata()); - ctx.getDestination().getMetadata().setDepositAmount(getDepositAmount("500")); - ctx.getDestination().getMetadata().setPoolRegistrationParams(new PoolRegistrationParams()); + ctx.getDestination().getMetadata().setDepositAmount(getDepositAmount()); + ctx.getDestination().getMetadata() + .setPoolRegistrationParams(new PoolRegistrationParams()); var params = ctx.getDestination().getMetadata().getPoolRegistrationParams(); params.setPledge(ctx.getSource().getPledge()); params.setCost(ctx.getSource().getCost()); diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/StakeRegistrationToOperation.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/StakeRegistrationToOperation.java index 4f5a502f9..c05077ba2 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/StakeRegistrationToOperation.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/StakeRegistrationToOperation.java @@ -29,9 +29,9 @@ public Operation toDto(StakeRegistration model, OperationStatus status, int inde .addMappings(mp -> { mp.map(f -> status.getStatus(), Operation::setStatus); - mp.map(f->convert(model.getType()), Operation::setType); + mp.map(f -> convert(model.getType()), Operation::setType); mp.map(StakeRegistration::getAddress, (d, v) -> d.getAccount().setAddress(v)); - mp.map(f->getDepositAmount("2000000"), (d, v) -> d.getMetadata().setDepositAmount(v)); + mp.map(f -> getDepositAmount(), (d, v) -> d.getMetadata().setDepositAmount(v)); mp.map(f -> index, (d, v) -> d.getOperationIdentifier().setIndex(v)); diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/WithdrawalToOperation.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/WithdrawalToOperation.java index 42b7bdaf4..7ed83ef9f 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/WithdrawalToOperation.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/mapper/WithdrawalToOperation.java @@ -1,5 +1,6 @@ package org.cardanofoundation.rosetta.api.block.mapper; +import java.math.BigInteger; import java.util.Optional; import lombok.AllArgsConstructor; import org.cardanofoundation.rosetta.api.block.model.domain.Withdrawal; @@ -26,10 +27,13 @@ public Operation toDto(Withdrawal model, OperationStatus status, int index) { mp.map(f -> status.getStatus(), Operation::setStatus); mp.map(f -> OperationType.WITHDRAWAL.getValue(), Operation::setType); mp.map(Withdrawal::getStakeAddress, (d, v) -> d.getAccount().setAddress(v)); - mp.map(f -> getDepositAmount("-" + f.getAmount()), (d, v) -> d.getMetadata().setWithdrawalAmount(v)); + mp.map(f -> updateDepositAmount( + Optional.ofNullable(model.getAmount()) + .map(BigInteger::negate) + .orElse(BigInteger.ZERO)), //TODO saa: is it OK? + (d, v) -> d.getMetadata().setWithdrawalAmount(v)); mp.map(f -> index, (d, v) -> d.getOperationIdentifier().setIndex(v)); }) - .setPostConverter(MappingContext::getDestination) .map(model); } } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/model/domain/BlockTx.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/model/domain/BlockTx.java index 3e9367909..4887e1aa5 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/model/domain/BlockTx.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/model/domain/BlockTx.java @@ -10,7 +10,7 @@ import org.cardanofoundation.rosetta.api.account.model.domain.Utxo; /** - * Cardano Transaction model. Named so because of clash with the Transaction from the Rosetta API. + * Cardano Transaction domain model. */ @Data @NoArgsConstructor diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/BaseMapperTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/BaseMapperTest.java index 618783bf0..44a268b82 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/api/BaseMapperTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/BaseMapperTest.java @@ -1,18 +1,35 @@ package org.cardanofoundation.rosetta.api; +import java.math.BigInteger; + import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.mockito.Mock; + +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.cardanofoundation.rosetta.ConfigurationMapper; +import org.cardanofoundation.rosetta.api.block.model.domain.ProtocolParams; import org.cardanofoundation.rosetta.common.services.ProtocolParamService; +import static org.mockito.Mockito.when; + @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = {ConfigurationMapper.class, SpringMappersTestConfig.class}) public class BaseMapperTest { @MockBean protected ProtocolParamService protocolParamService; + + @Mock + ProtocolParams protocolParams; + + @BeforeEach + public void before() { + when(protocolParamService.getProtocolParameters()).thenReturn(protocolParams); + when(protocolParams.getPoolDeposit()).thenReturn(new BigInteger("500")); + } } diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/IntegrationTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/IntegrationTest.java index e7255b568..01104ce08 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/api/IntegrationTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/IntegrationTest.java @@ -36,7 +36,7 @@ public abstract class IntegrationTest { @BeforeAll public static void init(@Autowired ObjectMapper objectMapper) throws IOException { generatedDataMap = objectMapper.readValue(new File("." + TestConstants.FILE_SAVE_PATH), - new TypeReference>() { + new TypeReference<>() { }); } } diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/block/controller/BlockApiImplTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/block/controller/BlockApiImplTest.java index c3b9dbedb..1fd462aa3 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/api/block/controller/BlockApiImplTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/block/controller/BlockApiImplTest.java @@ -101,7 +101,7 @@ void blockTransaction_Test() throws Exception { when(protocolParamService.getProtocolParameters()).thenReturn(protocolParams); when(protocolParams.getPoolDeposit()).thenReturn(new BigInteger("1000")); //any string - when(mapperToBlockTxResponse.toDto(any(BlockTx.class), anyString())).thenReturn(resp); + when(mapperToBlockTxResponse.toDto(any(BlockTx.class))).thenReturn(resp); //when //then String txHash = resp.getTransaction().getTransactionIdentifier().getHash(); diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToBlockResponseTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToBlockResponseTest.java index 2e1b8e597..acbc613b3 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToBlockResponseTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToBlockResponseTest.java @@ -4,6 +4,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -11,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import com.bloxbean.cardano.yaci.core.model.certs.CertificateType; +import org.jetbrains.annotations.NotNull; import org.openapitools.client.model.AccountIdentifier; import org.openapitools.client.model.Amount; import org.openapitools.client.model.BlockResponse; @@ -167,13 +169,13 @@ void toDto_test_Ok() { .map(Operation::getMetadata) .collect(Collectors.toList())) .allSatisfy(d -> { - //TODO saa: is it OK to have all values here is null other than depositAmount? + //TODO saa: Is it OK to have all values here is null other than depositAmount? assertAllPropertiesIsNull(d, "depositAmount"); assertProperty(d, "depositAmount", Amount .builder() .currency(ada) - .value("2000000") + .value("500") .build()); }); @@ -194,9 +196,9 @@ void toDto_test_Ok() { Amount.builder().currency(ada).value("500").build()); //d == List size == 2 - assertProperty(List.of(orderOwners(d.getFirst())), "poolRegistrationParams", + assertProperty(List.of(d.getFirst()), "poolRegistrationParams", buildRegParams(aiPool.incrementAndGet())); - assertProperty(List.of(orderOwners(d.getLast())), "poolRegistrationParams", + assertProperty(List.of(d.getLast()), "poolRegistrationParams", buildRegParams(aiPool.incrementAndGet())); }); @@ -232,16 +234,6 @@ void toDto_test_Ok() { } - private OperationMetadata orderOwners(OperationMetadata om) { //TODO saa rewrite with TreeSet - -// getPoolOwners() -- immutable list, so need to convert to array and back - String[] poolOwners = om.getPoolRegistrationParams().getPoolOwners().toArray(new String[]{}); - Arrays.sort(poolOwners); //sort required because of the Set in domain model: - // - org.cardanofoundation.rosetta.api.block.model.domain.PoolRegistration.owners - om.getPoolRegistrationParams().setPoolOwners(List.of(poolOwners)); - return om; - } - private static PoolRegistrationParams buildRegParams(int i) { return PoolRegistrationParams.builder() .vrfKeyHash("vrfKeyHash" + i) @@ -338,7 +330,7 @@ private List newPoolRegistrations(int... instances) { .cost("1" + ver) .margin("1.0" + ver) .rewardAccount("rewardAccount" + ver) - .owners(Set.of("owner1" + ver, "owner2" + ver)) + .owners(newOwners(ver)) .relays(List.of(Relay.builder().ipv4("ipv4" + ver).ipv6("ipv6" + ver) .dnsName("dnsName" + ver).port(1 + ver).type("type" + ver).build())) .epoch(1 + ver) @@ -348,6 +340,14 @@ private List newPoolRegistrations(int... instances) { .collect(Collectors.toList()); } + @NotNull + private static Set newOwners(int ver) { + TreeSet treeSet = new TreeSet<>(); + treeSet.add("owner1" + ver); + treeSet.add("owner2" + ver); + return treeSet; + } + private List newPoolRetirements(int... instances) { return Arrays.stream(instances) diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToEntityTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToEntityTest.java index f78e375e2..d187b8c60 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToEntityTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockToEntityTest.java @@ -25,7 +25,6 @@ class BlockToEntityTest extends BaseMapperTest { @Test void fromEntity_Test() { //given - my.modelMapper.validate(); BlockEntity from = newBlockEntity(); //when Block into = my.fromEntity(from); diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToBlockTxResponseTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToBlockTxResponseTest.java index 86e6cb6aa..9e69950dc 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToBlockTxResponseTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToBlockTxResponseTest.java @@ -33,9 +33,8 @@ void toDto() { //given BlockTx from = newTran(); // when - BlockTransactionResponse into = my.toDto(from, "500"); + BlockTransactionResponse into = my.toDto(from); // then - my.modelMapper.validate(); Transaction tx = into.getTransaction(); assertThat(tx.getMetadata().getSize()).isEqualTo(from.getSize()); diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToRosettaTransactionTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToRosettaTransactionTest.java index 326a12824..d9cfd860d 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToRosettaTransactionTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/block/mapper/BlockTxToRosettaTransactionTest.java @@ -9,7 +9,6 @@ import com.bloxbean.cardano.yaci.core.model.certs.CertificateType; import org.apache.commons.codec.binary.Hex; import org.assertj.core.util.introspection.CaseFormatUtils; -import org.jetbrains.annotations.NotNull; import org.openapitools.client.model.Amount; import org.openapitools.client.model.CoinAction; import org.openapitools.client.model.CoinChange; @@ -30,6 +29,7 @@ import org.cardanofoundation.rosetta.api.block.model.domain.PoolRegistration; import org.cardanofoundation.rosetta.api.block.model.domain.PoolRetirement; import org.cardanofoundation.rosetta.api.block.model.domain.StakeRegistration; +import org.cardanofoundation.rosetta.api.block.model.domain.Withdrawal; import org.cardanofoundation.rosetta.common.enumeration.OperationType; import org.cardanofoundation.rosetta.common.util.Constants; @@ -50,7 +50,7 @@ void toDto_Test_empty_operations() { from.setInputs(List.of()); from.setOutputs(List.of()); //when - Transaction into = my.toDto(from, "500"); + Transaction into = my.toDto(from); //then assertThat(into.getMetadata().getSize()).isEqualTo(from.getSize()); assertThat(into.getMetadata().getScriptSize()).isEqualTo(from.getScriptSize()); @@ -74,7 +74,7 @@ void toDto_Test_StakeRegistrationOperations() { .slot(1L) .build())); //when - Transaction into = my.toDto(from, "500"); + Transaction into = my.toDto(from); //then assertThat(into.getMetadata().getSize()).isEqualTo(from.getSize()); assertThat(into.getMetadata().getScriptSize()).isEqualTo(from.getScriptSize()); @@ -97,8 +97,7 @@ void toDto_Test_StakeRegistrationOperations() { assertThat(stakeInto.getOperationIdentifier().getIndex()).isEqualTo(1); //index in array assertThat(stakeInto.getOperationIdentifier().getNetworkIndex()).isNull(); //TODO ?? assertThat(stakeInto.getAccount().getAddress()).isEqualTo(firstFrom.getAddress()); - assertThat(stakeInto.getMetadata().getDepositAmount()) - .isEqualTo(depositAmountActual("2000000")); + assertThat(stakeInto.getMetadata().getDepositAmount()).isEqualTo(amountActual("500")); }); } @@ -116,7 +115,7 @@ void toDto_Test_DelegationOperations() { .slot(1L) .build())); //when - Transaction into = my.toDto(from, "500"); + Transaction into = my.toDto(from); //then assertThat(into.getMetadata().getSize()).isEqualTo(from.getSize()); assertThat(into.getMetadata().getScriptSize()).isEqualTo(from.getScriptSize()); @@ -169,7 +168,7 @@ void toDto_Test_getPoolRegistrationOperations() { .slot(1L) .build())); //when - Transaction into = my.toDto(from, "500"); + Transaction into = my.toDto(from); //then assertThat(into.getMetadata().getSize()).isEqualTo(from.getSize()); assertThat(into.getMetadata().getScriptSize()).isEqualTo(from.getScriptSize()); @@ -191,8 +190,7 @@ void toDto_Test_getPoolRegistrationOperations() { assertThat(poolInto.getStatus()).isEqualTo("success"); assertThat(poolInto.getOperationIdentifier().getIndex()).isEqualTo(1); //index in array assertThat(poolInto.getAccount().getAddress()).isEqualTo(firstFrom.getPoolId()); - assertThat(poolInto.getMetadata().getDepositAmount()) - .isEqualTo(depositAmountActual("500")); + assertThat(poolInto.getMetadata().getDepositAmount()).isEqualTo(amountActual("500")); PoolRegistrationParams poolRegParams = poolInto.getMetadata().getPoolRegistrationParams(); assertThat(poolRegParams.getPledge()).isEqualTo(firstFrom.getPledge()); @@ -220,7 +218,7 @@ void toDto_Test_getPoolRetirementOperations() { .build())); //when - Transaction into = my.toDto(from, "500"); + Transaction into = my.toDto(from); //then assertThat(into.getMetadata().getSize()).isEqualTo(from.getSize()); assertThat(into.getMetadata().getScriptSize()).isEqualTo(from.getScriptSize()); @@ -252,7 +250,7 @@ void toDto_Test_getOutputsAsOperations() { //given BlockTx from = newTran(); //when - Transaction into = my.toDto(from, "500"); + Transaction into = my.toDto(from); //then assertThat(into.getMetadata().getSize()).isEqualTo(from.getSize()); assertThat(into.getMetadata().getScriptSize()).isEqualTo(from.getScriptSize()); @@ -271,7 +269,7 @@ void toDto_Test_getOutputsAsOperations() { assertThat(opInto.getStatus()).isEqualTo("success"); assertThat(opInto.getOperationIdentifier().getIndex()).isEqualTo(1); //index in array assertThat(opInto.getAccount().getAddress()).isEqualTo(firstFrom.getOwnerAddr()); - assertThat(opInto.getAmount()).isEqualTo(depositAmountActual("10")); + assertThat(opInto.getAmount()).isEqualTo(amountActual("10")); CoinChange coinChange = opInto.getCoinChange(); assertThat(coinChange.getCoinAction()).isEqualTo(CoinAction.CREATED); @@ -286,8 +284,6 @@ void toDto_Test_getOutputsAsOperations() { assertThat(bundle.getTokens().size()).isEqualTo(1); Amount token = bundle.getTokens().getFirst(); - assertThat(token.getValue()) - .isEqualTo(from.getOutputs().getFirst().getAmounts().getFirst().getQuantity().toString()); assertThat(token.getCurrency().getSymbol()) .isEqualTo(Hex.encodeHexString( from.getOutputs().getFirst().getAmounts().getFirst().getAssetName().getBytes())); @@ -295,10 +291,86 @@ void toDto_Test_getOutputsAsOperations() { } - private static Amount depositAmountActual(String value) { + + @Test + void toDto_Test_getInputsAsOperations() { + //given + BlockTx from = newTran(); + //when + Transaction into = my.toDto(from); + //then + assertThat(into.getMetadata().getSize()).isEqualTo(from.getSize()); + assertThat(into.getMetadata().getScriptSize()).isEqualTo(from.getScriptSize()); + assertThat(into.getTransactionIdentifier().getHash()).isEqualTo(from.getHash()); + assertThat(into.getOperations().size()).isEqualTo(2); + + Optional opt = into.getOperations() + .stream() + .filter(f -> f.getType().equals(Constants.INPUT)) + .findFirst(); + assertThat(opt.isPresent()).isTrue(); + + Operation opInto = opt.get(); + Utxo firstFrom = from.getInputs().getFirst(); + assertThat(opInto.getType()).isEqualTo(Constants.INPUT); + assertThat(opInto.getStatus()).isEqualTo("success"); + assertThat(opInto.getOperationIdentifier().getIndex()).isEqualTo(0); //index in array + assertThat(opInto.getAccount().getAddress()).isEqualTo(firstFrom.getOwnerAddr()); + assertThat(opInto.getAmount()).isEqualTo(amountActual("10")); + + CoinChange coinChange = opInto.getCoinChange(); + assertThat(coinChange.getCoinAction()).isEqualTo(CoinAction.SPENT); + assertThat(coinChange.getCoinIdentifier().getIdentifier()) + .isEqualTo(firstFrom.getTxHash() + ":" + firstFrom.getOutputIndex()); + + assertThat(opInto.getMetadata().getTokenBundle().size()).isEqualTo(1); + TokenBundleItem bundle = opInto.getMetadata().getTokenBundle().getFirst(); + + assertThat(bundle.getPolicyId()) + .isEqualTo(from.getInputs().getFirst().getAmounts().getFirst().getPolicyId()); + assertThat(bundle.getTokens().size()).isEqualTo(1); + + Amount token = bundle.getTokens().getFirst(); + assertThat(token.getCurrency().getSymbol()) + .isEqualTo(Hex.encodeHexString( + from.getInputs().getFirst().getAmounts().getFirst().getAssetName().getBytes())); + assertThat(token.getCurrency().getDecimals()).isEqualTo(0); + + } + + + @Test + void toDto_Test_getWithdrawlOperations() { + //given + BlockTx from = newTran(); + from.setWithdrawals(List.of(Withdrawal.builder() + .amount(BigInteger.TWO) + .stakeAddress("stake_addr1_for_withdraw") + .build())); + //when + Transaction into = my.toDto(from); + //then + assertThat(into.getOperations().size()).isEqualTo(3); + Optional opt = into.getOperations() + .stream() + .filter(f -> f.getType().equals(OperationType.WITHDRAWAL.getValue())) + .findFirst(); + assertThat(opt.isPresent()).isTrue(); + Operation opInto = opt.get(); + assertThat(opInto.getStatus()).isEqualTo("success"); + assertThat(opInto.getOperationIdentifier().getIndex()).isEqualTo(1); //index in array + assertThat(opInto.getAccount().getAddress()).isNotEmpty(); + assertThat(opInto.getAccount().getAddress()) + .isEqualTo(from.getWithdrawals().getFirst().getStakeAddress()); + assertThat(opInto.getMetadata().getWithdrawalAmount().getValue()) + .isEqualTo("-"+ from.getWithdrawals().getFirst().getAmount().toString()); + } + + + private static Amount amountActual(String value) { return Amount.builder() .currency(Currency.builder().symbol(ADA).decimals(ADA_DECIMALS).build()) - .value(value) //TODO saa: should be checked from genesis json settings? + .value(value) .build(); } diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/block/service/BlockServiceImplIntTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/block/service/BlockServiceImplIntTest.java index 98b4a817f..85df40bf9 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/api/block/service/BlockServiceImplIntTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/block/service/BlockServiceImplIntTest.java @@ -20,27 +20,28 @@ class BlockServiceImplIntTest extends IntegrationTest { @Autowired private BlockService blockService; - final TransactionBlockDetails generatedTestData = generatedDataMap.get( + final TransactionBlockDetails simpleTx = generatedDataMap.get( TestTransactionNames.SIMPLE_TRANSACTION.getName()); @Autowired private ProtocolParamService protocolParamService; + @Test void getBlockWithTransaction_Test() { //given //when - Block block = blockService.findBlock(generatedTestData.blockNumber(), - generatedTestData.blockHash()); + Block block = blockService.findBlock(simpleTx.blockNumber(), + simpleTx.blockHash()); //then - assertEquals(generatedTestData.blockHash(), block.getHash()); - assertEquals(generatedTestData.blockNumber(), block.getSlotNo()); + assertEquals(simpleTx.blockHash(), block.getHash()); + assertEquals(simpleTx.blockNumber(), block.getSlotNo()); assertEquals(1, block.getTransactions().size()); Utxo receiverUtxoDto = block.getTransactions().getFirst().getOutputs().getFirst(); assertEquals(TestConstants.TEST_ACCOUNT_ADDRESS, receiverUtxoDto.getOwnerAddr()); - assertEquals(generatedTestData.txHash(), receiverUtxoDto.getTxHash()); + assertEquals(simpleTx.txHash(), receiverUtxoDto.getTxHash()); assertEquals(TestConstants.ACCOUNT_BALANCE_LOVELACE_AMOUNT, receiverUtxoDto.getLovelaceAmount().toString()); @@ -49,9 +50,9 @@ void getBlockWithTransaction_Test() { @Test void getBlockTransaction_Test() { //given - long blockNo = generatedTestData.blockNumber(); - String blockHash = generatedTestData.blockHash(); - String blockTxHash = generatedTestData.txHash(); + long blockNo = simpleTx.blockNumber(); + String blockHash = simpleTx.blockHash(); + String blockTxHash = simpleTx.txHash(); String fee = "172321"; //when BlockTx tx = blockService.getBlockTransaction(blockNo, blockHash, blockTxHash); @@ -64,7 +65,6 @@ void getBlockTransaction_Test() { assertEquals(0, tx.getScriptSize()); assertEquals(1, tx.getInputs().size()); assertEquals(2, tx.getOutputs().size()); - //TODO saa check the operations assertEquals(0, tx.getStakeRegistrations().size()); assertEquals(0, tx.getPoolRegistrations().size()); assertEquals(0, tx.getPoolRetirements().size()); @@ -73,8 +73,8 @@ void getBlockTransaction_Test() { Utxo inUtxo = tx.getInputs().getFirst(); //TODO saa: how to check? + assertEquals(TestConstants.SENDER_2_ADDRESS, inUtxo.getOwnerAddr()); // assertEquals(blockTxHash, inUtxo.getTxHash()); -// assertEquals(TestConstants.TEST_ACCOUNT_ADDRESS, inUtxo.getOwnerAddr()); Utxo outUtxo = tx.getOutputs().getFirst(); assertEquals(TestConstants.TEST_ACCOUNT_ADDRESS, outUtxo.getOwnerAddr()); @@ -87,7 +87,8 @@ void getBlockTransaction_Test() { @Test void getDepositPool_Test() { - assertThat(protocolParamService.getProtocolParameters().getPoolDeposit()).isEqualTo(500000000); + assertThat(protocolParamService.getProtocolParameters().getPoolDeposit()) + .isEqualTo(500000000); } } diff --git a/api/src/test/java/org/cardanofoundation/rosetta/common/mapper/ProtocolParamsToEntityTest.java b/api/src/test/java/org/cardanofoundation/rosetta/common/mapper/ProtocolParamsToEntityTest.java index 637221351..3df7b368f 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/common/mapper/ProtocolParamsToEntityTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/common/mapper/ProtocolParamsToEntityTest.java @@ -24,7 +24,6 @@ class ProtocolParamsToEntityTest extends BaseMapperTest { @Test void fromEntity_Test_ok() { - my.modelMapper.validate(); EpochParamEntity from = newEpochParamEntity(); ProtocolParams into = my.fromEntity(from.getParams());