cosmossdk.io/client/v2@v2.0.0-beta.1/autocli/msg_test.go (about)

     1  package autocli
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/spf13/cobra"
     8  	"gotest.tools/v3/assert"
     9  	"gotest.tools/v3/golden"
    10  
    11  	autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
    12  	bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
    13  	"cosmossdk.io/client/v2/internal/testpb"
    14  )
    15  
    16  var buildModuleMsgCommand = func(moduleName string, b *Builder) (*cobra.Command, error) {
    17  	cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
    18  	err := b.AddMsgServiceCommands(cmd, bankAutoCLI)
    19  	return cmd, err
    20  }
    21  
    22  func buildCustomModuleMsgCommand(cmdDescriptor *autocliv1.ServiceCommandDescriptor) func(moduleName string, b *Builder) (*cobra.Command, error) {
    23  	return func(moduleName string, b *Builder) (*cobra.Command, error) {
    24  		cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
    25  		err := b.AddMsgServiceCommands(cmd, cmdDescriptor)
    26  		return cmd, err
    27  	}
    28  }
    29  
    30  var bankAutoCLI = &autocliv1.ServiceCommandDescriptor{
    31  	Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
    32  	RpcCommandOptions: []*autocliv1.RpcCommandOptions{
    33  		{
    34  			RpcMethod:      "Send",
    35  			Use:            "send [from_key_or_address] [to_address] [amount] [flags]",
    36  			Short:          "Send coins from one account to another",
    37  			PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "from_address"}, {ProtoField: "to_address"}, {ProtoField: "amount"}},
    38  		},
    39  	},
    40  	EnhanceCustomCommand: true,
    41  }
    42  
    43  func TestMsg(t *testing.T) {
    44  	fixture := initFixture(t)
    45  	out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "send",
    46  		"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
    47  		"--generate-only",
    48  		"--output", "json",
    49  	)
    50  	assert.NilError(t, err)
    51  	golden.Assert(t, out.String(), "msg-output.golden")
    52  
    53  	out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
    54  		Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
    55  		RpcCommandOptions: []*autocliv1.RpcCommandOptions{
    56  			{
    57  				RpcMethod:      "Send",
    58  				Use:            "send [from_key_or_address] [to_address] [amount] [flags]",
    59  				Short:          "Send coins from one account to another",
    60  				PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "to_address"}, {ProtoField: "amount"}},
    61  				// from_address should be automatically added
    62  			},
    63  		},
    64  		EnhanceCustomCommand: true,
    65  	}), "send",
    66  		"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
    67  		"--from", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
    68  		"--generate-only",
    69  		"--output", "json",
    70  	)
    71  	assert.NilError(t, err)
    72  	golden.Assert(t, out.String(), "msg-output.golden")
    73  
    74  	out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
    75  		Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
    76  		RpcCommandOptions: []*autocliv1.RpcCommandOptions{
    77  			{
    78  				RpcMethod:      "Send",
    79  				Use:            "send [from_key_or_address] [to_address] [amount] [flags]",
    80  				Short:          "Send coins from one account to another",
    81  				PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "to_address"}, {ProtoField: "amount"}},
    82  				FlagOptions: map[string]*autocliv1.FlagOptions{
    83  					"from_address": {Name: "sender"}, // use a custom flag for signer
    84  				},
    85  			},
    86  		},
    87  		EnhanceCustomCommand: true,
    88  	}), "send",
    89  		"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
    90  		"--sender", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
    91  		"--generate-only",
    92  		"--output", "json",
    93  	)
    94  	assert.NilError(t, err)
    95  	golden.Assert(t, out.String(), "msg-output.golden")
    96  }
    97  
    98  func TestMsgOptionsError(t *testing.T) {
    99  	fixture := initFixture(t)
   100  
   101  	_, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
   102  		"send", "5",
   103  	)
   104  	assert.ErrorContains(t, err, "accepts 3 arg(s)")
   105  
   106  	_, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
   107  		"send", "foo", "bar", "invalid",
   108  	)
   109  	assert.ErrorContains(t, err, "invalid argument")
   110  }
   111  
   112  func TestHelpMsg(t *testing.T) {
   113  	fixture := initFixture(t)
   114  
   115  	out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "-h")
   116  	assert.NilError(t, err)
   117  	golden.Assert(t, out.String(), "help-toplevel-msg.golden")
   118  
   119  	out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "send", "-h")
   120  	assert.NilError(t, err)
   121  	golden.Assert(t, out.String(), "help-echo-msg.golden")
   122  }
   123  
   124  func TestBuildCustomMsgCommand(t *testing.T) {
   125  	b := &Builder{}
   126  	customCommandCalled := false
   127  	appOptions := AppOptions{
   128  		ModuleOptions: map[string]*autocliv1.ModuleOptions{
   129  			"test": {
   130  				Tx: &autocliv1.ServiceCommandDescriptor{
   131  					Service:           testpb.Msg_ServiceDesc.ServiceName,
   132  					RpcCommandOptions: []*autocliv1.RpcCommandOptions{},
   133  				},
   134  			},
   135  		},
   136  	}
   137  
   138  	cmd, err := b.BuildMsgCommand(appOptions, map[string]*cobra.Command{
   139  		"test": {Use: "test", Run: func(cmd *cobra.Command, args []string) {
   140  			customCommandCalled = true
   141  		}},
   142  	})
   143  	assert.NilError(t, err)
   144  	cmd.SetArgs([]string{"test", "tx"})
   145  	assert.NilError(t, cmd.Execute())
   146  	assert.Assert(t, customCommandCalled)
   147  }
   148  
   149  func TestNotFoundErrorsMsg(t *testing.T) {
   150  	fixture := initFixture(t)
   151  	b := fixture.b
   152  	b.AddQueryConnFlags = nil
   153  	b.AddTxConnFlags = nil
   154  
   155  	buildModuleMsgCommand := func(moduleName string, cmdDescriptor *autocliv1.ServiceCommandDescriptor) (*cobra.Command, error) {
   156  		cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
   157  
   158  		err := b.AddMsgServiceCommands(cmd, cmdDescriptor)
   159  		return cmd, err
   160  	}
   161  
   162  	// Query non existent service
   163  	_, err := buildModuleMsgCommand("test", &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"})
   164  	assert.ErrorContains(t, err, "can't find service un-existent-service")
   165  
   166  	_, err = buildModuleMsgCommand("test", &autocliv1.ServiceCommandDescriptor{
   167  		Service:           testpb.Query_ServiceDesc.ServiceName,
   168  		RpcCommandOptions: []*autocliv1.RpcCommandOptions{{RpcMethod: "un-existent-method"}},
   169  	})
   170  	assert.ErrorContains(t, err, "rpc method \"un-existent-method\" not found")
   171  
   172  	_, err = buildModuleMsgCommand("test", &autocliv1.ServiceCommandDescriptor{
   173  		Service: testpb.Msg_ServiceDesc.ServiceName,
   174  		RpcCommandOptions: []*autocliv1.RpcCommandOptions{
   175  			{
   176  				RpcMethod: "Send",
   177  				PositionalArgs: []*autocliv1.PositionalArgDescriptor{
   178  					{
   179  						ProtoField: "un-existent-proto-field",
   180  					},
   181  				},
   182  			},
   183  		},
   184  	})
   185  	assert.ErrorContains(t, err, "can't find field un-existent-proto-field")
   186  
   187  	_, err = buildModuleMsgCommand("test", &autocliv1.ServiceCommandDescriptor{
   188  		Service: testpb.Msg_ServiceDesc.ServiceName,
   189  		RpcCommandOptions: []*autocliv1.RpcCommandOptions{
   190  			{
   191  				RpcMethod: "Send",
   192  				FlagOptions: map[string]*autocliv1.FlagOptions{
   193  					"un-existent-flag": {},
   194  				},
   195  			},
   196  		},
   197  	})
   198  	assert.ErrorContains(t, err, "can't find field un-existent-flag")
   199  }