github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/token_airdrop_transaction_unit_test.go (about)

     1  //go:build all || unit
     2  // +build all unit
     3  
     4  package hedera
     5  
     6  /*-
     7   *
     8   * Hedera Go SDK
     9   *
    10   * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
    11   *
    12   * Licensed under the Apache License, Version 2.0 (the "License");
    13   * you may not use this file except in compliance with the License.
    14   * You may obtain a copy of the License at
    15   *
    16   *      http://www.apache.org/licenses/LICENSE-2.0
    17   *
    18   * Unless required by applicable law or agreed to in writing, software
    19   * distributed under the License is distributed on an "AS IS" BASIS,
    20   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    21   * See the License for the specific language governing permissions and
    22   * limitations under the License.
    23   *
    24   */
    25  
    26  import (
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/hashgraph/hedera-protobufs-go/services"
    31  	"github.com/stretchr/testify/assert"
    32  	"github.com/stretchr/testify/require"
    33  )
    34  
    35  func TestUnitTokenAirdropTransactionSetTokenTransferWithDecimals(t *testing.T) {
    36  	t.Parallel()
    37  
    38  	tokenID := TokenID{Token: 1}
    39  	senderAccountID := AccountID{Account: 2}
    40  	amount := int64(10)
    41  	decimals := uint32(5)
    42  
    43  	transaction := NewTokenAirdropTransaction().
    44  		AddTokenTransferWithDecimals(tokenID, senderAccountID, amount, decimals)
    45  
    46  	require.Equal(t, transaction.GetTokenIDDecimals()[tokenID], decimals)
    47  }
    48  
    49  func TestUnitTokenAirdropTransactionAddApprovedTokenTransferWithDecimals(t *testing.T) {
    50  	t.Parallel()
    51  
    52  	tokenID := TokenID{Token: 1}
    53  	accountID := AccountID{Account: 2}
    54  	amount := int64(100)
    55  	decimals := uint32(5)
    56  
    57  	transaction := NewTokenAirdropTransaction().
    58  		AddApprovedTokenTransferWithDecimals(tokenID, accountID, amount, decimals, true)
    59  
    60  	transfers := transaction.GetTokenTransfers()
    61  	require.NotNil(t, transfers)
    62  	require.Contains(t, transfers, tokenID)
    63  	require.Len(t, transfers[tokenID], 1)
    64  	assert.Equal(t, accountID, transfers[tokenID][0].AccountID)
    65  	assert.Equal(t, amount, transfers[tokenID][0].Amount)
    66  	assert.True(t, transfers[tokenID][0].IsApproved)
    67  	assert.Equal(t, decimals, transaction.GetTokenIDDecimals()[tokenID])
    68  }
    69  
    70  func TestUnitTokenAirdropTransactionValidate(t *testing.T) {
    71  	t.Parallel()
    72  
    73  	client, err := _NewMockClient()
    74  	client.SetLedgerID(*NewLedgerIDTestnet())
    75  	require.NoError(t, err)
    76  	client.SetAutoValidateChecksums(true)
    77  	accountID, err := AccountIDFromString("0.0.123-esxsf")
    78  	require.NoError(t, err)
    79  	nodeAccountIDs := []AccountID{{Account: 10}}
    80  	transactionID := TransactionIDGenerate(AccountID{Account: 123})
    81  
    82  	checksum := "dmqui"
    83  
    84  	token := TokenID{Token: 3, checksum: &checksum}
    85  	nft := NftID{TokenID: TokenID{Token: 3, checksum: &checksum}, SerialNumber: 1}
    86  	airdrop := NewTokenAirdropTransaction().
    87  		AddTokenTransfer(token, accountID, 100).
    88  		AddNftTransfer(nft, accountID, accountID).
    89  		SetTransactionID(transactionID).SetNodeAccountIDs(nodeAccountIDs).
    90  		SetMaxTransactionFee(HbarFromTinybar(100)).SetRegenerateTransactionID(true).
    91  		SetTransactionMemo("go sdk unit test").SetTransactionValidDuration(time.Second * 120).
    92  		SetMaxRetry(1).SetMaxBackoff(time.Second * 120).SetMinBackoff(time.Second * 1)
    93  
    94  	err = airdrop.validateNetworkOnIDs(client)
    95  	require.NoError(t, err)
    96  }
    97  
    98  func TestUnitTokenAirdropTransactionValidateWrong(t *testing.T) {
    99  	t.Parallel()
   100  
   101  	client, err := _NewMockClient()
   102  	client.SetLedgerID(*NewLedgerIDTestnet())
   103  	require.NoError(t, err)
   104  	client.SetAutoValidateChecksums(true)
   105  	accountID, err := AccountIDFromString("0.0.123-rmkykd")
   106  	require.NoError(t, err)
   107  
   108  	airdrop := NewTokenAirdropTransaction().
   109  		AddTokenTransfer(TokenID{Token: 1}, accountID, 100)
   110  
   111  	err = airdrop.validateNetworkOnIDs(client)
   112  	require.Error(t, err)
   113  }
   114  
   115  func TestUnitTokenAirdropTransactionAddTokenTransfer(t *testing.T) {
   116  	t.Parallel()
   117  
   118  	tokenID := TokenID{Token: 1}
   119  	accountID := AccountID{Account: 2}
   120  	amount := int64(100)
   121  
   122  	transaction := NewTokenAirdropTransaction().
   123  		AddTokenTransfer(tokenID, accountID, amount)
   124  
   125  	transfers := transaction.GetTokenTransfers()
   126  	require.NotNil(t, transfers)
   127  	require.Contains(t, transfers, tokenID)
   128  	require.Len(t, transfers[tokenID], 1)
   129  	assert.Equal(t, accountID, transfers[tokenID][0].AccountID)
   130  	assert.Equal(t, amount, transfers[tokenID][0].Amount)
   131  }
   132  
   133  func TestUnitTokenAirdropTransactionAddNftTransfer(t *testing.T) {
   134  	t.Parallel()
   135  
   136  	tokenID := TokenID{Token: 1}
   137  	serialNumber := int64(1)
   138  	nftID := NftID{TokenID: tokenID, SerialNumber: serialNumber}
   139  	sender := AccountID{Account: 2}
   140  	receiver := AccountID{Account: 3}
   141  
   142  	transaction := NewTokenAirdropTransaction().
   143  		AddNftTransfer(nftID, sender, receiver)
   144  
   145  	nftTransfers := transaction.GetNftTransfers()
   146  	require.NotNil(t, nftTransfers)
   147  	require.Contains(t, nftTransfers, tokenID)
   148  	require.Len(t, nftTransfers[tokenID], 1)
   149  	assert.Equal(t, sender, nftTransfers[tokenID][0].SenderAccountID)
   150  	assert.Equal(t, receiver, nftTransfers[tokenID][0].ReceiverAccountID)
   151  	assert.Equal(t, serialNumber, nftTransfers[tokenID][0].SerialNumber)
   152  }
   153  
   154  func TestUnitTokenAirdropTransactionSetTokenTransferApproval(t *testing.T) {
   155  	t.Parallel()
   156  
   157  	tokenID := TokenID{Token: 1}
   158  	accountID := AccountID{Account: 2}
   159  	amount := int64(100)
   160  
   161  	transaction := NewTokenAirdropTransaction().
   162  		AddTokenTransfer(tokenID, accountID, amount).
   163  		SetTokenTransferApproval(tokenID, accountID, true)
   164  
   165  	transfers := transaction.GetTokenTransfers()
   166  	require.NotNil(t, transfers)
   167  	require.Contains(t, transfers, tokenID)
   168  	require.Len(t, transfers[tokenID], 1)
   169  	assert.True(t, transfers[tokenID][0].IsApproved)
   170  }
   171  
   172  func TestUnitTokenAirdropTransactionSetNftTransferApproval(t *testing.T) {
   173  	t.Parallel()
   174  
   175  	tokenID := TokenID{Token: 1}
   176  	serialNumber := int64(1)
   177  	nftID := NftID{TokenID: tokenID, SerialNumber: serialNumber}
   178  	sender := AccountID{Account: 2}
   179  	receiver := AccountID{Account: 3}
   180  
   181  	transaction := NewTokenAirdropTransaction().
   182  		AddNftTransfer(nftID, sender, receiver).
   183  		SetNftTransferApproval(nftID, true)
   184  
   185  	nftTransfers := transaction.GetNftTransfers()
   186  	require.NotNil(t, nftTransfers)
   187  	require.Contains(t, nftTransfers, tokenID)
   188  	require.Len(t, nftTransfers[tokenID], 1)
   189  	assert.True(t, nftTransfers[tokenID][0].IsApproved)
   190  }
   191  
   192  func TestUnitTokenAirdropTransactionAddApprovedTokenTransfer(t *testing.T) {
   193  	t.Parallel()
   194  
   195  	tokenID := TokenID{Token: 1}
   196  	accountID := AccountID{Account: 2}
   197  	amount := int64(100)
   198  
   199  	transaction := NewTokenAirdropTransaction().
   200  		AddApprovedTokenTransfer(tokenID, accountID, amount, true)
   201  
   202  	transfers := transaction.GetTokenTransfers()
   203  	require.NotNil(t, transfers)
   204  	require.Contains(t, transfers, tokenID)
   205  	require.Len(t, transfers[tokenID], 1)
   206  	assert.Equal(t, accountID, transfers[tokenID][0].AccountID)
   207  	assert.Equal(t, amount, transfers[tokenID][0].Amount)
   208  	assert.True(t, transfers[tokenID][0].IsApproved)
   209  }
   210  
   211  func TestUnitTokenAirdropTransactionAddApprovedNftTransfer(t *testing.T) {
   212  	t.Parallel()
   213  
   214  	tokenID := TokenID{Token: 1}
   215  	serialNumber := int64(1)
   216  	nftID := NftID{TokenID: tokenID, SerialNumber: serialNumber}
   217  	sender := AccountID{Account: 2}
   218  	receiver := AccountID{Account: 3}
   219  
   220  	transaction := NewTokenAirdropTransaction().
   221  		AddApprovedNftTransfer(nftID, sender, receiver, true)
   222  
   223  	nftTransfers := transaction.GetNftTransfers()
   224  	require.NotNil(t, nftTransfers)
   225  	require.Contains(t, nftTransfers, tokenID)
   226  	require.Len(t, nftTransfers[tokenID], 1)
   227  	assert.Equal(t, sender, nftTransfers[tokenID][0].SenderAccountID)
   228  	assert.Equal(t, receiver, nftTransfers[tokenID][0].ReceiverAccountID)
   229  	assert.Equal(t, serialNumber, nftTransfers[tokenID][0].SerialNumber)
   230  	assert.True(t, nftTransfers[tokenID][0].IsApproved)
   231  }
   232  
   233  func TestUnitTokenAirdropTransactionToBytes(t *testing.T) {
   234  	t.Parallel()
   235  
   236  	tokenID := TokenID{Token: 1}
   237  	accountID := AccountID{Account: 2}
   238  	amount := int64(100)
   239  
   240  	transaction := NewTokenAirdropTransaction().
   241  		AddTokenTransfer(tokenID, accountID, amount)
   242  
   243  	bytes, err := transaction.ToBytes()
   244  	require.NoError(t, err)
   245  	require.NotNil(t, bytes)
   246  }
   247  
   248  func TestUnitTokenAirdropTransactionFromBytes(t *testing.T) {
   249  	t.Parallel()
   250  
   251  	tokenID := TokenID{Token: 1}
   252  	accountID := AccountID{Account: 2}
   253  	amount := int64(100)
   254  
   255  	transaction := NewTokenAirdropTransaction().
   256  		AddTokenTransfer(tokenID, accountID, amount)
   257  
   258  	bytes, err := transaction.ToBytes()
   259  	require.NoError(t, err)
   260  	require.NotNil(t, bytes)
   261  
   262  	deserializedTransaction, err := TransactionFromBytes(bytes)
   263  	require.NoError(t, err)
   264  
   265  	switch tx := deserializedTransaction.(type) {
   266  	case TokenAirdropTransaction:
   267  		assert.Equal(t, transaction.GetTokenTransfers(), tx.GetTokenTransfers())
   268  	default:
   269  		t.Fatalf("expected TokenAirdropTransaction, got %T", deserializedTransaction)
   270  	}
   271  }
   272  
   273  func TestUnitTokenAirdropTransactionScheduleProtobuf(t *testing.T) {
   274  	t.Parallel()
   275  
   276  	transactionID := TransactionIDGenerate(AccountID{Account: 324})
   277  
   278  	tokenID1 := TokenID{Token: 1}
   279  	tokenID2 := TokenID{Token: 2}
   280  	accountID1 := AccountID{Account: 1}
   281  	accountID2 := AccountID{Account: 2}
   282  	amount1 := int64(100)
   283  	amount2 := int64(200)
   284  	serialNumber1 := int64(1)
   285  	serialNumber2 := int64(2)
   286  
   287  	tx, err := NewTokenAirdropTransaction().
   288  		SetTransactionID(transactionID).
   289  		SetNodeAccountIDs(nodeAccountID).
   290  		AddTokenTransfer(tokenID1, accountID1, amount1).
   291  		AddTokenTransfer(tokenID2, accountID2, amount2).
   292  		AddNftTransfer(tokenID1.Nft(serialNumber1), accountID1, accountID2).
   293  		AddNftTransfer(tokenID2.Nft(serialNumber2), accountID2, accountID1).
   294  		Freeze()
   295  	require.NoError(t, err)
   296  
   297  	expected := &services.SchedulableTransactionBody{
   298  		TransactionFee: 100000000,
   299  		Data: &services.SchedulableTransactionBody_TokenAirdrop{
   300  			TokenAirdrop: &services.TokenAirdropTransactionBody{
   301  				TokenTransfers: []*services.TokenTransferList{
   302  					{
   303  						Token: tokenID1._ToProtobuf(),
   304  						Transfers: []*services.AccountAmount{
   305  							{
   306  								AccountID: accountID1._ToProtobuf(),
   307  								Amount:    amount1,
   308  							},
   309  						},
   310  					},
   311  					{
   312  						Token: tokenID2._ToProtobuf(),
   313  						Transfers: []*services.AccountAmount{
   314  							{
   315  								AccountID: accountID2._ToProtobuf(),
   316  								Amount:    amount2,
   317  							},
   318  						},
   319  					},
   320  					{
   321  						Token: tokenID1._ToProtobuf(),
   322  						NftTransfers: []*services.NftTransfer{
   323  							{
   324  								SenderAccountID:   accountID1._ToProtobuf(),
   325  								ReceiverAccountID: accountID2._ToProtobuf(),
   326  								SerialNumber:      serialNumber1,
   327  							},
   328  						},
   329  					},
   330  					{
   331  						Token: tokenID2._ToProtobuf(),
   332  						NftTransfers: []*services.NftTransfer{
   333  							{
   334  								SenderAccountID:   accountID2._ToProtobuf(),
   335  								ReceiverAccountID: accountID1._ToProtobuf(),
   336  								SerialNumber:      serialNumber2,
   337  							},
   338  						},
   339  					},
   340  				},
   341  			},
   342  		},
   343  	}
   344  
   345  	actual, err := tx.buildScheduled()
   346  	require.NoError(t, err)
   347  	require.ElementsMatch(t, expected.GetTokenAirdrop().TokenTransfers, actual.GetTokenAirdrop().TokenTransfers)
   348  }