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

     1  package authz_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	cdctypes "github.com/Finschia/finschia-sdk/codec/types"
    10  	sdk "github.com/Finschia/finschia-sdk/types"
    11  	"github.com/Finschia/finschia-sdk/x/auth/legacy/legacytx"
    12  	"github.com/Finschia/finschia-sdk/x/authz"
    13  	banktypes "github.com/Finschia/finschia-sdk/x/bank/types"
    14  	stakingtypes "github.com/Finschia/finschia-sdk/x/staking/types"
    15  )
    16  
    17  var (
    18  	coinsPos = sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
    19  	granter  = sdk.AccAddress("_______granter______")
    20  	grantee  = sdk.AccAddress("_______grantee______")
    21  )
    22  
    23  func TestMsgExecAuthorized(t *testing.T) {
    24  	tests := []struct {
    25  		title      string
    26  		grantee    sdk.AccAddress
    27  		msgs       []sdk.Msg
    28  		expectPass bool
    29  	}{
    30  		{"nil grantee address", nil, []sdk.Msg{}, false},
    31  		{"zero-messages test: should fail", grantee, []sdk.Msg{}, false},
    32  		{"valid test: msg type", grantee, []sdk.Msg{
    33  			&banktypes.MsgSend{
    34  				Amount:      sdk.NewCoins(sdk.NewInt64Coin("steak", 2)),
    35  				FromAddress: granter.String(),
    36  				ToAddress:   grantee.String(),
    37  			},
    38  		}, true},
    39  	}
    40  	for i, tc := range tests {
    41  		msg := authz.NewMsgExec(tc.grantee, tc.msgs)
    42  		if tc.expectPass {
    43  			require.NoError(t, msg.ValidateBasic(), "test: %v", i)
    44  		} else {
    45  			require.Error(t, msg.ValidateBasic(), "test: %v", i)
    46  		}
    47  	}
    48  }
    49  
    50  func TestMsgRevokeAuthorization(t *testing.T) {
    51  	tests := []struct {
    52  		title            string
    53  		granter, grantee sdk.AccAddress
    54  		msgType          string
    55  		expectPass       bool
    56  	}{
    57  		{"nil Granter address", nil, grantee, "hello", false},
    58  		{"nil Grantee address", granter, nil, "hello", false},
    59  		{"nil Granter and Grantee address", nil, nil, "hello", false},
    60  		{"valid test case", granter, grantee, "hello", true},
    61  	}
    62  	for i, tc := range tests {
    63  		msg := authz.NewMsgRevoke(tc.granter, tc.grantee, tc.msgType)
    64  		if tc.expectPass {
    65  			require.NoError(t, msg.ValidateBasic(), "test: %v", i)
    66  		} else {
    67  			require.Error(t, msg.ValidateBasic(), "test: %v", i)
    68  		}
    69  	}
    70  }
    71  
    72  func TestMsgGrantAuthorization(t *testing.T) {
    73  	tests := []struct {
    74  		title            string
    75  		granter, grantee sdk.AccAddress
    76  		authorization    authz.Authorization
    77  		expiration       time.Time
    78  		expectErr        bool
    79  		expectPass       bool
    80  	}{
    81  		{"nil granter address", nil, grantee, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now(), false, false},
    82  		{"nil grantee address", granter, nil, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now(), false, false},
    83  		{"nil granter and grantee address", nil, nil, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now(), false, false},
    84  		{"nil authorization", granter, grantee, nil, time.Now(), true, false},
    85  		{"valid test case", granter, grantee, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now().AddDate(0, 1, 0), false, true},
    86  		{"past time", granter, grantee, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now().AddDate(0, 0, -1), false, true}, // TODO need 0.45
    87  	}
    88  	for i, tc := range tests {
    89  		msg, err := authz.NewMsgGrant(
    90  			tc.granter, tc.grantee, tc.authorization, tc.expiration,
    91  		)
    92  		if !tc.expectErr {
    93  			require.NoError(t, err)
    94  		} else {
    95  			continue
    96  		}
    97  		if tc.expectPass {
    98  			require.NoError(t, msg.ValidateBasic(), "test: %v", i)
    99  		} else {
   100  			require.Error(t, msg.ValidateBasic(), "test: %v", i)
   101  		}
   102  	}
   103  }
   104  
   105  func TestMsgGrantGetAuthorization(t *testing.T) {
   106  	require := require.New(t)
   107  
   108  	m := authz.MsgGrant{}
   109  	require.Nil(m.GetAuthorization())
   110  
   111  	g := authz.GenericAuthorization{Msg: "some_type"}
   112  	var err error
   113  	m.Grant.Authorization, err = cdctypes.NewAnyWithValue(&g)
   114  	require.NoError(err)
   115  	require.Equal(m.GetAuthorization(), &g)
   116  
   117  	g = authz.GenericAuthorization{Msg: "some_type2"}
   118  	m.SetAuthorization(&g)
   119  	require.Equal(m.GetAuthorization(), &g)
   120  }
   121  
   122  func TestAminoJSON(t *testing.T) {
   123  	tx := legacytx.StdTx{}
   124  	var msg legacytx.LegacyMsg
   125  	someDate := time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC)
   126  	msgSend := banktypes.MsgSend{FromAddress: "link1ghi", ToAddress: "link1jkl"}
   127  	typeURL := sdk.MsgTypeURL(&msgSend)
   128  	msgSendAny, err := cdctypes.NewAnyWithValue(&msgSend)
   129  	require.NoError(t, err)
   130  	grant, err := authz.NewGrant(someDate, authz.NewGenericAuthorization(typeURL), someDate.Add(time.Hour))
   131  	require.NoError(t, err)
   132  	sendGrant, err := authz.NewGrant(someDate, banktypes.NewSendAuthorization(sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000)))), someDate.Add(time.Hour))
   133  	require.NoError(t, err)
   134  	valAddr, err := sdk.ValAddressFromBech32("linkvaloper1hcnhauxt4crgz04zwvdl60a9pk9wzzqe8uelc0")
   135  	require.NoError(t, err)
   136  	stakingAuth, err := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{valAddr}, nil, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &sdk.Coin{Denom: "stake", Amount: sdk.NewInt(1000)})
   137  	require.NoError(t, err)
   138  	delegateGrant, err := authz.NewGrant(someDate, stakingAuth, someDate.Add(time.Hour))
   139  	require.NoError(t, err)
   140  
   141  	// Amino JSON encoding has changed in authz since v0.46.
   142  	// Before, it was outputting something like:
   143  	// `{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"grant":{"authorization":{"msg":"/cosmos.bank.v1beta1.MsgSend"},"expiration":"0001-01-01T02:01:01.000000001Z"},"grantee":"link1def","granter":"link1abc"}],"sequence":"1","timeout_height":"1"}`
   144  	//
   145  	// This was a bug. Now, it's as below, See how there's `type` & `value` fields.
   146  	// ref: https://github.com/cosmos/cosmos-sdk/issues/11190
   147  	// ref: https://github.com/cosmos/cosmjs/issues/1026
   148  	msg = &authz.MsgGrant{Granter: "link1abc", Grantee: "link1def", Grant: grant}
   149  	tx.Msgs = []sdk.Msg{msg}
   150  	require.Equal(t,
   151  		`{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgGrant","value":{"grant":{"authorization":{"type":"cosmos-sdk/GenericAuthorization","value":{"msg":"/cosmos.bank.v1beta1.MsgSend"}},"expiration":"0001-01-01T02:01:01.000000001Z"},"grantee":"link1def","granter":"link1abc"}}],"sequence":"1","timeout_height":"1"}`,
   152  		string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{msg}, "memo")),
   153  	)
   154  
   155  	msg = &authz.MsgGrant{Granter: "link1abc", Grantee: "link1def", Grant: sendGrant}
   156  	tx.Msgs = []sdk.Msg{msg}
   157  	require.Equal(t,
   158  		`{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgGrant","value":{"grant":{"authorization":{"type":"cosmos-sdk/SendAuthorization","value":{"spend_limit":[{"amount":"1000","denom":"stake"}]}},"expiration":"0001-01-01T02:01:01.000000001Z"},"grantee":"link1def","granter":"link1abc"}}],"sequence":"1","timeout_height":"1"}`,
   159  		string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{msg}, "memo")),
   160  	)
   161  
   162  	msg = &authz.MsgGrant{Granter: "link1abc", Grantee: "link1def", Grant: delegateGrant}
   163  	tx.Msgs = []sdk.Msg{msg}
   164  	require.Equal(t,
   165  		`{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgGrant","value":{"grant":{"authorization":{"type":"cosmos-sdk/StakeAuthorization","value":{"Validators":{"type":"cosmos-sdk/StakeAuthorization/AllowList","value":{"allow_list":{"address":["linkvaloper1hcnhauxt4crgz04zwvdl60a9pk9wzzqe8uelc0"]}}},"authorization_type":1,"max_tokens":{"amount":"1000","denom":"stake"}}},"expiration":"0001-01-01T02:01:01.000000001Z"},"grantee":"link1def","granter":"link1abc"}}],"sequence":"1","timeout_height":"1"}`,
   166  		string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{msg}, "memo")),
   167  	)
   168  
   169  	msg = &authz.MsgRevoke{Granter: "link1abc", Grantee: "link1def", MsgTypeUrl: typeURL}
   170  	tx.Msgs = []sdk.Msg{msg}
   171  	require.Equal(t,
   172  		`{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgRevoke","value":{"grantee":"link1def","granter":"link1abc","msg_type_url":"/cosmos.bank.v1beta1.MsgSend"}}],"sequence":"1","timeout_height":"1"}`,
   173  		string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{msg}, "memo")),
   174  	)
   175  
   176  	msg = &authz.MsgExec{Grantee: "link1def", Msgs: []*cdctypes.Any{msgSendAny}}
   177  	tx.Msgs = []sdk.Msg{msg}
   178  	require.Equal(t,
   179  		`{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgExec","value":{"grantee":"link1def","msgs":[{"type":"cosmos-sdk/MsgSend","value":{"amount":[],"from_address":"link1ghi","to_address":"link1jkl"}}]}}],"sequence":"1","timeout_height":"1"}`,
   180  		string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{msg}, "memo")),
   181  	)
   182  }