github.com/Finschia/finschia-sdk@v0.48.1/x/bank/types/msgs_test.go (about)

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	sdk "github.com/Finschia/finschia-sdk/types"
    10  )
    11  
    12  func TestMsgSendRoute(t *testing.T) {
    13  	addr1 := sdk.AccAddress([]byte("from"))
    14  	addr2 := sdk.AccAddress([]byte("to"))
    15  	coins := sdk.NewCoins(sdk.NewInt64Coin("atom", 10))
    16  	msg := NewMsgSend(addr1, addr2, coins)
    17  
    18  	require.Equal(t, msg.Route(), RouterKey)
    19  	require.Equal(t, msg.Type(), "send")
    20  }
    21  
    22  func TestMsgSendValidation(t *testing.T) {
    23  	addr1 := sdk.AccAddress([]byte("from________________"))
    24  	addr2 := sdk.AccAddress([]byte("to__________________"))
    25  	addrEmpty := sdk.AccAddress([]byte(""))
    26  	addrLong := sdk.AccAddress([]byte("Purposefully long address"))
    27  
    28  	atom123 := sdk.NewCoins(sdk.NewInt64Coin("atom", 123))
    29  	atom0 := sdk.NewCoins(sdk.NewInt64Coin("atom", 0))
    30  	atom123eth123 := sdk.NewCoins(sdk.NewInt64Coin("atom", 123), sdk.NewInt64Coin("eth", 123))
    31  	atom123eth0 := sdk.Coins{sdk.NewInt64Coin("atom", 123), sdk.NewInt64Coin("eth", 0)}
    32  
    33  	cases := []struct {
    34  		expectedErr string // empty means no error expected
    35  		msg         *MsgSend
    36  	}{
    37  		{"", NewMsgSend(addr1, addr2, atom123)},                                // valid send
    38  		{"", NewMsgSend(addr1, addr2, atom123eth123)},                          // valid send with multiple coins
    39  		{"", NewMsgSend(addrLong, addr2, atom123)},                             // valid send with long addr sender
    40  		{"", NewMsgSend(addr1, addrLong, atom123)},                             // valid send with long addr recipient
    41  		{": invalid coins", NewMsgSend(addr1, addr2, atom0)},                   // non positive coin
    42  		{"123atom,0eth: invalid coins", NewMsgSend(addr1, addr2, atom123eth0)}, // non positive coin in multicoins
    43  		{"Invalid sender address (empty address string is not allowed): invalid address", NewMsgSend(addrEmpty, addr2, atom123)},
    44  		{"Invalid recipient address (empty address string is not allowed): invalid address", NewMsgSend(addr1, addrEmpty, atom123)},
    45  	}
    46  
    47  	for _, tc := range cases {
    48  		err := tc.msg.ValidateBasic()
    49  		if tc.expectedErr == "" {
    50  			require.Nil(t, err)
    51  		} else {
    52  			require.EqualError(t, err, tc.expectedErr)
    53  		}
    54  	}
    55  }
    56  
    57  func TestMsgSendGetSignBytes(t *testing.T) {
    58  	addr1 := sdk.AccAddress([]byte("input"))
    59  	addr2 := sdk.AccAddress([]byte("output"))
    60  	coins := sdk.NewCoins(sdk.NewInt64Coin("atom", 10))
    61  	msg := NewMsgSend(addr1, addr2, coins)
    62  	res := msg.GetSignBytes()
    63  
    64  	expected := `{"type":"cosmos-sdk/MsgSend","value":{"amount":[{"amount":"10","denom":"atom"}],"from_address":"link1d9h8qat5fnwd3e","to_address":"link1da6hgur4ws537sex"}}`
    65  	require.Equal(t, expected, string(res))
    66  }
    67  
    68  func TestMsgSendGetSigners(t *testing.T) {
    69  	msg := NewMsgSend(sdk.AccAddress([]byte("input111111111111111")), sdk.AccAddress{}, sdk.NewCoins())
    70  	res := msg.GetSigners()
    71  	// TODO: fix this !
    72  	require.Equal(t, fmt.Sprintf("%v", res), "[696E707574313131313131313131313131313131]")
    73  }
    74  
    75  func TestMsgMultiSendRoute(t *testing.T) {
    76  	// Construct a MsgSend
    77  	addr1 := sdk.AccAddress([]byte("input"))
    78  	addr2 := sdk.AccAddress([]byte("output"))
    79  	coins := sdk.NewCoins(sdk.NewInt64Coin("atom", 10))
    80  	msg := MsgMultiSend{
    81  		Inputs:  []Input{NewInput(addr1, coins)},
    82  		Outputs: []Output{NewOutput(addr2, coins)},
    83  	}
    84  
    85  	// TODO some failures for bad result
    86  	require.Equal(t, msg.Route(), RouterKey)
    87  	require.Equal(t, msg.Type(), "multisend")
    88  }
    89  
    90  func TestInputValidation(t *testing.T) {
    91  	addr1 := sdk.AccAddress([]byte("_______alice________"))
    92  	addr2 := sdk.AccAddress([]byte("________bob_________"))
    93  	addrEmpty := sdk.AccAddress([]byte(""))
    94  	addrLong := sdk.AccAddress([]byte("Purposefully long address"))
    95  
    96  	someCoins := sdk.NewCoins(sdk.NewInt64Coin("atom", 123))
    97  	multiCoins := sdk.NewCoins(sdk.NewInt64Coin("atom", 123), sdk.NewInt64Coin("eth", 20))
    98  
    99  	emptyCoins := sdk.NewCoins()
   100  	emptyCoins2 := sdk.NewCoins(sdk.NewInt64Coin("eth", 0))
   101  	someEmptyCoins := sdk.Coins{sdk.NewInt64Coin("eth", 10), sdk.NewInt64Coin("atom", 0)}
   102  	unsortedCoins := sdk.Coins{sdk.NewInt64Coin("eth", 1), sdk.NewInt64Coin("atom", 1)}
   103  
   104  	cases := []struct {
   105  		expectedErr string // empty means no error expected
   106  		txIn        Input
   107  	}{
   108  		// auth works with different apps
   109  		{"", NewInput(addr1, someCoins)},
   110  		{"", NewInput(addr2, someCoins)},
   111  		{"", NewInput(addr2, multiCoins)},
   112  		{"", NewInput(addrLong, someCoins)},
   113  
   114  		{"empty address string is not allowed", NewInput(addrEmpty, someCoins)},
   115  		{": invalid coins", NewInput(addr1, emptyCoins)},                // invalid coins
   116  		{": invalid coins", NewInput(addr1, emptyCoins2)},               // invalid coins
   117  		{"10eth,0atom: invalid coins", NewInput(addr1, someEmptyCoins)}, // invalid coins
   118  		{"1eth,1atom: invalid coins", NewInput(addr1, unsortedCoins)},   // unsorted coins
   119  	}
   120  
   121  	for i, tc := range cases {
   122  		err := tc.txIn.ValidateBasic()
   123  		if tc.expectedErr == "" {
   124  			require.Nil(t, err, "%d: %+v", i, err)
   125  		} else {
   126  			require.EqualError(t, err, tc.expectedErr, "%d", i)
   127  		}
   128  	}
   129  }
   130  
   131  func TestOutputValidation(t *testing.T) {
   132  	addr1 := sdk.AccAddress([]byte("_______alice________"))
   133  	addr2 := sdk.AccAddress([]byte("________bob_________"))
   134  	addrEmpty := sdk.AccAddress([]byte(""))
   135  	addrLong := sdk.AccAddress([]byte("Purposefully long address"))
   136  
   137  	someCoins := sdk.NewCoins(sdk.NewInt64Coin("atom", 123))
   138  	multiCoins := sdk.NewCoins(sdk.NewInt64Coin("atom", 123), sdk.NewInt64Coin("eth", 20))
   139  
   140  	emptyCoins := sdk.NewCoins()
   141  	emptyCoins2 := sdk.NewCoins(sdk.NewInt64Coin("eth", 0))
   142  	someEmptyCoins := sdk.Coins{sdk.NewInt64Coin("eth", 10), sdk.NewInt64Coin("atom", 0)}
   143  	unsortedCoins := sdk.Coins{sdk.NewInt64Coin("eth", 1), sdk.NewInt64Coin("atom", 1)}
   144  
   145  	cases := []struct {
   146  		expectedErr string // empty means no error expected
   147  		txOut       Output
   148  	}{
   149  		// auth works with different apps
   150  		{"", NewOutput(addr1, someCoins)},
   151  		{"", NewOutput(addr2, someCoins)},
   152  		{"", NewOutput(addr2, multiCoins)},
   153  		{"", NewOutput(addrLong, someCoins)},
   154  
   155  		{"Invalid output address (empty address string is not allowed): invalid address", NewOutput(addrEmpty, someCoins)},
   156  		{": invalid coins", NewOutput(addr1, emptyCoins)},                // invalid coins
   157  		{": invalid coins", NewOutput(addr1, emptyCoins2)},               // invalid coins
   158  		{"10eth,0atom: invalid coins", NewOutput(addr1, someEmptyCoins)}, // invalid coins
   159  		{"1eth,1atom: invalid coins", NewOutput(addr1, unsortedCoins)},   // unsorted coins
   160  	}
   161  
   162  	for i, tc := range cases {
   163  		err := tc.txOut.ValidateBasic()
   164  		if tc.expectedErr == "" {
   165  			require.Nil(t, err, "%d: %+v", i, err)
   166  		} else {
   167  			require.EqualError(t, err, tc.expectedErr, "%d", i)
   168  		}
   169  	}
   170  }
   171  
   172  func TestMsgMultiSendValidation(t *testing.T) {
   173  	addr1 := sdk.AccAddress([]byte("_______alice________"))
   174  	addr2 := sdk.AccAddress([]byte("________bob_________"))
   175  	atom123 := sdk.NewCoins(sdk.NewInt64Coin("atom", 123))
   176  	atom124 := sdk.NewCoins(sdk.NewInt64Coin("atom", 124))
   177  	eth123 := sdk.NewCoins(sdk.NewInt64Coin("eth", 123))
   178  	atom123eth123 := sdk.NewCoins(sdk.NewInt64Coin("atom", 123), sdk.NewInt64Coin("eth", 123))
   179  
   180  	input1 := NewInput(addr1, atom123)
   181  	input2 := NewInput(addr1, eth123)
   182  	output1 := NewOutput(addr2, atom123)
   183  	output2 := NewOutput(addr2, atom124)
   184  	outputMulti := NewOutput(addr2, atom123eth123)
   185  
   186  	var emptyAddr sdk.AccAddress
   187  
   188  	cases := []struct {
   189  		valid bool
   190  		tx    MsgMultiSend
   191  	}{
   192  		{false, MsgMultiSend{}},                           // no input or output
   193  		{false, MsgMultiSend{Inputs: []Input{input1}}},    // just input
   194  		{false, MsgMultiSend{Outputs: []Output{output1}}}, // just output
   195  		{false, MsgMultiSend{
   196  			Inputs:  []Input{NewInput(emptyAddr, atom123)}, // invalid input
   197  			Outputs: []Output{output1},
   198  		}},
   199  		{
   200  			false, MsgMultiSend{
   201  				Inputs:  []Input{input1},
   202  				Outputs: []Output{{emptyAddr.String(), atom123}},
   203  			}, // invalid output
   204  		},
   205  		{
   206  			false, MsgMultiSend{
   207  				Inputs:  []Input{input1},
   208  				Outputs: []Output{output2},
   209  			}, // amounts dont match
   210  		},
   211  		{
   212  			true, MsgMultiSend{
   213  				Inputs:  []Input{input1},
   214  				Outputs: []Output{output1},
   215  			},
   216  		},
   217  		{
   218  			true, MsgMultiSend{
   219  				Inputs:  []Input{input1, input2},
   220  				Outputs: []Output{outputMulti},
   221  			},
   222  		},
   223  	}
   224  
   225  	for i, tc := range cases {
   226  		err := tc.tx.ValidateBasic()
   227  		if tc.valid {
   228  			require.Nil(t, err, "%d: %+v", i, err)
   229  		} else {
   230  			require.NotNil(t, err, "%d", i)
   231  		}
   232  	}
   233  }
   234  
   235  func TestMsgMultiSendGetSignBytes(t *testing.T) {
   236  	addr1 := sdk.AccAddress([]byte("input"))
   237  	addr2 := sdk.AccAddress([]byte("output"))
   238  	coins := sdk.NewCoins(sdk.NewInt64Coin("atom", 10))
   239  	msg := MsgMultiSend{
   240  		Inputs:  []Input{NewInput(addr1, coins)},
   241  		Outputs: []Output{NewOutput(addr2, coins)},
   242  	}
   243  	res := msg.GetSignBytes()
   244  
   245  	expected := `{"type":"cosmos-sdk/MsgMultiSend","value":{"inputs":[{"address":"link1d9h8qat5fnwd3e","coins":[{"amount":"10","denom":"atom"}]}],"outputs":[{"address":"link1da6hgur4ws537sex","coins":[{"amount":"10","denom":"atom"}]}]}}`
   246  	require.Equal(t, expected, string(res))
   247  }
   248  
   249  func TestMsgMultiSendGetSigners(t *testing.T) {
   250  	msg := MsgMultiSend{
   251  		Inputs: []Input{
   252  			NewInput(sdk.AccAddress([]byte("input111111111111111")), nil),
   253  			NewInput(sdk.AccAddress([]byte("input222222222222222")), nil),
   254  			NewInput(sdk.AccAddress([]byte("input333333333333333")), nil),
   255  		},
   256  	}
   257  
   258  	res := msg.GetSigners()
   259  	// TODO: fix this !
   260  	require.Equal(t, "[696E707574313131313131313131313131313131 696E707574323232323232323232323232323232 696E707574333333333333333333333333333333]", fmt.Sprintf("%v", res))
   261  }
   262  
   263  func TestMsgSendSigners(t *testing.T) {
   264  	signers := []sdk.AccAddress{
   265  		{1, 2, 3},
   266  		{4, 5, 6},
   267  		{7, 8, 9},
   268  	}
   269  
   270  	someCoins := sdk.NewCoins(sdk.NewInt64Coin("atom", 123))
   271  	inputs := make([]Input, len(signers))
   272  	for i, signer := range signers {
   273  		inputs[i] = NewInput(signer, someCoins)
   274  	}
   275  	tx := NewMsgMultiSend(inputs, nil)
   276  
   277  	require.Equal(t, signers, tx.GetSigners())
   278  }