Skip to content

Commit

Permalink
feat:/RA-44 add integration tests (#121)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
shleger authored Apr 12, 2024
1 parent 8a261ec commit 34b0407
Show file tree
Hide file tree
Showing 20 changed files with 195 additions and 135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,9 @@ public ResponseEntity<BlockTransactionResponse> 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));

}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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<T> {

@Autowired
Expand All @@ -42,7 +48,7 @@ protected OperationMetadata mapToOperationMetaData(boolean spent, List<Amt> 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());
Expand All @@ -60,15 +66,29 @@ protected OperationMetadata mapToOperationMetaData(boolean spent, List<Amt> 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<Utxo, Operation> mp) {
mp.map(f -> status.getStatus(), Operation::setStatus);
mp.<Long>map(f -> index, (d, v) -> d.getOperationIdentifier().setIndex(v));
mp.<String>map(Utxo::getOwnerAddr, (d, v) -> d.getAccount().setAddress(v));
mp.map(Utxo::getLovelaceAmount, (d, v) -> d.getAmount().setValue(String.valueOf(v)));
mp.<String>map(f -> ADA, (d, v) -> d.getAmount().getCurrency().setSymbol(v));
mp.<Integer>map(f -> ADA_DECIMALS, (d, v) -> d.getAmount().getCurrency().setDecimals(v));
mp.<String>map(f -> model.getTxHash() + ":" + model.getOutputIndex(),
(d, v) -> d.getCoinChange().getCoinIdentifier().setIdentifier(v));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -46,43 +45,39 @@ public BlockResponse toDto(Block model) {
mapper.<Long>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();
}).map(model);

}

private static Block source(MappingContext<Block, BlockResponse> 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<Transaction> mapToRosettaTransactions(
List<BlockTx> transactions,
String poolDeposit) {
public List<Transaction> mapToRosettaTransactions(List<BlockTx> transactions) {
List<Transaction> rosettaTransactions = new ArrayList<>();
for (BlockTx tranDto : transactions) {
rosettaTransactions.add(mapToRosettaTransaction.toDto(tranDto, poolDeposit));
rosettaTransactions.add(mapToRosettaTransaction.toDto(tranDto));
}
return rosettaTransactions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<Utxo> {
Expand All @@ -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.<String>map(Utxo::getOwnerAddr, (d, v) -> d.getAccount().setAddress(v));
mp.map(Utxo::getLovelaceAmount, (d, v) -> d.getAmount().setValue(String.valueOf(v)));
mp.<String>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.<CoinAction>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);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<Utxo> {
Expand All @@ -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.<Long>map(f -> index, (d, v) -> d.getOperationIdentifier().setIndex(v));
mp.<String>map(Utxo::getOwnerAddr, (d, v) -> d.getAccount().setAddress(v));
mp.map(Utxo::getLovelaceAmount, (d, v) -> d.getAmount().setValue(String.valueOf(v)));
mp.<String>map(f -> ADA, (d, v) -> d.getAmount().getCurrency().setSymbol(v));
mp.<Integer>map(f -> ADA_DECIMALS, (d, v) -> d.getAmount().getCurrency().setDecimals(v));
mp.<String>map(f -> model.getTxHash() + ":" + model.getOutputIndex(),
(d, v) -> d.getCoinChange().getCoinIdentifier().setIdentifier(v));
mp.<CoinAction>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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.<Amount>map(f -> getDepositAmount("5000"),
// (d, v) -> d.getMetadata().setDepositAmount(v));
//// mp.<String>map(PoolRegistration::getPledge,
//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setPledge(v));
//// mp.<String>map(PoolRegistration::getCost,
//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setCost(v));
//// mp.<List<String>>map(f->model.getOwners().stream().toList(),
//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setPoolOwners(v));
//// mp.<String>map(PoolRegistration::getMargin,
//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setMarginPercentage(v));
//// mp.<List<Relay>>map(PoolRegistration::getRelays,
//// (d, v) -> d.getMetadata().getPoolRegistrationParams().setRelays(v));
//
// })
.addMappings(mp -> {
mp.skip(Operation::setMetadata);

Expand All @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.<String>map(StakeRegistration::getAddress, (d, v) -> d.getAccount().setAddress(v));
mp.<Amount>map(f->getDepositAmount("2000000"), (d, v) -> d.getMetadata().setDepositAmount(v));
mp.<Amount>map(f -> getDepositAmount(), (d, v) -> d.getMetadata().setDepositAmount(v));
mp.<Long>map(f -> index, (d, v) -> d.getOperationIdentifier().setIndex(v));


Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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.<String>map(Withdrawal::getStakeAddress, (d, v) -> d.getAccount().setAddress(v));
mp.<Amount>map(f -> getDepositAmount("-" + f.getAmount()), (d, v) -> d.getMetadata().setWithdrawalAmount(v));
mp.<Amount>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.<Long>map(f -> index, (d, v) -> d.getOperationIdentifier().setIndex(v));
})
.setPostConverter(MappingContext::getDestination)
.map(model);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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"));
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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<Map<String, TransactionBlockDetails>>() {
new TypeReference<>() {
});
}
}
Loading

0 comments on commit 34b0407

Please sign in to comment.