github.com/cosmos/cosmos-sdk@v0.50.10/x/group/client/cli/tx_test.go (about)

     1  package cli_test
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"testing"
     9  
    10  	abci "github.com/cometbft/cometbft/abci/types"
    11  	rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock"
    12  	"github.com/stretchr/testify/suite"
    13  
    14  	// without this import amino json encoding will fail when resolving any types
    15  	_ "cosmossdk.io/api/cosmos/group/v1"
    16  	sdkmath "cosmossdk.io/math"
    17  
    18  	"github.com/cosmos/cosmos-sdk/client"
    19  	"github.com/cosmos/cosmos-sdk/client/flags"
    20  	"github.com/cosmos/cosmos-sdk/codec/address"
    21  	"github.com/cosmos/cosmos-sdk/crypto/hd"
    22  	"github.com/cosmos/cosmos-sdk/crypto/keyring"
    23  	svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
    24  	"github.com/cosmos/cosmos-sdk/testutil"
    25  	clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
    26  	sdk "github.com/cosmos/cosmos-sdk/types"
    27  	testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil"
    28  	"github.com/cosmos/cosmos-sdk/x/group"
    29  	groupcli "github.com/cosmos/cosmos-sdk/x/group/client/cli"
    30  	groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
    31  )
    32  
    33  var validMetadata = "metadata"
    34  
    35  type CLITestSuite struct {
    36  	suite.Suite
    37  
    38  	kr          keyring.Keyring
    39  	encCfg      testutilmod.TestEncodingConfig
    40  	baseCtx     client.Context
    41  	clientCtx   client.Context
    42  	group       *group.GroupInfo
    43  	commonFlags []string
    44  }
    45  
    46  func TestCLITestSuite(t *testing.T) {
    47  	suite.Run(t, new(CLITestSuite))
    48  }
    49  
    50  func (s *CLITestSuite) SetupSuite() {
    51  	s.encCfg = testutilmod.MakeTestEncodingConfig(groupmodule.AppModuleBasic{})
    52  	s.kr = keyring.NewInMemory(s.encCfg.Codec)
    53  	s.baseCtx = client.Context{}.
    54  		WithKeyring(s.kr).
    55  		WithTxConfig(s.encCfg.TxConfig).
    56  		WithCodec(s.encCfg.Codec).
    57  		WithClient(clitestutil.MockCometRPC{Client: rpcclientmock.Client{}}).
    58  		WithAccountRetriever(client.MockAccountRetriever{}).
    59  		WithOutput(io.Discard).
    60  		WithChainID("test-chain")
    61  
    62  	s.commonFlags = []string{
    63  		fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
    64  		fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
    65  		fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
    66  	}
    67  
    68  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
    69  	val := accounts[0]
    70  
    71  	ctxGen := func() client.Context {
    72  		bz, _ := s.encCfg.Codec.Marshal(&sdk.TxResponse{})
    73  		c := clitestutil.NewMockCometRPC(abci.ResponseQuery{
    74  			Value: bz,
    75  		})
    76  		return s.baseCtx.WithClient(c)
    77  	}
    78  	s.clientCtx = ctxGen()
    79  
    80  	// create a new account
    81  	info, _, err := s.clientCtx.Keyring.NewMnemonic("NewValidator", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
    82  	s.Require().NoError(err)
    83  
    84  	pk, err := info.GetPubKey()
    85  	s.Require().NoError(err)
    86  
    87  	account := sdk.AccAddress(pk.Address())
    88  	_, err = clitestutil.MsgSendExec(
    89  		s.clientCtx,
    90  		val.Address,
    91  		account,
    92  		sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(2000))), address.NewBech32Codec("cosmos"), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
    93  		fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
    94  		fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
    95  	)
    96  	s.Require().NoError(err)
    97  
    98  	// create a group
    99  	validMembers := fmt.Sprintf(`
   100  	{
   101  		"members": [
   102  			{
   103  				"address": "%s",
   104  				"weight": "3",
   105  				"metadata": "%s"
   106  			}
   107  		]
   108  	}`, val.Address.String(), validMetadata)
   109  	validMembersFile := testutil.WriteToNewTempFile(s.T(), validMembers)
   110  	out, err := clitestutil.ExecTestCLICmd(s.clientCtx, groupcli.MsgCreateGroupCmd(),
   111  		append(
   112  			[]string{
   113  				val.Address.String(),
   114  				validMetadata,
   115  				validMembersFile.Name(),
   116  			},
   117  			s.commonFlags...,
   118  		),
   119  	)
   120  
   121  	s.Require().NoError(err, out.String())
   122  	txResp := sdk.TxResponse{}
   123  	s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String())
   124  	s.Require().Equal(uint32(0), txResp.Code, out.String())
   125  
   126  	s.group = &group.GroupInfo{Id: 1, Admin: val.Address.String(), Metadata: validMetadata, TotalWeight: "3", Version: 1}
   127  }
   128  
   129  func (s *CLITestSuite) TestTxCreateGroup() {
   130  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
   131  
   132  	cmd := groupcli.MsgCreateGroupCmd()
   133  	cmd.SetOutput(io.Discard)
   134  
   135  	validMembers := fmt.Sprintf(`{"members": [{
   136  		"address": "%s",
   137  		  "weight": "1",
   138  		  "metadata": "%s"
   139  	  }]}`, accounts[0].Address.String(), validMetadata)
   140  	validMembersFile := testutil.WriteToNewTempFile(s.T(), validMembers)
   141  
   142  	invalidMembersWeight := fmt.Sprintf(`{"members": [{
   143  			"address": "%s",
   144  			  "weight": "0"
   145  		  }]}`, accounts[0].Address.String())
   146  	invalidMembersWeightFile := testutil.WriteToNewTempFile(s.T(), invalidMembersWeight)
   147  
   148  	testCases := []struct {
   149  		name         string
   150  		args         []string
   151  		expCmdOutput string
   152  		expectErrMsg string
   153  	}{
   154  		{
   155  			name: "correct data",
   156  			args: append(
   157  				[]string{
   158  					accounts[0].Address.String(),
   159  					"",
   160  					validMembersFile.Name(),
   161  				},
   162  				s.commonFlags...,
   163  			),
   164  			expCmdOutput: fmt.Sprintf("%s %s %s", accounts[0].Address.String(), "", validMembersFile.Name()),
   165  			expectErrMsg: "",
   166  		},
   167  		{
   168  			"with amino-json",
   169  			append(
   170  				[]string{
   171  					accounts[0].Address.String(),
   172  					"",
   173  					validMembersFile.Name(),
   174  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   175  				},
   176  				s.commonFlags...,
   177  			),
   178  			fmt.Sprintf("%s %s %s", accounts[0].Address.String(), "", validMembersFile.Name()),
   179  			"",
   180  		},
   181  		{
   182  			"invalid members weight",
   183  			append(
   184  				[]string{
   185  					accounts[0].Address.String(),
   186  					"null",
   187  					invalidMembersWeightFile.Name(),
   188  				},
   189  				s.commonFlags...,
   190  			),
   191  			"",
   192  			"weight must be positive",
   193  		},
   194  		{
   195  			"no member provided",
   196  			append(
   197  				[]string{
   198  					accounts[0].Address.String(),
   199  					"null",
   200  					"doesnotexist.json",
   201  				},
   202  				s.commonFlags...,
   203  			),
   204  			"",
   205  			"no such file or directory",
   206  		},
   207  	}
   208  
   209  	for _, tc := range testCases {
   210  		tc := tc
   211  
   212  		s.Run(tc.name, func() {
   213  			ctx := svrcmd.CreateExecuteContext(context.Background())
   214  			cmd.SetContext(ctx)
   215  			cmd.SetArgs(tc.args)
   216  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
   217  
   218  			if len(tc.args) != 0 {
   219  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
   220  			}
   221  
   222  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
   223  			if tc.expectErrMsg != "" {
   224  				s.Require().Error(err)
   225  				s.Require().Contains(out.String(), tc.expectErrMsg)
   226  			} else {
   227  				s.Require().NoError(err)
   228  				msg := &sdk.TxResponse{}
   229  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
   230  			}
   231  		})
   232  	}
   233  }
   234  
   235  func (s *CLITestSuite) TestTxUpdateGroupAdmin() {
   236  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 2)
   237  
   238  	cmd := groupcli.MsgUpdateGroupAdminCmd()
   239  	cmd.SetOutput(io.Discard)
   240  
   241  	ctx := svrcmd.CreateExecuteContext(context.Background())
   242  	cmd.SetContext(ctx)
   243  	s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
   244  
   245  	groupIDs := make([]string, 2)
   246  	for i := 0; i < 2; i++ {
   247  		validMembers := fmt.Sprintf(`{"members": [{
   248  	  "address": "%s",
   249  		"weight": "1",
   250  		"metadata": "%s"
   251  	}]}`, accounts[0].Address.String(), validMetadata)
   252  		validMembersFile := testutil.WriteToNewTempFile(s.T(), validMembers)
   253  		out, err := clitestutil.ExecTestCLICmd(s.baseCtx, groupcli.MsgCreateGroupCmd(),
   254  			append(
   255  				[]string{
   256  					accounts[0].Address.String(),
   257  					validMetadata,
   258  					validMembersFile.Name(),
   259  				},
   260  				s.commonFlags...,
   261  			),
   262  		)
   263  		s.Require().NoError(err, out.String())
   264  		groupIDs[i] = fmt.Sprintf("%d", i+1)
   265  	}
   266  
   267  	testCases := []struct {
   268  		name         string
   269  		ctxGen       func() client.Context
   270  		args         []string
   271  		expCmdOutput string
   272  		expectErrMsg string
   273  	}{
   274  		{
   275  			"correct data",
   276  			func() client.Context {
   277  				bz, _ := s.encCfg.Codec.Marshal(&sdk.TxResponse{})
   278  				c := clitestutil.NewMockCometRPC(abci.ResponseQuery{
   279  					Value: bz,
   280  				})
   281  				return s.baseCtx.WithClient(c)
   282  			},
   283  			append(
   284  				[]string{
   285  					accounts[0].Address.String(),
   286  					groupIDs[0],
   287  					accounts[1].Address.String(),
   288  				},
   289  				s.commonFlags...,
   290  			),
   291  			fmt.Sprintf("%s %s %s", accounts[0].Address.String(), groupIDs[0], accounts[1].Address.String()),
   292  			"",
   293  		},
   294  		{
   295  			"with amino-json",
   296  			func() client.Context {
   297  				bz, _ := s.encCfg.Codec.Marshal(&sdk.TxResponse{})
   298  				c := clitestutil.NewMockCometRPC(abci.ResponseQuery{
   299  					Value: bz,
   300  				})
   301  				return s.baseCtx.WithClient(c)
   302  			},
   303  			append(
   304  				[]string{
   305  					accounts[0].Address.String(),
   306  					groupIDs[1],
   307  					accounts[1].Address.String(),
   308  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   309  				},
   310  				s.commonFlags...,
   311  			),
   312  			fmt.Sprintf("%s %s %s --%s=%s", accounts[0].Address.String(), groupIDs[1], accounts[1].Address.String(), flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   313  			"",
   314  		},
   315  		{
   316  			"group id invalid",
   317  			func() client.Context {
   318  				bz, _ := s.encCfg.Codec.Marshal(&sdk.TxResponse{})
   319  				c := clitestutil.NewMockCometRPC(abci.ResponseQuery{
   320  					Value: bz,
   321  				})
   322  				return s.baseCtx.WithClient(c)
   323  			},
   324  			append(
   325  				[]string{
   326  					accounts[0].Address.String(),
   327  					"",
   328  					accounts[1].Address.String(),
   329  				},
   330  				s.commonFlags...,
   331  			),
   332  			fmt.Sprintf("%s %s %s", accounts[0].Address.String(), "", accounts[1].Address.String()),
   333  			"strconv.ParseUint: parsing \"\": invalid syntax",
   334  		},
   335  	}
   336  
   337  	for _, tc := range testCases {
   338  		tc := tc
   339  
   340  		s.Run(tc.name, func() {
   341  			ctx := svrcmd.CreateExecuteContext(context.Background())
   342  
   343  			cmd.SetContext(ctx)
   344  			cmd.SetArgs(tc.args)
   345  
   346  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
   347  
   348  			if len(tc.args) != 0 {
   349  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
   350  			}
   351  
   352  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
   353  			if tc.expectErrMsg != "" {
   354  				s.Require().Error(err)
   355  				s.Require().Contains(out.String(), tc.expectErrMsg)
   356  			} else {
   357  				s.Require().NoError(err)
   358  				msg := &sdk.TxResponse{}
   359  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
   360  			}
   361  		})
   362  	}
   363  }
   364  
   365  func (s *CLITestSuite) TestTxUpdateGroupMetadata() {
   366  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
   367  
   368  	cmd := groupcli.MsgUpdateGroupMetadataCmd()
   369  	cmd.SetOutput(io.Discard)
   370  
   371  	testCases := []struct {
   372  		name         string
   373  		args         []string
   374  		expCmdOutput string
   375  		expectErrMsg string
   376  	}{
   377  		{
   378  			"correct data",
   379  			append(
   380  				[]string{
   381  					accounts[0].Address.String(),
   382  					"1",
   383  					validMetadata,
   384  				},
   385  				s.commonFlags...,
   386  			),
   387  			fmt.Sprintf("%s %s %s", accounts[0].Address.String(), "1", validMetadata),
   388  			"",
   389  		},
   390  		{
   391  			"with amino-json",
   392  			append(
   393  				[]string{
   394  					accounts[0].Address.String(),
   395  					"1",
   396  					validMetadata,
   397  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   398  				},
   399  				s.commonFlags...,
   400  			),
   401  			fmt.Sprintf("%s %s %s --%s=%s", accounts[0].Address.String(), "1", validMetadata, flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   402  			"",
   403  		},
   404  		{
   405  			"invalid group id",
   406  			append(
   407  				[]string{
   408  					accounts[0].Address.String(),
   409  					"abc",
   410  					validMetadata,
   411  				},
   412  				s.commonFlags...,
   413  			),
   414  			fmt.Sprintf("%s %s %s", accounts[0].Address.String(), "abc", validMetadata),
   415  			"Error: strconv.ParseUint: parsing \"abc\"",
   416  		},
   417  		{
   418  			"empty group id",
   419  			append(
   420  				[]string{
   421  					accounts[0].Address.String(),
   422  					"0",
   423  					validMetadata,
   424  				},
   425  				s.commonFlags...,
   426  			),
   427  			fmt.Sprintf("%s %s %s", accounts[0].Address.String(), "0", validMetadata),
   428  			"group id cannot be 0",
   429  		},
   430  	}
   431  
   432  	for _, tc := range testCases {
   433  		tc := tc
   434  
   435  		s.Run(tc.name, func() {
   436  			ctx := svrcmd.CreateExecuteContext(context.Background())
   437  
   438  			cmd.SetContext(ctx)
   439  			cmd.SetArgs(tc.args)
   440  
   441  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
   442  
   443  			if len(tc.args) != 0 {
   444  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
   445  			}
   446  
   447  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
   448  			if tc.expectErrMsg != "" {
   449  				s.Require().Error(err)
   450  				s.Require().Contains(out.String(), tc.expectErrMsg)
   451  			} else {
   452  				s.Require().NoError(err)
   453  				msg := &sdk.TxResponse{}
   454  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
   455  			}
   456  		})
   457  	}
   458  }
   459  
   460  func (s *CLITestSuite) TestTxUpdateGroupMembers() {
   461  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 3)
   462  	groupPolicyAddress := accounts[2]
   463  
   464  	cmd := groupcli.MsgUpdateGroupMembersCmd()
   465  	cmd.SetOutput(io.Discard)
   466  
   467  	groupID := "1"
   468  
   469  	validUpdatedMembersFileName := testutil.WriteToNewTempFile(s.T(), fmt.Sprintf(`{"members": [{
   470  		"address": "%s",
   471  		"weight": "0",
   472  		"metadata": "%s"
   473  	}, {
   474  		"address": "%s",
   475  		"weight": "1",
   476  		"metadata": "%s"
   477  	}]}`, accounts[1], validMetadata, groupPolicyAddress, validMetadata)).Name()
   478  
   479  	invalidMembersMetadata := fmt.Sprintf(`{"members": [{
   480  		"address": "%s",
   481  		  "weight": "-1",
   482  		  "metadata": "foo"
   483  	  }]}`, accounts[1])
   484  	invalidMembersMetadataFileName := testutil.WriteToNewTempFile(s.T(), invalidMembersMetadata).Name()
   485  
   486  	testCases := []struct {
   487  		name         string
   488  		args         []string
   489  		expCmdOutput string
   490  		expectErrMsg string
   491  	}{
   492  		{
   493  			"correct data",
   494  			append(
   495  				[]string{
   496  					accounts[0].Address.String(),
   497  					groupID,
   498  					validUpdatedMembersFileName,
   499  				},
   500  				s.commonFlags...,
   501  			),
   502  			fmt.Sprintf("%s %s %s", accounts[0].Address.String(), groupID, validUpdatedMembersFileName),
   503  			"",
   504  		},
   505  		{
   506  			"with amino-json",
   507  			append(
   508  				[]string{
   509  					accounts[0].Address.String(),
   510  					groupID,
   511  					validUpdatedMembersFileName,
   512  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   513  				},
   514  				s.commonFlags...,
   515  			),
   516  			fmt.Sprintf("%s %s %s --%s=%s", accounts[0].Address.String(), groupID, validUpdatedMembersFileName, flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   517  			"",
   518  		},
   519  		{
   520  			"group id invalid",
   521  			append(
   522  				[]string{
   523  					accounts[0].Address.String(),
   524  					"0",
   525  					validUpdatedMembersFileName,
   526  				},
   527  				s.commonFlags...,
   528  			),
   529  			fmt.Sprintf("%s %s %s", accounts[0].Address.String(), "0", validUpdatedMembersFileName),
   530  			"group id cannot be 0",
   531  		},
   532  		{
   533  			"group member weight invalid",
   534  			append(
   535  				[]string{
   536  					accounts[0].Address.String(),
   537  					groupID,
   538  					invalidMembersMetadataFileName,
   539  				},
   540  				s.commonFlags...,
   541  			),
   542  			fmt.Sprintf("%s %s %s", accounts[0].Address.String(), groupID, invalidMembersMetadataFileName),
   543  			"invalid weight -1",
   544  		},
   545  	}
   546  
   547  	for _, tc := range testCases {
   548  		tc := tc
   549  
   550  		s.Run(tc.name, func() {
   551  			ctx := svrcmd.CreateExecuteContext(context.Background())
   552  
   553  			cmd.SetContext(ctx)
   554  			cmd.SetArgs(tc.args)
   555  
   556  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
   557  
   558  			if len(tc.args) != 0 {
   559  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
   560  			}
   561  
   562  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
   563  			if tc.expectErrMsg != "" {
   564  				s.Require().Error(err)
   565  				s.Require().Contains(out.String(), tc.expectErrMsg)
   566  			} else {
   567  				s.Require().NoError(err)
   568  				msg := &sdk.TxResponse{}
   569  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
   570  			}
   571  		})
   572  	}
   573  }
   574  
   575  func (s *CLITestSuite) TestTxCreateGroupWithPolicy() {
   576  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
   577  
   578  	cmd := groupcli.MsgCreateGroupWithPolicyCmd()
   579  	cmd.SetOutput(io.Discard)
   580  
   581  	validMembers := fmt.Sprintf(`{"members": [{
   582  		"address": "%s",
   583  		  "weight": "1",
   584  		  "metadata": "%s"
   585  	}]}`, accounts[0].Address.String(), validMetadata)
   586  	validMembersFile := testutil.WriteToNewTempFile(s.T(), validMembers)
   587  
   588  	invalidMembersWeight := fmt.Sprintf(`{"members": [{
   589  		"address": "%s",
   590  		  "weight": "0"
   591  	}]}`, accounts[0].Address.String())
   592  	invalidMembersWeightFile := testutil.WriteToNewTempFile(s.T(), invalidMembersWeight)
   593  
   594  	thresholdDecisionPolicyFile := testutil.WriteToNewTempFile(s.T(), `{"@type": "/cosmos.group.v1.ThresholdDecisionPolicy","threshold": "1","windows": {"voting_period":"1s"}}`)
   595  
   596  	testCases := []struct {
   597  		name         string
   598  		args         []string
   599  		expectErrMsg string
   600  		expCmdOutput string
   601  	}{
   602  		{
   603  			"correct data",
   604  			append(
   605  				[]string{
   606  					accounts[0].Address.String(),
   607  					validMetadata,
   608  					validMetadata,
   609  					validMembersFile.Name(),
   610  					thresholdDecisionPolicyFile.Name(),
   611  					fmt.Sprintf("--%s=%v", groupcli.FlagGroupPolicyAsAdmin, false),
   612  				},
   613  				s.commonFlags...,
   614  			),
   615  			"",
   616  			fmt.Sprintf("%s %s %s %s %s --%s=%v", accounts[0].Address.String(), validMetadata, validMetadata, validMembersFile.Name(), thresholdDecisionPolicyFile.Name(), groupcli.FlagGroupPolicyAsAdmin, false),
   617  		},
   618  		{
   619  			"group-policy-as-admin is true",
   620  			append(
   621  				[]string{
   622  					accounts[0].Address.String(),
   623  					validMetadata,
   624  					validMetadata,
   625  					validMembersFile.Name(),
   626  					thresholdDecisionPolicyFile.Name(),
   627  					fmt.Sprintf("--%s=%v", groupcli.FlagGroupPolicyAsAdmin, true),
   628  				},
   629  				s.commonFlags...,
   630  			),
   631  			"",
   632  			fmt.Sprintf("%s %s %s %s %s --%s=%v", accounts[0].Address.String(), validMetadata, validMetadata, validMembersFile.Name(), thresholdDecisionPolicyFile.Name(), groupcli.FlagGroupPolicyAsAdmin, true),
   633  		},
   634  		{
   635  			"with amino-json",
   636  			append(
   637  				[]string{
   638  					accounts[0].Address.String(),
   639  					validMetadata,
   640  					validMetadata,
   641  					validMembersFile.Name(),
   642  					thresholdDecisionPolicyFile.Name(),
   643  					fmt.Sprintf("--%s=%v", groupcli.FlagGroupPolicyAsAdmin, false),
   644  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   645  				},
   646  				s.commonFlags...,
   647  			),
   648  			"",
   649  			fmt.Sprintf("%s %s %s %s %s --%s=%v --%s=%s", accounts[0].Address.String(), validMetadata, validMetadata, validMembersFile.Name(), thresholdDecisionPolicyFile.Name(), groupcli.FlagGroupPolicyAsAdmin, false, flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   650  		},
   651  		{
   652  			"invalid members weight",
   653  			append(
   654  				[]string{
   655  					accounts[0].Address.String(),
   656  					validMetadata,
   657  					validMetadata,
   658  					invalidMembersWeightFile.Name(),
   659  					thresholdDecisionPolicyFile.Name(),
   660  					fmt.Sprintf("--%s=%v", groupcli.FlagGroupPolicyAsAdmin, false),
   661  				},
   662  				s.commonFlags...,
   663  			),
   664  			"weight must be positive",
   665  			fmt.Sprintf("%s %s %s %s %s --%s=%v", accounts[0].Address.String(), validMetadata, validMetadata, invalidMembersWeightFile.Name(), thresholdDecisionPolicyFile.Name(), groupcli.FlagGroupPolicyAsAdmin, false),
   666  		},
   667  	}
   668  	for _, tc := range testCases {
   669  		tc := tc
   670  
   671  		s.Run(tc.name, func() {
   672  			ctx := svrcmd.CreateExecuteContext(context.Background())
   673  
   674  			cmd.SetContext(ctx)
   675  			cmd.SetArgs(tc.args)
   676  
   677  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
   678  
   679  			if len(tc.args) != 0 {
   680  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
   681  			}
   682  
   683  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
   684  			if tc.expectErrMsg != "" {
   685  				s.Require().Error(err)
   686  				s.Require().Contains(out.String(), tc.expectErrMsg)
   687  			} else {
   688  				s.Require().NoError(err, out.String())
   689  				msg := &sdk.TxResponse{}
   690  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
   691  			}
   692  		})
   693  	}
   694  }
   695  
   696  func (s *CLITestSuite) TestTxCreateGroupPolicy() {
   697  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 2)
   698  	val := accounts[0]
   699  
   700  	groupID := s.group.Id
   701  
   702  	thresholdDecisionPolicyFile := testutil.WriteToNewTempFile(s.T(), `{"@type": "/cosmos.group.v1.ThresholdDecisionPolicy","threshold": "1","windows": {"voting_period":"1s"}}`)
   703  
   704  	percentageDecisionPolicyFile := testutil.WriteToNewTempFile(s.T(), `{"@type":"/cosmos.group.v1.PercentageDecisionPolicy", "percentage":"0.5", "windows":{"voting_period":"1s"}}`)
   705  	invalidNegativePercentageDecisionPolicyFile := testutil.WriteToNewTempFile(s.T(), `{"@type":"/cosmos.group.v1.PercentageDecisionPolicy", "percentage":"-0.5", "windows":{"voting_period":"1s"}}`)
   706  	invalidPercentageDecisionPolicyFile := testutil.WriteToNewTempFile(s.T(), `{"@type":"/cosmos.group.v1.PercentageDecisionPolicy", "percentage":"2", "windows":{"voting_period":"1s"}}`)
   707  
   708  	cmd := groupcli.MsgCreateGroupPolicyCmd()
   709  	cmd.SetOutput(io.Discard)
   710  
   711  	testCases := []struct {
   712  		name         string
   713  		args         []string
   714  		expectErrMsg string
   715  		expCmdOutput string
   716  	}{
   717  		{
   718  			"correct data",
   719  			append(
   720  				[]string{
   721  					val.Address.String(),
   722  					fmt.Sprintf("%v", groupID),
   723  					validMetadata,
   724  					thresholdDecisionPolicyFile.Name(),
   725  				},
   726  				s.commonFlags...,
   727  			),
   728  			"",
   729  			fmt.Sprintf("%s %s %s %s", val.Address.String(), fmt.Sprintf("%v", groupID), validMetadata, thresholdDecisionPolicyFile.Name()),
   730  		},
   731  		{
   732  			"correct data with percentage decision policy",
   733  			append(
   734  				[]string{
   735  					val.Address.String(),
   736  					fmt.Sprintf("%v", groupID),
   737  					validMetadata,
   738  					percentageDecisionPolicyFile.Name(),
   739  				},
   740  				s.commonFlags...,
   741  			),
   742  			"",
   743  			fmt.Sprintf("%s %s %s %s", val.Address.String(), fmt.Sprintf("%v", groupID), validMetadata, percentageDecisionPolicyFile.Name()),
   744  		},
   745  		{
   746  			"with amino-json",
   747  			append(
   748  				[]string{
   749  					val.Address.String(),
   750  					fmt.Sprintf("%v", groupID),
   751  					validMetadata,
   752  					thresholdDecisionPolicyFile.Name(),
   753  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   754  				},
   755  				s.commonFlags...,
   756  			),
   757  			"",
   758  			fmt.Sprintf("%s %s %s %s --%s=%s", val.Address.String(), fmt.Sprintf("%v", groupID), validMetadata, thresholdDecisionPolicyFile.Name(), flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   759  		},
   760  		{
   761  			"wrong admin",
   762  			append(
   763  				[]string{
   764  					"wrongAdmin",
   765  					fmt.Sprintf("%v", groupID),
   766  					validMetadata,
   767  					thresholdDecisionPolicyFile.Name(),
   768  				},
   769  				s.commonFlags...,
   770  			),
   771  			"key not found",
   772  			fmt.Sprintf("%s %s %s %s", "wrongAdmin", fmt.Sprintf("%v", groupID), validMetadata, thresholdDecisionPolicyFile.Name()),
   773  		},
   774  		{
   775  			"invalid percentage decision policy with negative value",
   776  			append(
   777  				[]string{
   778  					val.Address.String(),
   779  					fmt.Sprintf("%v", groupID),
   780  					validMetadata,
   781  					invalidNegativePercentageDecisionPolicyFile.Name(),
   782  				},
   783  				s.commonFlags...,
   784  			),
   785  			"expected a positive decimal",
   786  			fmt.Sprintf("%s %s %s %s", val.Address.String(), fmt.Sprintf("%v", groupID), validMetadata, invalidNegativePercentageDecisionPolicyFile.Name()),
   787  		},
   788  		{
   789  			"invalid percentage decision policy with value greater than 1",
   790  			append(
   791  				[]string{
   792  					val.Address.String(),
   793  					fmt.Sprintf("%v", groupID),
   794  					validMetadata,
   795  					invalidPercentageDecisionPolicyFile.Name(),
   796  				},
   797  				s.commonFlags...,
   798  			),
   799  			"percentage must be > 0 and <= 1",
   800  			fmt.Sprintf("%s %s %s %s", val.Address.String(), fmt.Sprintf("%v", groupID), validMetadata, invalidPercentageDecisionPolicyFile.Name()),
   801  		},
   802  	}
   803  
   804  	for _, tc := range testCases {
   805  		tc := tc
   806  
   807  		s.Run(tc.name, func() {
   808  			ctx := svrcmd.CreateExecuteContext(context.Background())
   809  
   810  			cmd.SetContext(ctx)
   811  			cmd.SetArgs(tc.args)
   812  
   813  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
   814  
   815  			if len(tc.args) != 0 {
   816  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
   817  			}
   818  
   819  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
   820  			if tc.expectErrMsg != "" {
   821  				s.Require().Error(err)
   822  				s.Require().Contains(out.String(), tc.expectErrMsg)
   823  			} else {
   824  				s.Require().NoError(err, out.String())
   825  				msg := &sdk.TxResponse{}
   826  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
   827  			}
   828  		})
   829  	}
   830  }
   831  
   832  func (s *CLITestSuite) TestTxUpdateGroupPolicyAdmin() {
   833  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 4)
   834  	newAdmin := accounts[0]
   835  	groupPolicyAdmin := accounts[1]
   836  	groupPolicyAddress := accounts[2]
   837  
   838  	commonFlags := s.commonFlags
   839  	commonFlags = append(commonFlags, fmt.Sprintf("--%s=%d", flags.FlagGas, 300000))
   840  
   841  	cmd := groupcli.MsgUpdateGroupPolicyAdminCmd()
   842  	cmd.SetOutput(io.Discard)
   843  
   844  	testCases := []struct {
   845  		name         string
   846  		args         []string
   847  		expCmdOutput string
   848  		expectErrMsg string
   849  	}{
   850  		{
   851  			"correct data",
   852  			append(
   853  				[]string{
   854  					groupPolicyAdmin.Address.String(),
   855  					groupPolicyAddress.Address.String(),
   856  					newAdmin.Address.String(),
   857  				},
   858  				commonFlags...,
   859  			),
   860  			fmt.Sprintf("%s %s %s", groupPolicyAdmin.Address.String(), groupPolicyAddress.Address.String(), newAdmin.Address.String()),
   861  			"",
   862  		},
   863  		{
   864  			"with amino-json",
   865  			append(
   866  				[]string{
   867  					groupPolicyAdmin.Address.String(),
   868  					groupPolicyAddress.Address.String(),
   869  					newAdmin.Address.String(),
   870  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   871  				},
   872  				commonFlags...,
   873  			),
   874  			fmt.Sprintf("%s %s %s --%s=%s", groupPolicyAdmin.Address.String(), groupPolicyAddress.Address.String(), newAdmin.Address.String(), flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   875  			"",
   876  		},
   877  		{
   878  			"wrong admin",
   879  			append(
   880  				[]string{
   881  					"wrong admin",
   882  					groupPolicyAddress.Address.String(),
   883  					newAdmin.Address.String(),
   884  				},
   885  				commonFlags...,
   886  			),
   887  			fmt.Sprintf("%s %s %s", "wrong admin", groupPolicyAddress.Address.String(), newAdmin.Address.String()),
   888  			"key not found",
   889  		},
   890  		{
   891  			"identical admin and new admin",
   892  			append(
   893  				[]string{
   894  					groupPolicyAdmin.Address.String(),
   895  					groupPolicyAddress.Address.String(),
   896  					groupPolicyAdmin.Address.String(),
   897  				},
   898  				commonFlags...,
   899  			),
   900  			fmt.Sprintf("%s %s %s", groupPolicyAdmin.Address.String(), groupPolicyAddress.Address.String(), groupPolicyAdmin.Address.String()),
   901  			"new admin cannot be the same as the current admin",
   902  		},
   903  	}
   904  
   905  	for _, tc := range testCases {
   906  		tc := tc
   907  
   908  		s.Run(tc.name, func() {
   909  			ctx := svrcmd.CreateExecuteContext(context.Background())
   910  
   911  			cmd.SetContext(ctx)
   912  			cmd.SetArgs(tc.args)
   913  
   914  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
   915  
   916  			if len(tc.args) != 0 {
   917  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
   918  			}
   919  
   920  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
   921  			if tc.expectErrMsg != "" {
   922  				s.Require().Error(err)
   923  				s.Require().Contains(out.String(), tc.expectErrMsg)
   924  			} else {
   925  				s.Require().NoError(err)
   926  				msg := &sdk.TxResponse{}
   927  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
   928  			}
   929  		})
   930  	}
   931  }
   932  
   933  func (s *CLITestSuite) TestTxUpdateGroupPolicyDecisionPolicy() {
   934  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 3)
   935  	newAdmin := accounts[0]
   936  	groupPolicyAdmin := accounts[1]
   937  	groupPolicyAddress := accounts[2]
   938  
   939  	commonFlags := s.commonFlags
   940  	commonFlags = append(commonFlags, fmt.Sprintf("--%s=%d", flags.FlagGas, 300000))
   941  
   942  	thresholdDecisionPolicy := testutil.WriteToNewTempFile(s.T(), `{"@type":"/cosmos.group.v1.ThresholdDecisionPolicy", "threshold":"1", "windows":{"voting_period":"40000s"}}`)
   943  	percentageDecisionPolicy := testutil.WriteToNewTempFile(s.T(), `{"@type":"/cosmos.group.v1.PercentageDecisionPolicy", "percentage":"0.5", "windows":{"voting_period":"40000s"}}`)
   944  
   945  	cmd := groupcli.MsgUpdateGroupPolicyDecisionPolicyCmd(address.NewBech32Codec("cosmos"))
   946  	cmd.SetOutput(io.Discard)
   947  
   948  	testCases := []struct {
   949  		name         string
   950  		args         []string
   951  		expCmdOutput string
   952  		expectErrMsg string
   953  	}{
   954  		{
   955  			"correct data",
   956  			append(
   957  				[]string{
   958  					groupPolicyAdmin.Address.String(),
   959  					groupPolicyAddress.Address.String(),
   960  					thresholdDecisionPolicy.Name(),
   961  				},
   962  				commonFlags...,
   963  			),
   964  			fmt.Sprintf("%s %s %s", groupPolicyAdmin.Address.String(), groupPolicyAddress.Address.String(), thresholdDecisionPolicy.Name()),
   965  			"",
   966  		},
   967  		{
   968  			"correct data with percentage decision policy",
   969  			append(
   970  				[]string{
   971  					groupPolicyAdmin.Address.String(),
   972  					groupPolicyAddress.Address.String(),
   973  					percentageDecisionPolicy.Name(),
   974  				},
   975  				commonFlags...,
   976  			),
   977  			fmt.Sprintf("%s %s %s", groupPolicyAdmin.Address.String(), groupPolicyAddress.Address.String(), percentageDecisionPolicy.Name()),
   978  			"",
   979  		},
   980  		{
   981  			"with amino-json",
   982  			append(
   983  				[]string{
   984  					groupPolicyAdmin.Address.String(),
   985  					groupPolicyAddress.Address.String(),
   986  					thresholdDecisionPolicy.Name(),
   987  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   988  				},
   989  				commonFlags...,
   990  			),
   991  			fmt.Sprintf("%s %s %s --%s=%s", groupPolicyAdmin.Address.String(), groupPolicyAddress.Address.String(), thresholdDecisionPolicy.Name(), flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
   992  			"",
   993  		},
   994  		{
   995  			"wrong admin",
   996  			append(
   997  				[]string{
   998  					newAdmin.Address.String(),
   999  					"invalid",
  1000  					thresholdDecisionPolicy.Name(),
  1001  				},
  1002  				commonFlags...,
  1003  			),
  1004  			fmt.Sprintf("%s %s %s", newAdmin.Address.String(), "invalid", thresholdDecisionPolicy.Name()),
  1005  			"decoding bech32 failed",
  1006  		},
  1007  	}
  1008  
  1009  	for _, tc := range testCases {
  1010  		tc := tc
  1011  
  1012  		s.Run(tc.name, func() {
  1013  			ctx := svrcmd.CreateExecuteContext(context.Background())
  1014  
  1015  			cmd.SetContext(ctx)
  1016  			cmd.SetArgs(tc.args)
  1017  
  1018  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
  1019  
  1020  			if len(tc.args) != 0 {
  1021  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
  1022  			}
  1023  
  1024  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
  1025  			if tc.expectErrMsg != "" {
  1026  				s.Require().Error(err)
  1027  				s.Require().Contains(out.String(), tc.expectErrMsg)
  1028  			} else {
  1029  				s.Require().NoError(err)
  1030  				msg := &sdk.TxResponse{}
  1031  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
  1032  			}
  1033  		})
  1034  	}
  1035  }
  1036  
  1037  func (s *CLITestSuite) TestTxUpdateGroupPolicyMetadata() {
  1038  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 2)
  1039  	groupPolicyAdmin := accounts[0].Address
  1040  	groupPolicyAddress := accounts[1].Address
  1041  
  1042  	commonFlags := s.commonFlags
  1043  	commonFlags = append(commonFlags, fmt.Sprintf("--%s=%d", flags.FlagGas, 300000))
  1044  
  1045  	cmd := groupcli.MsgUpdateGroupPolicyMetadataCmd()
  1046  	cmd.SetOutput(io.Discard)
  1047  
  1048  	testCases := []struct {
  1049  		name         string
  1050  		args         []string
  1051  		expCmdOutput string
  1052  		expectErrMsg string
  1053  	}{
  1054  		{
  1055  			"correct data",
  1056  			append(
  1057  				[]string{
  1058  					groupPolicyAdmin.String(),
  1059  					groupPolicyAddress.String(),
  1060  					validMetadata,
  1061  				},
  1062  				commonFlags...,
  1063  			),
  1064  			fmt.Sprintf("%s %s %s", groupPolicyAdmin.String(), groupPolicyAddress.String(), validMetadata),
  1065  			"",
  1066  		},
  1067  		{
  1068  			"with amino-json",
  1069  			append(
  1070  				[]string{
  1071  					groupPolicyAdmin.String(),
  1072  					groupPolicyAddress.String(),
  1073  					validMetadata,
  1074  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
  1075  				},
  1076  				commonFlags...,
  1077  			),
  1078  			fmt.Sprintf("%s %s %s --%s=%s", groupPolicyAdmin.String(), groupPolicyAddress.String(), validMetadata, flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
  1079  			"",
  1080  		},
  1081  		{
  1082  			"wrong admin",
  1083  			append(
  1084  				[]string{
  1085  					"wrong admin",
  1086  					groupPolicyAddress.String(),
  1087  					validMetadata,
  1088  				},
  1089  				commonFlags...,
  1090  			),
  1091  			fmt.Sprintf("%s %s %s", "wrong admin", groupPolicyAddress.String(), validMetadata),
  1092  			"key not found",
  1093  		},
  1094  	}
  1095  
  1096  	for _, tc := range testCases {
  1097  		tc := tc
  1098  
  1099  		s.Run(tc.name, func() {
  1100  			ctx := svrcmd.CreateExecuteContext(context.Background())
  1101  
  1102  			cmd.SetContext(ctx)
  1103  			cmd.SetArgs(tc.args)
  1104  
  1105  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
  1106  
  1107  			if len(tc.args) != 0 {
  1108  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
  1109  			}
  1110  
  1111  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
  1112  			if tc.expectErrMsg != "" {
  1113  				s.Require().Error(err)
  1114  				s.Require().Contains(out.String(), tc.expectErrMsg)
  1115  			} else {
  1116  				s.Require().NoError(err)
  1117  				msg := &sdk.TxResponse{}
  1118  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
  1119  			}
  1120  		})
  1121  	}
  1122  }
  1123  
  1124  func (s *CLITestSuite) TestTxSubmitProposal() {
  1125  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 2)
  1126  	groupPolicyAddress := accounts[1].Address
  1127  
  1128  	p := groupcli.Proposal{
  1129  		GroupPolicyAddress: groupPolicyAddress.String(),
  1130  		Messages:           []json.RawMessage{},
  1131  		Metadata:           validMetadata,
  1132  		Proposers:          []string{accounts[0].Address.String()},
  1133  	}
  1134  	bz, err := json.Marshal(&p)
  1135  	s.Require().NoError(err)
  1136  	proposalFile := testutil.WriteToNewTempFile(s.T(), string(bz))
  1137  
  1138  	cmd := groupcli.MsgSubmitProposalCmd()
  1139  	cmd.SetOutput(io.Discard)
  1140  
  1141  	testCases := []struct {
  1142  		name         string
  1143  		args         []string
  1144  		expCmdOutput string
  1145  		expectErrMsg string
  1146  	}{
  1147  		{
  1148  			"correct data",
  1149  			append(
  1150  				[]string{
  1151  					proposalFile.Name(),
  1152  				},
  1153  				s.commonFlags...,
  1154  			),
  1155  			proposalFile.Name(),
  1156  			"",
  1157  		},
  1158  		{
  1159  			"with try exec",
  1160  			append(
  1161  				[]string{
  1162  					proposalFile.Name(),
  1163  					fmt.Sprintf("--%s=try", groupcli.FlagExec),
  1164  				},
  1165  				s.commonFlags...,
  1166  			),
  1167  			fmt.Sprintf("%s --%s=try", proposalFile.Name(), groupcli.FlagExec),
  1168  			"",
  1169  		},
  1170  		{
  1171  			"with try exec, not enough yes votes for proposal to pass",
  1172  			append(
  1173  				[]string{
  1174  					proposalFile.Name(),
  1175  					fmt.Sprintf("--%s=try", groupcli.FlagExec),
  1176  				},
  1177  				s.commonFlags...,
  1178  			),
  1179  			fmt.Sprintf("%s --%s=try", proposalFile.Name(), groupcli.FlagExec),
  1180  			"",
  1181  		},
  1182  		{
  1183  			"with amino-json",
  1184  			append(
  1185  				[]string{
  1186  					proposalFile.Name(),
  1187  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
  1188  				},
  1189  				s.commonFlags...,
  1190  			),
  1191  			fmt.Sprintf("%s --%s=%s", proposalFile.Name(), flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
  1192  			"",
  1193  		},
  1194  	}
  1195  
  1196  	for _, tc := range testCases {
  1197  		tc := tc
  1198  
  1199  		s.Run(tc.name, func() {
  1200  			ctx := svrcmd.CreateExecuteContext(context.Background())
  1201  
  1202  			cmd.SetContext(ctx)
  1203  			cmd.SetArgs(tc.args)
  1204  
  1205  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
  1206  
  1207  			if len(tc.args) != 0 {
  1208  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
  1209  			}
  1210  
  1211  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
  1212  			if tc.expectErrMsg != "" {
  1213  				s.Require().Error(err)
  1214  				s.Require().Contains(out.String(), tc.expectErrMsg)
  1215  			} else {
  1216  				s.Require().NoError(err)
  1217  				msg := &sdk.TxResponse{}
  1218  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
  1219  			}
  1220  		})
  1221  	}
  1222  }
  1223  
  1224  func (s *CLITestSuite) TestTxVote() {
  1225  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 4)
  1226  
  1227  	cmd := groupcli.MsgVoteCmd()
  1228  	cmd.SetOutput(io.Discard)
  1229  
  1230  	ids := make([]string, 4)
  1231  	for i := 0; i < len(ids); i++ {
  1232  		ids[i] = fmt.Sprint(i + 1)
  1233  	}
  1234  
  1235  	testCases := []struct {
  1236  		name         string
  1237  		args         []string
  1238  		expCmdOutput string
  1239  		expectErrMsg string
  1240  	}{
  1241  		{
  1242  			"invalid vote",
  1243  			append(
  1244  				[]string{
  1245  					ids[0],
  1246  					accounts[0].Address.String(),
  1247  					"AYE",
  1248  					"",
  1249  				},
  1250  				s.commonFlags...,
  1251  			),
  1252  			fmt.Sprintf("%s %s %s", ids[0], accounts[0].Address.String(), "AYE"),
  1253  			"Error: 'AYE' is not a valid vote option",
  1254  		},
  1255  		{
  1256  			"correct data",
  1257  			append(
  1258  				[]string{
  1259  					ids[0],
  1260  					accounts[0].Address.String(),
  1261  					"VOTE_OPTION_YES",
  1262  					"",
  1263  				},
  1264  				s.commonFlags...,
  1265  			),
  1266  			fmt.Sprintf("%s %s %s", ids[0], accounts[0].Address.String(), "VOTE_OPTION_YES"),
  1267  			"",
  1268  		},
  1269  		{
  1270  			"with try exec",
  1271  			append(
  1272  				[]string{
  1273  					ids[1],
  1274  					accounts[0].Address.String(),
  1275  					"VOTE_OPTION_YES",
  1276  					"",
  1277  					fmt.Sprintf("--%s=try", groupcli.FlagExec),
  1278  				},
  1279  				s.commonFlags...,
  1280  			),
  1281  			fmt.Sprintf("%s %s %s %s --%s=try", ids[1], accounts[0].Address.String(), "VOTE_OPTION_YES", "", groupcli.FlagExec),
  1282  			"",
  1283  		},
  1284  		{
  1285  			"with amino-json",
  1286  			append(
  1287  				[]string{
  1288  					ids[3],
  1289  					accounts[0].Address.String(),
  1290  					"VOTE_OPTION_YES",
  1291  					"",
  1292  					fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
  1293  				},
  1294  				s.commonFlags...,
  1295  			),
  1296  			fmt.Sprintf("%s %s %s %s --%s=%s", ids[3], accounts[0].Address.String(), "VOTE_OPTION_YES", "", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
  1297  			"",
  1298  		},
  1299  	}
  1300  
  1301  	for _, tc := range testCases {
  1302  		tc := tc
  1303  
  1304  		s.Run(tc.name, func() {
  1305  			ctx := svrcmd.CreateExecuteContext(context.Background())
  1306  
  1307  			cmd.SetContext(ctx)
  1308  			cmd.SetArgs(tc.args)
  1309  
  1310  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
  1311  
  1312  			if len(tc.args) != 0 {
  1313  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
  1314  			}
  1315  
  1316  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
  1317  			if tc.expectErrMsg != "" {
  1318  				s.Require().Error(err)
  1319  				s.Require().Contains(out.String(), tc.expectErrMsg)
  1320  			} else {
  1321  				s.Require().NoError(err)
  1322  				msg := &sdk.TxResponse{}
  1323  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
  1324  			}
  1325  		})
  1326  	}
  1327  }
  1328  
  1329  func (s *CLITestSuite) TestTxWithdrawProposal() {
  1330  	accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
  1331  
  1332  	cmd := groupcli.MsgWithdrawProposalCmd()
  1333  	cmd.SetOutput(io.Discard)
  1334  
  1335  	ids := make([]string, 2)
  1336  	ids[0] = "1"
  1337  	ids[1] = "2"
  1338  
  1339  	testCases := []struct {
  1340  		name         string
  1341  		args         []string
  1342  		expCmdOutput string
  1343  		expectErrMsg string
  1344  	}{
  1345  		{
  1346  			"correct data",
  1347  			append(
  1348  				[]string{
  1349  					ids[0],
  1350  					accounts[0].Address.String(),
  1351  				},
  1352  				s.commonFlags...,
  1353  			),
  1354  			fmt.Sprintf("%s %s", ids[0], accounts[0].Address.String()),
  1355  			"",
  1356  		},
  1357  		{
  1358  			"wrong admin",
  1359  			append(
  1360  				[]string{
  1361  					ids[1],
  1362  					"wrongAdmin",
  1363  				},
  1364  				s.commonFlags...,
  1365  			),
  1366  			fmt.Sprintf("%s %s", ids[1], "wrongAdmin"),
  1367  			"key not found",
  1368  		},
  1369  		{
  1370  			"wrong proposal id",
  1371  			append(
  1372  				[]string{
  1373  					"abc",
  1374  					accounts[0].Address.String(),
  1375  				},
  1376  				s.commonFlags...,
  1377  			),
  1378  			fmt.Sprintf("%s %s", "abc", accounts[0].Address.String()),
  1379  			"Error: strconv.ParseUint: parsing \"abc\"",
  1380  		},
  1381  	}
  1382  
  1383  	for _, tc := range testCases {
  1384  		tc := tc
  1385  
  1386  		s.Run(tc.name, func() {
  1387  			ctx := svrcmd.CreateExecuteContext(context.Background())
  1388  
  1389  			cmd.SetContext(ctx)
  1390  			cmd.SetArgs(tc.args)
  1391  
  1392  			s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
  1393  
  1394  			if len(tc.args) != 0 {
  1395  				s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput)
  1396  			}
  1397  
  1398  			out, err := clitestutil.ExecTestCLICmd(s.baseCtx, cmd, tc.args)
  1399  			if tc.expectErrMsg != "" {
  1400  				s.Require().Error(err)
  1401  				s.Require().Contains(out.String(), tc.expectErrMsg)
  1402  			} else {
  1403  				s.Require().NoError(err)
  1404  				msg := &sdk.TxResponse{}
  1405  				s.Require().NoError(s.baseCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
  1406  			}
  1407  		})
  1408  	}
  1409  }