Skip to content

Commit

Permalink
Feat/ra-41: integration tests for account api, resolving Sonar issues
Browse files Browse the repository at this point in the history
  • Loading branch information
BerezinD authored Apr 5, 2024
1 parent df7436c commit 20e603b
Show file tree
Hide file tree
Showing 25 changed files with 1,054 additions and 414 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.cardanofoundation.rosetta.api.account.model.entity;
package org.cardanofoundation.rosetta.api.account.model.domain;

import java.io.Serializable;
import java.math.BigInteger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import lombok.NoArgsConstructor;

import org.cardanofoundation.rosetta.api.account.model.entity.AddressUtxoEntity;
import org.cardanofoundation.rosetta.api.account.model.entity.Amt;
import org.cardanofoundation.rosetta.api.block.model.entity.UtxoKey;

@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Type;

import org.cardanofoundation.rosetta.api.account.model.domain.Amt;
import org.cardanofoundation.rosetta.api.block.model.entity.BlockAwareEntity;

@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
import org.openapitools.client.model.PoolRegistrationParams;
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.api.account.model.entity.Amt;
import org.cardanofoundation.rosetta.api.block.model.domain.BlockTx;
import org.cardanofoundation.rosetta.api.block.model.domain.Delegation;
import org.cardanofoundation.rosetta.api.block.model.domain.PoolRegistration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import lombok.Data;
import lombok.NoArgsConstructor;

import org.cardanofoundation.rosetta.api.account.model.entity.Amt;
import org.cardanofoundation.rosetta.api.account.model.domain.Amt;

//Not used
@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.io.FileNotFoundException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
Expand All @@ -16,22 +15,22 @@
import org.openapitools.client.model.Currency;

import org.cardanofoundation.rosetta.api.account.model.domain.AddressBalance;
import org.cardanofoundation.rosetta.api.account.model.domain.Amt;
import org.cardanofoundation.rosetta.api.account.model.domain.Utxo;
import org.cardanofoundation.rosetta.api.account.model.entity.AddressBalanceEntity;
import org.cardanofoundation.rosetta.api.account.model.entity.AddressUtxoEntity;
import org.cardanofoundation.rosetta.api.account.model.entity.Amt;
import org.cardanofoundation.rosetta.api.account.model.repository.AddressBalanceRepository;
import org.cardanofoundation.rosetta.api.account.model.repository.AddressUtxoRepository;
import org.cardanofoundation.rosetta.api.block.mapper.BlockToEntity;
import org.cardanofoundation.rosetta.api.block.mapper.BlockTxToEntity;
import org.cardanofoundation.rosetta.api.block.model.domain.Block;
import org.cardanofoundation.rosetta.api.block.model.domain.BlockTx;
import org.cardanofoundation.rosetta.api.block.model.domain.Delegation;
import org.cardanofoundation.rosetta.api.block.model.domain.GenesisBlock;
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.StakeAddressBalance;
import org.cardanofoundation.rosetta.api.block.model.domain.StakeRegistration;
import org.cardanofoundation.rosetta.api.block.model.domain.BlockTx;
import org.cardanofoundation.rosetta.api.block.model.entity.BlockEntity;
import org.cardanofoundation.rosetta.api.block.model.entity.ProtocolParams;
import org.cardanofoundation.rosetta.api.block.model.entity.StakeAddressBalanceEntity;
Expand All @@ -48,6 +47,7 @@
import org.cardanofoundation.rosetta.common.exception.ExceptionFactory;
import org.cardanofoundation.rosetta.common.services.CardanoConfigService;
import org.cardanofoundation.rosetta.common.services.LedgerDataProviderService;
import org.cardanofoundation.rosetta.common.util.Formatters;

@Slf4j
@Component
Expand All @@ -74,7 +74,7 @@ public class PostgresLedgerDataProviderService implements LedgerDataProviderServ
public GenesisBlock findGenesisBlock() {
log.debug("[findGenesisBlock] About to run findGenesisBlock query");
List<BlockEntity> blocks = blockRepository.findGenesisBlock();
if(!blocks.isEmpty()) {
if (!blocks.isEmpty()) {
BlockEntity genesis = blocks.getFirst();
return GenesisBlock.builder().hash(genesis.getHash())
.number(genesis.getNumber())
Expand All @@ -90,9 +90,9 @@ public Block findBlock(Long blockNumber, String blockHash) {
"[findBlock] Parameters received for run query blockNumber: {} , blockHash: {}",
blockNumber, blockHash);
List<BlockEntity> blocks;
if(blockHash == null && blockNumber != null) {
if (blockHash == null && blockNumber != null) {
blocks = blockRepository.findByNumber(blockNumber);
} else if(blockHash != null && blockNumber == null){
} else if (blockHash != null && blockNumber == null) {
blocks = blockRepository.findByHash(blockHash);
} else {
blocks = blockRepository.findByNumberAndHash(blockNumber, blockHash);
Expand All @@ -116,60 +116,57 @@ private void populateTransactions(List<BlockTx> transactions) {
populateUtxos(transaction.getInputs());
populateUtxos(transaction.getOutputs());
transaction.setStakeRegistrations(
stakeRegistrationRepository.findByTxHash(transaction.getHash())
.stream().map(StakeRegistration::fromEntity).toList()); // TODO Refacotring - do this via JPA
stakeRegistrationRepository.findByTxHash(transaction.getHash())
.stream().map(StakeRegistration::fromEntity)
.toList()); // TODO Refacotring - do this via JPA
transaction.setDelegations(delegationRepository.findByTxHash(transaction.getHash())
.stream().map(Delegation::fromEntity).toList()); // TODO Refacotring - do this via JPA
transaction.setPoolRegistrations(poolRegistrationRepository.findByTxHash(transaction.getHash())
.stream().map(PoolRegistration::fromEntity).toList()); // TODO Refacotring - do this via JPA
.stream().map(Delegation::fromEntity).toList()); // TODO Refacotring - do this via JPA
transaction.setPoolRegistrations(
poolRegistrationRepository.findByTxHash(transaction.getHash())
.stream().map(PoolRegistration::fromEntity)
.toList()); // TODO Refacotring - do this via JPA
transaction.setPoolRetirements(poolRetirementRepository.findByTxHash(transaction.getHash())
.stream().map(PoolRetirement::fromEntity).toList()); // TODO Refacotring - do this via JPA
.stream().map(PoolRetirement::fromEntity).toList()); // TODO Refacotring - do this via JPA
}
}

private void populateUtxos(List<Utxo> inputs) {
for (Utxo utxo : inputs) {
AddressUtxoEntity first = addressUtxoRepository.findAddressUtxoEntitiesByOutputIndexAndTxHash(utxo.getOutputIndex(), utxo.getTxHash()).getFirst();
if(first != null) {
AddressUtxoEntity first = addressUtxoRepository.findAddressUtxoEntitiesByOutputIndexAndTxHash(
utxo.getOutputIndex(), utxo.getTxHash()).getFirst();
if (first != null) {
utxo.populateFromUtxoEntity(first);
}
}
}

@Override
public List<AddressBalance> findBalanceByAddressAndBlock(String address, Long number) {
List<AddressBalanceEntity> balances = addressBalanceRepository.findAddressBalanceByAddressAndBlockNumber(address, number);
List<AddressBalanceEntity> balances = addressBalanceRepository.findAddressBalanceByAddressAndBlockNumber(
address, number);
return balances.stream().map(AddressBalance::fromEntity).toList();
}

@Override
public List<StakeAddressBalance> findStakeAddressBalanceByAddressAndBlock(String address, Long number) {
List<StakeAddressBalanceEntity> balances = stakeAddressRepository.findStakeAddressBalanceByAddressAndBlockNumber(address, number);
public List<StakeAddressBalance> findStakeAddressBalanceByAddressAndBlock(String address,
Long number) {
List<StakeAddressBalanceEntity> balances = stakeAddressRepository.findStakeAddressBalanceByAddressAndBlockNumber(
address, number);
return balances.stream().map(StakeAddressBalance::fromEntity).toList();
}

@Override
public Long findLatestBlockNumber() {
return blockRepository.findLatestBlockNumber();
return blockRepository.findLatestBlockNumber();
}

@Override
public List<Utxo> findUtxoByAddressAndCurrency(String address, List<Currency> currencies) {
List<AddressUtxoEntity> addressUtxoEntities = addressUtxoRepository.findUtxosByAddress(address);
List<Utxo> utxos = new ArrayList<>();
for(AddressUtxoEntity entity : addressUtxoEntities) {
List<Amt> amountsToAdd = new ArrayList<>();
for(Amt amt : entity.getAmounts()) {
boolean addToList = currencies.isEmpty() || currencies.stream().anyMatch(currency -> currency.getSymbol().equals(amt.getUnit()));
if(addToList) {
amountsToAdd.add(amt);
}
}
Utxo utxoModel = Utxo.fromUtxoKey(UtxoKey.builder().outputIndex(entity.getOutputIndex()).txHash(entity.getTxHash()).build());
utxoModel.setAmounts(amountsToAdd);
utxos.add(utxoModel);
}
return utxos;

return addressUtxoEntities.stream()
.map(entity -> createUtxoModel(currencies, entity))
.toList();
}

@Override
Expand Down Expand Up @@ -199,7 +196,8 @@ public List<BlockTx> findTransactionsByBlock(Long blockNumber, String blockHash)
blockNumber, blockHash);
return Collections.emptyList();
}
List<TxnEntity> txList = txRepository.findTransactionsByBlockHash(byNumberAndHash.getFirst().getHash());
List<TxnEntity> txList = txRepository.findTransactionsByBlockHash(
byNumberAndHash.getFirst().getHash());
log.debug(
"[findTransactionsByBlock] Found {} transactions", txList.size());
if (ObjectUtils.isNotEmpty(txList)) {
Expand Down Expand Up @@ -231,4 +229,30 @@ public ProtocolParams findProtocolParametersFromIndexerAndConfig() {
protocolParams.merge(findProtocolParametersFromConfig());
return protocolParams;
}

private static Utxo createUtxoModel(List<Currency> currencies, AddressUtxoEntity entity) {
Utxo utxoModel = Utxo.fromUtxoKey(
UtxoKey.builder().outputIndex(entity.getOutputIndex()).txHash(entity.getTxHash())
.build());
utxoModel.setAmounts(getAmts(currencies, entity));
return utxoModel;
}

private static List<Amt> getAmts(List<Currency> currencies, AddressUtxoEntity entity) {
return currencies.isEmpty()
? entity.getAmounts()
: entity.getAmounts().stream()
.filter(amt -> isAmountMatchesCurrency(currencies, amt))
.toList();
}

private static boolean isAmountMatchesCurrency(List<Currency> currencies, Amt amt) {
return currencies.stream()
.anyMatch(currency -> {
String currencyUnit = Formatters.isEmptyHexString(currency.getSymbol()) ?
currency.getMetadata().getPolicyId() :
currency.getMetadata().getPolicyId() + currency.getSymbol();
return currencyUnit.equals(amt.getUnit());
});
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
package org.cardanofoundation.rosetta.common.util;


import static org.cardanofoundation.rosetta.common.exception.ExceptionFactory.invalidPolicyIdError;
import static org.cardanofoundation.rosetta.common.exception.ExceptionFactory.invalidTokenNameError;
import static org.cardanofoundation.rosetta.common.util.Formatters.hexStringToBuffer;
import static org.cardanofoundation.rosetta.common.util.Formatters.isEmptyHexString;

import com.bloxbean.cardano.client.address.Address;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;

import com.bloxbean.cardano.client.address.Address;
import org.openapitools.client.model.Currency;
import org.openapitools.client.model.CurrencyMetadata;

import org.cardanofoundation.rosetta.api.account.model.domain.Utxo;
import org.cardanofoundation.rosetta.common.enumeration.CatalystDataIndexes;
import org.cardanofoundation.rosetta.common.enumeration.CatalystSigIndexes;
import org.openapitools.client.model.Currency;

import static org.cardanofoundation.rosetta.common.exception.ExceptionFactory.invalidPolicyIdError;
import static org.cardanofoundation.rosetta.common.exception.ExceptionFactory.invalidTokenNameError;
import static org.cardanofoundation.rosetta.common.util.Formatters.hexStringToBuffer;
import static org.cardanofoundation.rosetta.common.util.Formatters.isEmptyHexString;


public class ValidationUtil {
Expand All @@ -34,14 +36,14 @@ private ValidationUtil() {
public static void validateCurrencies(List<Currency> currencies) {
for (Currency currency : currencies) {
String symbol = currency.getSymbol();
Map<String, Object> metadata = (Map<String, Object>) currency.getMetadata();
CurrencyMetadata metadata = currency.getMetadata();
if (!isTokenNameValid(symbol)) {
throw invalidTokenNameError("Given name is " + symbol);
}
if (
!symbol.equals(Constants.ADA)
&& !isPolicyIdValid(String.valueOf(metadata.get("policyId")))) {
throw invalidPolicyIdError("Given policy id is " + metadata.get("policyId"));
if (!symbol.equals(Constants.ADA)
&& (metadata == null || !isPolicyIdValid(String.valueOf(metadata.getPolicyId())))) {
String policyId = metadata == null ? null : metadata.getPolicyId();
throw invalidPolicyIdError("Given policy id is " + policyId);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,30 @@

import java.io.File;
import java.io.IOException;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.context.annotation.Profile;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.junit.jupiter.api.BeforeAll;

import org.cardanofoundation.rosetta.RosettaApiApplication;
import org.cardanofoundation.rosetta.testgenerator.common.GeneratedTestDataDTO;
import org.cardanofoundation.rosetta.testgenerator.common.TestConstants;
import org.cardanofoundation.rosetta.testgenerator.common.TransactionBlockDetails;

@Profile("test-integration")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {
RosettaApiApplication.class})
@Transactional
public abstract class IntegrationTest {

protected static GeneratedTestDataDTO generatedTestData;
protected static Map<String, TransactionBlockDetails> generatedDataMap;

@Autowired
public TestRestTemplate restTemplate;
Expand All @@ -33,7 +35,8 @@ public abstract class IntegrationTest {

@BeforeAll
public static void init(@Autowired ObjectMapper objectMapper) throws IOException {
generatedTestData = objectMapper.readValue(new File("." + TestConstants.FILE_SAVE_PATH),
GeneratedTestDataDTO.class);
generatedDataMap = objectMapper.readValue(new File("." + TestConstants.FILE_SAVE_PATH),
new TypeReference<Map<String, TransactionBlockDetails>>() {
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import org.junit.jupiter.api.extension.ExtendWith;

import org.cardanofoundation.rosetta.api.account.model.domain.AddressBalance;
import org.cardanofoundation.rosetta.api.account.model.domain.Amt;
import org.cardanofoundation.rosetta.api.account.model.domain.Utxo;
import org.cardanofoundation.rosetta.api.account.model.entity.Amt;
import org.cardanofoundation.rosetta.api.block.model.domain.Block;
import org.cardanofoundation.rosetta.api.block.model.domain.StakeAddressBalance;
import org.cardanofoundation.rosetta.common.enumeration.StakeAddressPrefix;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
import org.junit.jupiter.api.Test;

import org.cardanofoundation.rosetta.api.BaseMapperTest;
import org.cardanofoundation.rosetta.api.account.model.domain.Amt;
import org.cardanofoundation.rosetta.api.account.model.domain.Utxo;
import org.cardanofoundation.rosetta.api.account.model.entity.Amt;
import org.cardanofoundation.rosetta.api.block.model.domain.BlockTx;
import org.cardanofoundation.rosetta.api.block.model.domain.Delegation;
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.BlockTx;

import static org.assertj.core.api.Assertions.assertThat;

Expand Down Expand Up @@ -144,4 +144,4 @@ private List<Delegation> newDelegations() {
.build());
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
import org.junit.jupiter.api.Test;

import org.cardanofoundation.rosetta.api.BaseMapperTest;
import org.cardanofoundation.rosetta.api.account.model.domain.Amt;
import org.cardanofoundation.rosetta.api.account.model.domain.Utxo;
import org.cardanofoundation.rosetta.api.account.model.entity.Amt;
import org.cardanofoundation.rosetta.api.block.model.domain.BlockTx;
import org.cardanofoundation.rosetta.api.block.model.domain.Delegation;
import org.cardanofoundation.rosetta.api.block.model.domain.PoolRegistration;
Expand Down Expand Up @@ -384,4 +384,4 @@ private static Amt newAmt() {
}


}
}
Loading

0 comments on commit 20e603b

Please sign in to comment.