Skip to content

Commit

Permalink
fix: add tests to address PR comments
Browse files Browse the repository at this point in the history
Signed-off-by: Stanimir Stoyanov <[email protected]>
  • Loading branch information
stoyanov-st committed Jan 22, 2025
1 parent e5fa1c6 commit f3c676c
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2024 Hedera Hashgraph, LLC
* Copyright (C) 2024-2025 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -92,11 +92,14 @@ public class TokenAirdropDecoderTest {
private final TokenAirdropTransactionBody nftAirdrop = TokenAirdropTransactionBody.newBuilder()
.tokenTransfers(TokenTransferList.newBuilder()
.token(NON_FUNGIBLE_TOKEN_ID)
.nftTransfers(NftTransfer.newBuilder()
.senderAccountID(SENDER_ID)
.receiverAccountID(OWNER_ID)
.serialNumber(1)
.build())
.nftTransfers(nftTransfer(1))
.build())
.build();

private final TokenAirdropTransactionBody nftAirdrops = TokenAirdropTransactionBody.newBuilder()
.tokenTransfers(TokenTransferList.newBuilder()
.token(NON_FUNGIBLE_TOKEN_ID)
.nftTransfers(nftTransfer(1), nftTransfer(2), nftTransfer(3))
.build())
.build();

Expand Down Expand Up @@ -273,6 +276,29 @@ void tokenAirdropDecoderWorksForNFT() {
assertEquals(nftAirdrop, body.tokenAirdrop());
}

@Test
void tokenAirdropDecoderWorksForMultipleNFTs() {
final var tuple = new Tuple[] {
Tuple.of(NON_FUNGIBLE_TOKEN_HEADLONG_ADDRESS, new Tuple[] {}, new Tuple[] {
Tuple.of(asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, 1L, false),
Tuple.of(asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, 2L, false),
Tuple.of(asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, 3L, false)
})
};
final var encoded = Bytes.wrapByteBuffer(TOKEN_AIRDROP.encodeCall(Tuple.singleton(tuple)));
given(attempt.inputBytes()).willReturn(encoded.toArrayUnsafe());
given(attempt.configuration()).willReturn(configuration);
given(attempt.addressIdConverter()).willReturn(addressIdConverter);
given(configuration.getConfigData(LedgerConfig.class)).willReturn(ledgerConfig);
given(ledgerConfig.tokenTransfersMaxLen()).willReturn(10);
given(ledgerConfig.nftTransfersMaxLen()).willReturn(10);
final var body = subject.decodeAirdrop(attempt);
assertNotNull(body);
assertNotNull(body.tokenAirdrop());
assertNotNull(body.tokenAirdrop().tokenTransfers());
assertEquals(nftAirdrops, body.tokenAirdrop());
}

@Test
void tokenAirdropDecoderForNFTFailsIfNftExceedLimits() {
final var tuple = new Tuple[] {
Expand Down Expand Up @@ -301,4 +327,12 @@ void tokenAirdropDecoderForNFTFailsIfNftExceedLimits() {
.isThrownBy(() -> subject.decodeAirdrop(attempt))
.withMessage(TOKEN_REFERENCE_LIST_SIZE_LIMIT_EXCEEDED.protoName());
}

private NftTransfer nftTransfer(final long serial) {
return NftTransfer.newBuilder()
.senderAccountID(SENDER_ID)
.receiverAccountID(OWNER_ID)
.serialNumber(serial)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import static com.hedera.services.bdd.junit.TestTags.SMART_CONTRACT;
import static com.hedera.services.bdd.spec.HapiSpec.hapiTest;
import static com.hedera.services.bdd.spec.transactions.TxnVerbs.burnToken;
import static com.hedera.services.bdd.spec.utilops.CustomSpecAssert.allRunFor;
import static com.hedera.services.bdd.spec.utilops.UtilVerbs.withOpContext;
import static com.hedera.services.bdd.suites.contract.precompile.airdrops.SystemContractAirdropHelper.prepareAccountAddresses;
Expand All @@ -42,6 +43,7 @@
import com.hedera.services.bdd.spec.dsl.entities.SpecFungibleToken;
import com.hedera.services.bdd.spec.dsl.entities.SpecNonFungibleToken;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -596,4 +598,49 @@ public Stream<DynamicTest> distributeNftsOutOfBound(
receiver9.getBalance().andAssert(balance -> balance.hasTokenBalance(nft.name(), 0L)));
}));
}

@HapiTest
@Order(14)
@DisplayName("Cannot distribute NFTs to multiple accounts when some of the NFTs do not exist")
public Stream<DynamicTest> failToDistributeNfts(
@NonNull @NonFungibleToken(numPreMints = 6) final SpecNonFungibleToken nft,
@NonNull @Account(maxAutoAssociations = -1) final SpecAccount receiver1,
@NonNull @Account(maxAutoAssociations = -1) final SpecAccount receiver2,
@NonNull @Account(maxAutoAssociations = -1) final SpecAccount receiver3,
@NonNull @Account(maxAutoAssociations = -1) final SpecAccount receiver4,
@NonNull @Account(maxAutoAssociations = -1) final SpecAccount receiver5,
@NonNull @Account(maxAutoAssociations = -1) final SpecAccount receiver6) {
return hapiTest(withOpContext((spec, opLog) -> {
allRunFor(
spec,
sender.associateTokens(nft),
// We have six pre minted serials
// Burning some of them to make them invalid
burnToken(nft.name(), List.of(3L, 4L)),
receiver1.getBalance().andAssert(balance -> balance.hasTokenBalance(nft.name(), 0L)),
receiver2.getBalance().andAssert(balance -> balance.hasTokenBalance(nft.name(), 0L)),
receiver3.getBalance().andAssert(balance -> balance.hasTokenBalance(nft.name(), 0L)),
receiver4.getBalance().andAssert(balance -> balance.hasTokenBalance(nft.name(), 0L)),
receiver5.getBalance().andAssert(balance -> balance.hasTokenBalance(nft.name(), 0L)),
receiver6.getBalance().andAssert(balance -> balance.hasTokenBalance(nft.name(), 0L)),
receiver1.getInfo(),
receiver1.getInfo(),
receiver3.getInfo(),
receiver4.getInfo(),
receiver5.getInfo(),
receiver6.getInfo(),
nft.treasury().transferNFTsTo(sender, nft, 1L, 2L, 5L, 6L));
allRunFor(
spec,
airdropContract
.call(
"nftAirdropDistribute",
nft,
sender,
prepareAccountAddresses(
spec, receiver1, receiver2, receiver3, receiver4, receiver5, receiver6))
.gas(1500000)
.andAssert(txn -> txn.hasKnownStatuses(CONTRACT_REVERT_EXECUTED, INVALID_NFT_ID)));
}));
}
}

0 comments on commit f3c676c

Please sign in to comment.