Skip to content

Commit

Permalink
test: Increase code coverage in CryptoDeleteAllowanceHandlerTest (#…
Browse files Browse the repository at this point in the history
…16834)

Signed-off-by: Petar Tonev <[email protected]>
  • Loading branch information
petreze authored Nov 28, 2024
1 parent 539f059 commit 2a82e0d
Showing 1 changed file with 97 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
import static com.hedera.node.app.spi.fixtures.workflows.ExceptionConditions.responseCode;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mock.Strictness.LENIENT;
import static org.mockito.Mockito.mock;

import com.hedera.hapi.node.base.AccountID;
import com.hedera.hapi.node.base.TransactionID;
Expand All @@ -39,13 +41,18 @@
import com.hedera.node.app.service.token.impl.handlers.CryptoDeleteAllowanceHandler;
import com.hedera.node.app.service.token.impl.test.handlers.util.CryptoTokenHandlerTestBase;
import com.hedera.node.app.service.token.impl.validators.DeleteAllowanceValidator;
import com.hedera.node.app.spi.fees.FeeCalculator;
import com.hedera.node.app.spi.fees.FeeCalculatorFactory;
import com.hedera.node.app.spi.fees.FeeContext;
import com.hedera.node.app.spi.fees.Fees;
import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext;
import com.hedera.node.app.spi.validation.ExpiryValidator;
import com.hedera.node.app.spi.workflows.HandleContext;
import com.hedera.node.app.spi.workflows.HandleException;
import com.hedera.node.app.spi.workflows.PreCheckException;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
Expand Down Expand Up @@ -119,6 +126,32 @@ void happyPathDeletesAllowances() {
assertThat(writableNftStore.get(nftIdSl2).spenderId()).isNull();
}

@Test
void testNoOpDeleteAllowancesWhenListIsEmpty() {
writableNftStore.put(nftSl1.copyBuilder().spenderId(spenderId).build());
writableNftStore.put(nftSl2.copyBuilder().spenderId(spenderId).build());

final var txn = allowancesTxn(payerId, List.of());
given(handleContext.body()).willReturn(txn);
given(handleContext.payer()).willReturn(payerId);
given(expiryValidator.expirationStatus(any(), anyBoolean(), anyLong())).willReturn(OK);

assertThat(ownerAccount.approveForAllNftAllowances()).hasSize(1);
assertThat(writableNftStore.get(nftIdSl1).ownerId()).isEqualTo(ownerId);
assertThat(writableNftStore.get(nftIdSl2).ownerId()).isEqualTo(ownerId);
assertThat(writableNftStore.get(nftIdSl1).spenderId()).isEqualTo(spenderId);
assertThat(writableNftStore.get(nftIdSl2).spenderId()).isEqualTo(spenderId);

subject.handle(handleContext);

assertThat(ownerAccount.approveForAllNftAllowances()).hasSize(1);
assertThat(writableNftStore.get(nftIdSl1).ownerId()).isEqualTo(ownerId);
assertThat(writableNftStore.get(nftIdSl2).ownerId()).isEqualTo(ownerId);
// we expect the allowances to not be removed because of no op when list is empty
assertThat(writableNftStore.get(nftIdSl1).spenderId()).isNotNull();
assertThat(writableNftStore.get(nftIdSl2).spenderId()).isNotNull();
}

@Test
void canDeleteAllowancesOnTreasury() {
writableNftStore.put(nftSl1.copyBuilder().spenderId(spenderId).build());
Expand Down Expand Up @@ -157,6 +190,17 @@ void validateIfSerialsEmpty() {
.has(responseCode(EMPTY_ALLOWANCES));
}

@Test
void validateIfPureChecksDoesNotThrow() {
final var nftAllowance = NftRemoveAllowance.newBuilder()
.owner(payerId)
.tokenId(nonFungibleTokenId)
.serialNumbers(List.of(1L, 2L))
.build();
final var txn = allowancesTxn(payerId, List.of(nftAllowance));
assertDoesNotThrow(() -> subject.pureChecks(txn));
}

@Test
void checksEmptyAllowancesInTxn() {
final var txn = TransactionBody.newBuilder()
Expand Down Expand Up @@ -284,6 +328,59 @@ void considersPayerIfOwnerNotSpecified() {
assertThat(writableNftStore.get(nftIdSl2).spenderId()).isNull();
}

@Test
@DisplayName("check that fees are 1 for delete account allowance trx")
void testCalculateFeesReturnsCorrectFeeForDeleteAccountAllowance() {
final var feeCtx = mock(FeeContext.class);
final var feeCalcFact = mock(FeeCalculatorFactory.class);
final var feeCalc = mock(FeeCalculator.class);
final var txnBody = cryptoDeleteAllowanceTransaction(payerId);
given(feeCtx.feeCalculatorFactory()).willReturn(feeCalcFact);
given(feeCtx.body()).willReturn(txnBody);
given(feeCalcFact.feeCalculator(any())).willReturn(feeCalc);
given(feeCalc.addBytesPerTransaction(anyLong())).willReturn(feeCalc);
given(feeCalc.calculate()).willReturn(new Fees(1, 0, 0));

assertThat(subject.calculateFees(feeCtx)).isEqualTo(new Fees(1, 0, 0));
}

@Test
@DisplayName("calculate fees correctly considering bytes per transaction")
void testCalculateFeesConsideringBytesPerTransaction() {
final var feeCtx = mock(FeeContext.class);
final var feeCalcFact = mock(FeeCalculatorFactory.class);
final var feeCalc = mock(FeeCalculator.class);
final var txnBody = cryptoDeleteAllowanceTransaction(payerId);
given(feeCtx.feeCalculatorFactory()).willReturn(feeCalcFact);
given(feeCtx.body()).willReturn(txnBody);
given(feeCalcFact.feeCalculator(any())).willReturn(feeCalc);
final var cryptoDeleteAllowanceTransactionBody = txnBody.cryptoDeleteAllowanceOrThrow();
final var longSize = 8L;
final var nftDeleteAllowanceSize = 6 * longSize;
final var bytesPerTransaction =
cryptoDeleteAllowanceTransactionBody.nftAllowances().size() * nftDeleteAllowanceSize + (2 * longSize);
given(feeCalc.addBytesPerTransaction(bytesPerTransaction)).willReturn(feeCalc);
given(feeCalc.calculate()).willReturn(new Fees(1, 0, 0));

assertThat(subject.calculateFees(feeCtx)).isEqualTo(new Fees(1, 0, 0));
}

@Test
@DisplayName("check that fees are 1 for delete NFT serials trx")
void testCountNftDeleteSerials() {
final var feeCtx = mock(FeeContext.class);
final var feeCalcFact = mock(FeeCalculatorFactory.class);
final var feeCalc = mock(FeeCalculator.class);
final var txnBody = cryptoDeleteAllowanceTransaction(payerId);
given(feeCtx.feeCalculatorFactory()).willReturn(feeCalcFact);
given(feeCtx.body()).willReturn(txnBody);
given(feeCalcFact.feeCalculator(any())).willReturn(feeCalc);
given(feeCalc.addBytesPerTransaction(anyLong())).willReturn(feeCalc);
given(feeCalc.calculate()).willReturn(new Fees(1, 0, 0));

assertThat(subject.calculateFees(feeCtx)).isEqualTo(new Fees(1, 0, 0));
}

private TransactionBody cryptoDeleteAllowanceTransaction(final AccountID txnPayer) {
final var nftAllowance = NftRemoveAllowance.newBuilder()
.owner(ownerId)
Expand Down

0 comments on commit 2a82e0d

Please sign in to comment.