Merge PR #3517: Increasing test coverage in keys/client package

This commit is contained in:
Juan Leni
2019-02-08 12:45:23 -08:00
committed by Jack Zampolin
parent cff985ffc5
commit b5fdb83830
49 changed files with 1137 additions and 312 deletions
+17 -1
View File
@@ -15,10 +15,26 @@ import (
// MinPassLength is the minimum acceptable password length
const MinPassLength = 8
var currentStdin *bufio.Reader
func init() {
currentStdin = bufio.NewReader(os.Stdin)
}
// BufferStdin is used to allow reading prompts for stdin
// multiple times, when we read from non-tty
func BufferStdin() *bufio.Reader {
return bufio.NewReader(os.Stdin)
return currentStdin
}
// OverrideStdin allows to temporarily override stdin
func OverrideStdin(newStdin *bufio.Reader) (cleanUp func()) {
prevStdin := currentStdin
currentStdin = newStdin
cleanUp = func() {
currentStdin = prevStdin
}
return cleanUp
}
// GetPassword will prompt for a password one-time (to sign a tx)
+3 -3
View File
@@ -90,7 +90,7 @@ input
output
- armor encrypted private key (saved to file)
*/
func runAddCmd(cmd *cobra.Command, args []string) error {
func runAddCmd(_ *cobra.Command, args []string) error {
var kb keys.Keybase
var err error
var encryptPassword string
@@ -265,7 +265,7 @@ func printCreate(info keys.Info, showMnemonic bool, mnemonic string) error {
output := viper.Get(cli.OutputFlag)
switch output {
case "text":
case OutputFormatText:
fmt.Fprintln(os.Stderr)
printKeyInfo(info, Bech32KeyOutput)
@@ -276,7 +276,7 @@ func printCreate(info keys.Info, showMnemonic bool, mnemonic string) error {
fmt.Fprintln(os.Stderr, "")
fmt.Fprintln(os.Stderr, mnemonic)
}
case "json":
case OutputFormatJSON:
out, err := Bech32KeyOutput(info)
if err != nil {
return err
+104
View File
@@ -0,0 +1,104 @@
package keys
import (
"bufio"
"net/http"
"strings"
"testing"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/cosmos/cosmos-sdk/client"
"github.com/stretchr/testify/assert"
)
func Test_runAddCmdBasic(t *testing.T) {
cmd := addKeyCommand()
assert.NotNil(t, cmd)
// Missing input (enter password)
err := runAddCmd(cmd, []string{"keyname"})
assert.EqualError(t, err, "EOF")
// Prepare a keybase
kbHome, kbCleanUp, err := tests.GetTempDir("Test_runDeleteCmd")
assert.NoError(t, err)
assert.NotNil(t, kbHome)
defer kbCleanUp()
viper.Set(cli.HomeFlag, kbHome)
/// Test Text
viper.Set(cli.OutputFlag, OutputFormatText)
// Now enter password
cleanUp1 := client.OverrideStdin(bufio.NewReader(strings.NewReader("test1234\ntest1234\n")))
defer cleanUp1()
err = runAddCmd(cmd, []string{"keyname1"})
assert.NoError(t, err)
/// Test Text - Replace? >> FAIL
viper.Set(cli.OutputFlag, OutputFormatText)
// Now enter password
cleanUp2 := client.OverrideStdin(bufio.NewReader(strings.NewReader("test1234\ntest1234\n")))
defer cleanUp2()
err = runAddCmd(cmd, []string{"keyname1"})
assert.Error(t, err)
/// Test Text - Replace? Answer >> PASS
viper.Set(cli.OutputFlag, OutputFormatText)
// Now enter password
cleanUp3 := client.OverrideStdin(bufio.NewReader(strings.NewReader("y\ntest1234\ntest1234\n")))
defer cleanUp3()
err = runAddCmd(cmd, []string{"keyname1"})
assert.NoError(t, err)
// Check JSON
viper.Set(cli.OutputFlag, OutputFormatJSON)
// Now enter password
cleanUp4 := client.OverrideStdin(bufio.NewReader(strings.NewReader("test1234\ntest1234\n")))
defer cleanUp4()
err = runAddCmd(cmd, []string{"keyname2"})
assert.NoError(t, err)
}
type MockResponseWriter struct {
dataHeaderStatus int
dataBody []byte
}
func (MockResponseWriter) Header() http.Header {
panic("Unexpected call!")
}
func (w *MockResponseWriter) Write(data []byte) (int, error) {
w.dataBody = append(w.dataBody, data...)
return len(data), nil
}
func (w *MockResponseWriter) WriteHeader(statusCode int) {
w.dataHeaderStatus = statusCode
}
func TestCheckAndWriteErrorResponse(t *testing.T) {
mockRW := MockResponseWriter{}
mockRW.WriteHeader(100)
assert.Equal(t, 100, mockRW.dataHeaderStatus)
detected := CheckAndWriteErrorResponse(&mockRW, http.StatusBadRequest, errors.New("some ERROR"))
require.True(t, detected)
require.Equal(t, http.StatusBadRequest, mockRW.dataHeaderStatus)
require.Equal(t, "some ERROR", string(mockRW.dataBody[:]))
mockRW = MockResponseWriter{}
detected = CheckAndWriteErrorResponse(&mockRW, http.StatusBadRequest, nil)
require.False(t, detected)
require.Equal(t, 0, mockRW.dataHeaderStatus)
require.Equal(t, "", string(mockRW.dataBody[:]))
}
+100
View File
@@ -0,0 +1,100 @@
package keys
import (
"fmt"
"reflect"
"testing"
"github.com/stretchr/testify/require"
)
type testCases struct {
Keys []KeyOutput
Answers []KeyOutput
JSON [][]byte
}
func getTestCases() testCases {
return testCases{
[]KeyOutput{
{"A", "B", "C", "D", "E"},
{"A", "B", "C", "D", ""},
{"", "B", "C", "D", ""},
{"", "", "", "", ""},
},
make([]KeyOutput, 4),
[][]byte{
[]byte(`{"name":"A","type":"B","address":"C","pub_key":"D","mnemonic":"E"}`),
[]byte(`{"name":"A","type":"B","address":"C","pub_key":"D"}`),
[]byte(`{"name":"","type":"B","address":"C","pub_key":"D"}`),
[]byte(`{"name":"","type":"","address":"","pub_key":""}`),
},
}
}
func TestMarshalJSON(t *testing.T) {
type args struct {
o KeyOutput
}
data := getTestCases()
tests := []struct {
name string
args args
want []byte
wantErr bool
}{
{"basic", args{data.Keys[0]}, []byte(data.JSON[0]), false},
{"mnemonic is optional", args{data.Keys[1]}, []byte(data.JSON[1]), false},
// REVIEW: Are the next results expected??
{"empty name", args{data.Keys[2]}, []byte(data.JSON[2]), false},
{"empty object", args{data.Keys[3]}, []byte(data.JSON[3]), false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := MarshalJSON(tt.args.o)
if (err != nil) != tt.wantErr {
t.Errorf("MarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
return
}
fmt.Printf("%s\n", got)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("MarshalJSON() = %v, want %v", got, tt.want)
}
})
}
}
func TestUnmarshalJSON(t *testing.T) {
type args struct {
bz []byte
ptr interface{}
}
data := getTestCases()
tests := []struct {
name string
args args
wantErr bool
}{
{"basic", args{data.JSON[0], &data.Answers[0]}, false},
{"mnemonic is optional", args{data.JSON[1], &data.Answers[1]}, false},
// REVIEW: Are the next results expected??
{"empty name", args{data.JSON[2], &data.Answers[2]}, false},
{"empty object", args{data.JSON[3], &data.Answers[3]}, false},
}
for idx, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := UnmarshalJSON(tt.args.bz, tt.args.ptr); (err != nil) != tt.wantErr {
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
}
// Confirm deserialized objects are the same
require.Equal(t, data.Keys[idx], data.Answers[idx])
})
}
}
+16 -16
View File
@@ -91,6 +91,17 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error {
return nil
}
func confirmDeletion(buf *bufio.Reader) error {
answer, err := client.GetConfirmation("Key reference will be deleted. Continue?", buf)
if err != nil {
return err
}
if !answer {
return errors.New("aborted")
}
return nil
}
////////////////////////
// REST
@@ -110,42 +121,31 @@ func DeleteKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
err := decoder.Decode(&m)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
kb, err = NewKeyBaseFromHomeFlag()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
err = kb.Delete(name, m.Password, false)
if keyerror.IsErrKeyNotFound(err) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if keyerror.IsErrWrongPassword(err) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
w.WriteHeader(http.StatusOK)
}
func confirmDeletion(buf *bufio.Reader) error {
answer, err := client.GetConfirmation("Key reference will be deleted. Continue?", buf)
if err != nil {
return err
}
if !answer {
return errors.New("aborted")
}
return nil
}
+103
View File
@@ -0,0 +1,103 @@
package keys
import (
"bufio"
"strings"
"testing"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/cli"
)
func Test_runDeleteCmd(t *testing.T) {
deleteKeyCommand := deleteKeyCommand()
yesF, _ := deleteKeyCommand.Flags().GetBool(flagYes)
forceF, _ := deleteKeyCommand.Flags().GetBool(flagForce)
assert.False(t, yesF)
assert.False(t, forceF)
fakeKeyName1 := "runDeleteCmd_Key1"
fakeKeyName2 := "runDeleteCmd_Key2"
// Now add a temporary keybase
kbHome, cleanUp, err := tests.GetTempDir("Test_runDeleteCmd")
assert.NoError(t, err)
defer cleanUp()
viper.Set(cli.HomeFlag, kbHome)
// Now
kb, err := NewKeyBaseFromHomeFlag()
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName1, tests.TestMnemonic, "", "", 0, 0)
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName2, tests.TestMnemonic, "", "", 0, 1)
assert.NoError(t, err)
err = runDeleteCmd(deleteKeyCommand, []string{"blah"})
require.Error(t, err)
require.Equal(t, "Key blah not found", err.Error())
// User confirmation missing
err = runDeleteCmd(deleteKeyCommand, []string{fakeKeyName1})
require.Error(t, err)
require.Equal(t, "EOF", err.Error())
{
_, err = kb.Get(fakeKeyName1)
require.NoError(t, err)
// Now there is a confirmation
cleanUp := client.OverrideStdin(bufio.NewReader(strings.NewReader("y\n")))
defer cleanUp()
err = runDeleteCmd(deleteKeyCommand, []string{fakeKeyName1})
require.NoError(t, err)
_, err = kb.Get(fakeKeyName1)
require.Error(t, err) // Key1 is gone
}
viper.Set(flagYes, true)
_, err = kb.Get(fakeKeyName2)
require.NoError(t, err)
err = runDeleteCmd(deleteKeyCommand, []string{fakeKeyName2})
require.NoError(t, err)
_, err = kb.Get(fakeKeyName2)
require.Error(t, err) // Key2 is gone
// TODO: Write another case for !keys.Local
}
func Test_confirmDeletion(t *testing.T) {
type args struct {
buf *bufio.Reader
}
answerYes := bufio.NewReader(strings.NewReader("y\n"))
answerYes2 := bufio.NewReader(strings.NewReader("Y\n"))
answerNo := bufio.NewReader(strings.NewReader("n\n"))
answerInvalid := bufio.NewReader(strings.NewReader("245\n"))
tests := []struct {
name string
args args
wantErr bool
}{
{"Y", args{answerYes}, false},
{"y", args{answerYes2}, false},
{"N", args{answerNo}, true},
{"BAD", args{answerInvalid}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := confirmDeletion(tt.args.buf); (err != nil) != tt.wantErr {
t.Errorf("confirmDeletion() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
View File
+10 -11
View File
@@ -6,15 +6,14 @@ import (
"github.com/spf13/cobra"
)
// CMD
// listKeysCmd represents the list command
var listKeysCmd = &cobra.Command{
Use: "list",
Short: "List all keys",
Long: `Return a list of all public keys stored by this key manager
func listKeysCmd() *cobra.Command {
return &cobra.Command{
Use: "list",
Short: "List all keys",
Long: `Return a list of all public keys stored by this key manager
along with their associated name and address.`,
RunE: runListCmd,
RunE: runListCmd,
}
}
func runListCmd(cmd *cobra.Command, args []string) error {
@@ -39,13 +38,13 @@ func QueryKeysRequestHandler(indent bool) http.HandlerFunc {
kb, err := NewKeyBaseFromHomeFlag()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
infos, err := kb.List()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
// an empty list will be JSONized as null, but we want to keep the empty list
@@ -56,7 +55,7 @@ func QueryKeysRequestHandler(indent bool) http.HandlerFunc {
keysOutput, err := Bech32KeysOutput(infos)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
PostProcessResponse(w, cdc, keysOutput, indent)
+57
View File
@@ -0,0 +1,57 @@
package keys
import (
"testing"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/stretchr/testify/assert"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/spf13/cobra"
)
func Test_runListCmd(t *testing.T) {
type args struct {
cmd *cobra.Command
args []string
}
cmdBasic := listKeysCmd()
// Prepare some keybases
kbHome1, cleanUp1, err := tests.GetTempDir("Test_runListCmd")
defer cleanUp1()
assert.NoError(t, err)
// Do nothing, leave home1 empty
kbHome2, cleanUp2, err := tests.GetTempDir("Test_runListCmd")
defer cleanUp2()
viper.Set(cli.HomeFlag, kbHome2)
assert.NoError(t, err)
kb, err := NewKeyBaseFromHomeFlag()
assert.NoError(t, err)
_, err = kb.CreateAccount("something", tests.TestMnemonic, "", "", 0, 0)
assert.NoError(t, err)
testData := []struct {
name string
kbDir string
args args
wantErr bool
}{
{"invalid keybase", "/dev/null", args{cmdBasic, []string{}}, true},
{"keybase: empty", kbHome1, args{cmdBasic, []string{}}, false},
{"keybase: w/key", kbHome2, args{cmdBasic, []string{}}, false},
}
for _, tt := range testData {
t.Run(tt.name, func(t *testing.T) {
viper.Set(cli.HomeFlag, tt.kbDir)
if err := runListCmd(tt.args.cmd, tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("runListCmd() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
+1 -3
View File
@@ -43,9 +43,7 @@ func runMnemonicCmd(cmd *cobra.Command, args []string) error {
if len(inputEntropy) < 43 {
return fmt.Errorf("256-bits is 43 characters in Base-64, and 100 in Base-6. You entered %v, and probably want more", len(inputEntropy))
}
conf, err := client.GetConfirmation(
fmt.Sprintf("> Input length: %d", len(inputEntropy)),
buf)
conf, err := client.GetConfirmation(fmt.Sprintf("> Input length: %d", len(inputEntropy)), buf)
if err != nil {
return err
}
+59
View File
@@ -0,0 +1,59 @@
package keys
import (
"bufio"
"strings"
"testing"
"github.com/cosmos/cosmos-sdk/client"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_RunMnemonicCmdNormal(t *testing.T) {
cmdBasic := mnemonicKeyCommand()
err := runMnemonicCmd(cmdBasic, []string{})
require.NoError(t, err)
}
func Test_RunMnemonicCmdUser(t *testing.T) {
cmdUser := mnemonicKeyCommand()
err := cmdUser.Flags().Set(flagUserEntropy, "1")
assert.NoError(t, err)
err = runMnemonicCmd(cmdUser, []string{})
require.Error(t, err)
require.Equal(t, "EOF", err.Error())
// Try again
cleanUp := client.OverrideStdin(bufio.NewReader(strings.NewReader("Hi!\n")))
defer cleanUp()
err = runMnemonicCmd(cmdUser, []string{})
require.Error(t, err)
require.Equal(t,
"256-bits is 43 characters in Base-64, and 100 in Base-6. You entered 3, and probably want more",
err.Error())
// Now provide "good" entropy :)
fakeEntropy := strings.Repeat(":)", 40) + "\ny\n" // entropy + accept count
cleanUp2 := client.OverrideStdin(bufio.NewReader(strings.NewReader(fakeEntropy)))
defer cleanUp2()
err = runMnemonicCmd(cmdUser, []string{})
require.NoError(t, err)
// Now provide "good" entropy but no answer
fakeEntropy = strings.Repeat(":)", 40) + "\n" // entropy + accept count
cleanUp3 := client.OverrideStdin(bufio.NewReader(strings.NewReader(fakeEntropy)))
defer cleanUp3()
err = runMnemonicCmd(cmdUser, []string{})
require.Error(t, err)
// Now provide "good" entropy but say no
fakeEntropy = strings.Repeat(":)", 40) + "\nn\n" // entropy + accept count
cleanUp4 := client.OverrideStdin(bufio.NewReader(strings.NewReader(fakeEntropy)))
defer cleanUp4()
err = runMnemonicCmd(cmdUser, []string{})
require.NoError(t, err)
}
+1 -1
View File
@@ -22,7 +22,7 @@ func Commands() *cobra.Command {
cmd.AddCommand(
mnemonicKeyCommand(),
addKeyCommand(),
listKeysCmd,
listKeysCmd(),
showKeysCmd(),
client.LineBreak,
deleteKeyCommand(),
+22
View File
@@ -0,0 +1,22 @@
package keys
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/gorilla/mux"
)
func TestCommands(t *testing.T) {
rootCommands := Commands()
assert.NotNil(t, rootCommands)
// Commands are registered
assert.Equal(t, 7, len(rootCommands.Commands()))
}
func TestRegisterRoutes(t *testing.T) {
fakeRouter := mux.Router{}
RegisterRoutes(&fakeRouter, false)
}
+10 -5
View File
@@ -93,7 +93,12 @@ func runShowCmd(cmd *cobra.Command, args []string) (err error) {
isShowAddr := viper.GetBool(FlagAddress)
isShowPubKey := viper.GetBool(FlagPublicKey)
isOutputSet := cmd.Flag(cli.OutputFlag).Changed
isOutputSet := false
tmp := cmd.Flag(cli.OutputFlag)
if tmp != nil {
isOutputSet = tmp.Changed
}
if isShowAddr && isShowPubKey {
return errors.New("cannot use both --address and --pubkey at once")
@@ -161,25 +166,25 @@ func GetKeyRequestHandler(indent bool) http.HandlerFunc {
bechKeyOut, err := getBechKeyOut(bechPrefix)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
info, err := GetKeyInfo(name)
if keyerror.IsErrKeyNotFound(err) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
keyOutput, err := bechKeyOut(info)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
+146
View File
@@ -0,0 +1,146 @@
package keys
import (
"testing"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/stretchr/testify/assert"
"github.com/cosmos/cosmos-sdk/crypto/keys"
)
func Test_multiSigKey_Properties(t *testing.T) {
tmpKey1 := secp256k1.GenPrivKeySecp256k1([]byte("mySecret"))
tmp := multiSigKey{
name: "myMultisig",
key: tmpKey1.PubKey(),
}
assert.Equal(t, "myMultisig", tmp.GetName())
assert.Equal(t, keys.TypeLocal, tmp.GetType())
assert.Equal(t, "015ABFFB09DB738A45745A91E8C401423ECE4016", tmp.GetPubKey().Address().String())
assert.Equal(t, "cosmos1q9dtl7cfmdec53t5t2g733qpgglvusqk6xdntl", tmp.GetAddress().String())
}
func Test_showKeysCmd(t *testing.T) {
cmd := showKeysCmd()
assert.NotNil(t, cmd)
assert.Equal(t, "false", cmd.Flag(FlagAddress).DefValue)
assert.Equal(t, "false", cmd.Flag(FlagPublicKey).DefValue)
}
func Test_runShowCmd(t *testing.T) {
cmd := showKeysCmd()
err := runShowCmd(cmd, []string{"invalid"})
assert.EqualError(t, err, "Key invalid not found")
err = runShowCmd(cmd, []string{"invalid1", "invalid2"})
assert.EqualError(t, err, "Key invalid1 not found")
// Prepare a key base
// Now add a temporary keybase
kbHome, cleanUp, err := tests.GetTempDir("Test_runShowCmd")
assert.NoError(t, err)
defer cleanUp()
viper.Set(cli.HomeFlag, kbHome)
fakeKeyName1 := "runShowCmd_Key1"
fakeKeyName2 := "runShowCmd_Key2"
kb, err := NewKeyBaseFromHomeFlag()
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName1, tests.TestMnemonic, "", "", 0, 0)
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName2, tests.TestMnemonic, "", "", 0, 1)
assert.NoError(t, err)
// Now try single key
err = runShowCmd(cmd, []string{fakeKeyName1})
assert.EqualError(t, err, "invalid Bech32 prefix encoding provided: ")
// Now try single key - set bech to acc
viper.Set(FlagBechPrefix, "acc")
err = runShowCmd(cmd, []string{fakeKeyName1})
assert.NoError(t, err)
// Now try multisig key - set bech to acc
viper.Set(FlagBechPrefix, "acc")
err = runShowCmd(cmd, []string{fakeKeyName1, fakeKeyName2})
assert.EqualError(t, err, "threshold must be a positive integer")
// Now try multisig key - set bech to acc + threshold=2
viper.Set(FlagBechPrefix, "acc")
viper.Set(flagMultiSigThreshold, 2)
err = runShowCmd(cmd, []string{fakeKeyName1, fakeKeyName2})
assert.NoError(t, err)
// TODO: Capture stdout and compare
}
func Test_validateMultisigThreshold(t *testing.T) {
type args struct {
k int
nKeys int
}
tests := []struct {
name string
args args
wantErr bool
}{
{"zeros", args{0, 0}, true},
{"1-0", args{1, 0}, true},
{"1-1", args{1, 1}, false},
{"1-2", args{1, 1}, false},
{"1-2", args{2, 1}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := validateMultisigThreshold(tt.args.k, tt.args.nKeys); (err != nil) != tt.wantErr {
t.Errorf("validateMultisigThreshold() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_getBechKeyOut(t *testing.T) {
type args struct {
bechPrefix string
}
tests := []struct {
name string
args args
want bechKeyOutFn
wantErr bool
}{
{"empty", args{""}, nil, true},
{"wrong", args{"???"}, nil, true},
{"acc", args{"acc"}, Bech32KeyOutput, false},
{"val", args{"val"}, Bech32ValKeyOutput, false},
{"cons", args{"cons"}, Bech32ConsKeyOutput, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getBechKeyOut(tt.args.bechPrefix)
if (err != nil) != tt.wantErr {
t.Errorf("getBechKeyOut() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr {
assert.NotNil(t, got)
}
// TODO: Still not possible to compare functions
// Maybe in next release: https://github.com/stretchr/testify/issues/182
//if &got != &tt.want {
// t.Errorf("getBechKeyOut() = %v, want %v", got, tt.want)
//}
})
}
}
+6 -6
View File
@@ -8,7 +8,7 @@ import (
"github.com/gorilla/mux"
"github.com/cosmos/cosmos-sdk/client"
keys "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/spf13/cobra"
@@ -73,14 +73,14 @@ func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
err := decoder.Decode(&m)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
kb, err = NewKeyBaseFromHomeFlag()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
@@ -89,15 +89,15 @@ func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
err = kb.Update(name, m.OldPassword, getNewpass)
if keyerror.IsErrKeyNotFound(err) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if keyerror.IsErrWrongPassword(err) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
+64
View File
@@ -0,0 +1,64 @@
package keys
import (
"bufio"
"strings"
"testing"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/stretchr/testify/assert"
)
func Test_updateKeyCommand(t *testing.T) {
cmd := updateKeyCommand()
assert.NotNil(t, cmd)
// No flags or defaults to validate
}
func Test_runUpdateCmd(t *testing.T) {
fakeKeyName1 := "runUpdateCmd_Key1"
fakeKeyName2 := "runUpdateCmd_Key2"
cmd := updateKeyCommand()
// fails because it requests a password
err := runUpdateCmd(cmd, []string{fakeKeyName1})
assert.EqualError(t, err, "EOF")
cleanUp := client.OverrideStdin(bufio.NewReader(strings.NewReader("pass1234\n")))
defer cleanUp()
// try again
err = runUpdateCmd(cmd, []string{fakeKeyName1})
assert.EqualError(t, err, "Key runUpdateCmd_Key1 not found")
// Prepare a key base
// Now add a temporary keybase
kbHome, cleanUp1, err := tests.GetTempDir("Test_runShowCmd")
assert.NoError(t, err)
defer cleanUp1()
viper.Set(cli.HomeFlag, kbHome)
kb, err := NewKeyBaseFromHomeFlag()
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName1, tests.TestMnemonic, "", "", 0, 0)
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName2, tests.TestMnemonic, "", "", 0, 1)
assert.NoError(t, err)
// Try again now that we have keys
cleanUp2 := client.OverrideStdin(bufio.NewReader(strings.NewReader("pass1234\nNew1234\nNew1234")))
defer cleanUp2()
// Incorrect key type
err = runUpdateCmd(cmd, []string{fakeKeyName1})
assert.EqualError(t, err, "locally stored key required. Received: keys.offlineInfo")
// TODO: Check for other type types?
}
+10 -6
View File
@@ -15,7 +15,11 @@ import (
)
// KeyDBName is the directory under root where we store the keys
const KeyDBName = "keys"
const (
KeyDBName = "keys"
OutputFormatText = "text"
OutputFormatJSON = "json"
)
type bechKeyOutFn func(keyInfo keys.Info) (KeyOutput, error)
@@ -157,7 +161,7 @@ func printKeyInfo(keyInfo keys.Info, bechKeyOut bechKeyOutFn) {
}
switch viper.Get(cli.OutputFlag) {
case "text":
case OutputFormatText:
fmt.Printf("NAME:\tTYPE:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
printKeyOutput(ko)
case "json":
@@ -176,12 +180,12 @@ func printInfos(infos []keys.Info) {
panic(err)
}
switch viper.Get(cli.OutputFlag) {
case "text":
case OutputFormatText:
fmt.Printf("NAME:\tTYPE:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
for _, ko := range kos {
printKeyOutput(ko)
}
case "json":
case OutputFormatJSON:
out, err := MarshalJSON(kos)
if err != nil {
panic(err)
@@ -225,12 +229,12 @@ func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response inter
}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
case []byte:
output = response.([]byte)
}
w.Header().Set("Content-Type", "application/json")
w.Write(output)
_, _ = w.Write(output)
}
+1 -1
View File
@@ -175,7 +175,7 @@ func TestVersion(t *testing.T) {
reg, err := regexp.Compile(`\d+\.\d+\.\d+.*`)
require.Nil(t, err)
match := reg.MatchString(body)
require.True(t, match, body, fmt.Sprintf("%s", body))
require.True(t, match, body, body)
// node info
res, body = Request(t, port, "GET", "/node_version", nil)