github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/crypto/keys/client/export_test.go (about) 1 package client 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "strings" 8 "testing" 9 10 "github.com/gnolang/gno/tm2/pkg/commands" 11 "github.com/gnolang/gno/tm2/pkg/crypto/keys" 12 "github.com/gnolang/gno/tm2/pkg/testutils" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 // newTestKeybase generates a new test key-base 17 // Returns the temporary key-base, and its path 18 func newTestKeybase(t *testing.T) (keys.Keybase, string) { 19 t.Helper() 20 21 // Generate a temporary key-base directory 22 kbHome, kbCleanUp := testutils.NewTestCaseDir(t) 23 24 t.Cleanup(func() { 25 kbCleanUp() 26 }) 27 28 kb, err := keys.NewKeyBaseFromDir(kbHome) 29 if err != nil { 30 t.Fatalf( 31 "unable to create a key base in directory %s, %v", 32 kbHome, 33 err, 34 ) 35 } 36 37 return kb, kbHome 38 } 39 40 // addRandomKeyToKeybase adds a random key to the key-base 41 func addRandomKeyToKeybase( 42 kb keys.Keybase, 43 keyName, 44 encryptPassword string, 45 ) (keys.Info, error) { 46 // Generate a random mnemonic 47 mnemonic, err := GenerateMnemonic(mnemonicEntropySize) 48 if err != nil { 49 return nil, fmt.Errorf( 50 "unable to generate a mnemonic phrase, %w", 51 err, 52 ) 53 } 54 55 // Add the key to the key base 56 return kb.CreateAccount( 57 keyName, 58 mnemonic, 59 "", 60 encryptPassword, 61 0, 62 0, 63 ) 64 } 65 66 type testCmdKeyOptsBase struct { 67 kbHome string 68 keyName string 69 unsafe bool 70 } 71 72 type testExportKeyOpts struct { 73 testCmdKeyOptsBase 74 75 outputPath string 76 } 77 78 // exportKey runs the private key export command 79 // using the provided options 80 func exportKey( 81 exportOpts testExportKeyOpts, 82 input io.Reader, 83 ) error { 84 cfg := &ExportCfg{ 85 RootCfg: &BaseCfg{ 86 BaseOptions: BaseOptions{ 87 Home: exportOpts.kbHome, 88 InsecurePasswordStdin: true, 89 }, 90 }, 91 NameOrBech32: exportOpts.keyName, 92 OutputPath: exportOpts.outputPath, 93 Unsafe: exportOpts.unsafe, 94 } 95 96 cmdIO := commands.NewTestIO() 97 cmdIO.SetIn(input) 98 99 return execExport(cfg, cmdIO) 100 } 101 102 // TestExport_ExportKey makes sure the key can be exported correctly 103 func TestExport_ExportKey(t *testing.T) { 104 t.Parallel() 105 106 // numLines returns the number of new lines 107 // in a string 108 numLines := func(s string) int { 109 n := strings.Count(s, "\n") 110 if len(s) > 0 && !strings.HasSuffix(s, "\n") { 111 n++ 112 } 113 114 return n 115 } 116 117 const ( 118 keyName = "key name" 119 password = "password" 120 ) 121 122 testTable := []struct { 123 name string 124 baseOpts testCmdKeyOptsBase 125 input io.Reader 126 }{ 127 { 128 "encrypted key export", 129 testCmdKeyOptsBase{}, 130 strings.NewReader( 131 fmt.Sprintf( 132 "%s\n%s\n%s\n", 133 password, // decrypt 134 password, // encrypt 135 password, // encrypt confirm 136 ), 137 ), 138 }, 139 { 140 "unencrypted key export", 141 testCmdKeyOptsBase{ 142 unsafe: true, 143 }, 144 strings.NewReader( 145 fmt.Sprintf( 146 "%s\n", 147 password, // decrypt 148 ), 149 ), 150 }, 151 } 152 153 for _, testCase := range testTable { 154 testCase := testCase 155 156 t.Run(testCase.name, func(t *testing.T) { 157 t.Parallel() 158 159 // Generate a temporary key-base directory 160 kb, kbHome := newTestKeybase(t) 161 162 // Add an initial key to the key base 163 info, err := addRandomKeyToKeybase(kb, keyName, password) 164 if err != nil { 165 t.Fatalf( 166 "unable to create a key base account, %v", 167 err, 168 ) 169 } 170 171 outputFile, outputCleanupFn := testutils.NewTestFile(t) 172 t.Cleanup(func() { 173 outputCleanupFn() 174 }) 175 176 // Make sure the command executes correctly 177 assert.NoError( 178 t, 179 exportKey( 180 testExportKeyOpts{ 181 testCmdKeyOptsBase: testCmdKeyOptsBase{ 182 kbHome: kbHome, 183 keyName: info.GetName(), 184 unsafe: testCase.baseOpts.unsafe, 185 }, 186 outputPath: outputFile.Name(), 187 }, 188 testCase.input, 189 ), 190 ) 191 192 // Make sure the encrypted armor has been written to disk 193 buff, err := os.ReadFile(outputFile.Name()) 194 if err != nil { 195 t.Fatalf( 196 "unable to read temporary file from disk, %v", 197 err, 198 ) 199 } 200 201 assert.Greater(t, numLines(string(buff)), 1) 202 }) 203 } 204 } 205 206 func TestExport_ExportKeyWithEmptyName(t *testing.T) { 207 // Generate a temporary key-base directory 208 _, kbHome := newTestKeybase(t) 209 err := exportKey( 210 testExportKeyOpts{ 211 testCmdKeyOptsBase: testCmdKeyOptsBase{ 212 kbHome: kbHome, 213 keyName: "", 214 }, 215 }, 216 nil, 217 ) 218 assert.Error(t, err) 219 assert.EqualError(t, err, "key to be exported shouldn't be empty") 220 }