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 }