github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/gpg-key/delete/delete_test.go (about) 1 package delete 2 3 import ( 4 "bytes" 5 "net/http" 6 "testing" 7 8 "github.com/ungtb10d/cli/v2/internal/config" 9 "github.com/ungtb10d/cli/v2/internal/prompter" 10 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 11 "github.com/ungtb10d/cli/v2/pkg/httpmock" 12 "github.com/ungtb10d/cli/v2/pkg/iostreams" 13 "github.com/google/shlex" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestNewCmdDelete(t *testing.T) { 18 tests := []struct { 19 name string 20 tty bool 21 input string 22 output DeleteOptions 23 wantErr bool 24 wantErrMsg string 25 }{ 26 { 27 name: "tty", 28 tty: true, 29 input: "ABC123", 30 output: DeleteOptions{KeyID: "ABC123", Confirmed: false}, 31 }, 32 { 33 name: "confirm flag tty", 34 tty: true, 35 input: "ABC123 --confirm", 36 output: DeleteOptions{KeyID: "ABC123", Confirmed: true}, 37 }, 38 { 39 name: "shorthand confirm flag tty", 40 tty: true, 41 input: "ABC123 -y", 42 output: DeleteOptions{KeyID: "ABC123", Confirmed: true}, 43 }, 44 { 45 name: "no tty", 46 input: "ABC123", 47 wantErr: true, 48 wantErrMsg: "--confirm required when not running interactively", 49 }, 50 { 51 name: "confirm flag no tty", 52 input: "ABC123 --confirm", 53 output: DeleteOptions{KeyID: "ABC123", Confirmed: true}, 54 }, 55 { 56 name: "shorthand confirm flag no tty", 57 input: "ABC123 -y", 58 output: DeleteOptions{KeyID: "ABC123", Confirmed: true}, 59 }, 60 { 61 name: "no args", 62 input: "", 63 wantErr: true, 64 wantErrMsg: "cannot delete: key id required", 65 }, 66 { 67 name: "too many args", 68 input: "ABC123 XYZ", 69 wantErr: true, 70 wantErrMsg: "too many arguments", 71 }, 72 } 73 74 for _, tt := range tests { 75 t.Run(tt.name, func(t *testing.T) { 76 ios, _, _, _ := iostreams.Test() 77 ios.SetStdinTTY(tt.tty) 78 ios.SetStdoutTTY(tt.tty) 79 f := &cmdutil.Factory{ 80 IOStreams: ios, 81 } 82 argv, err := shlex.Split(tt.input) 83 assert.NoError(t, err) 84 85 var cmdOpts *DeleteOptions 86 cmd := NewCmdDelete(f, func(opts *DeleteOptions) error { 87 cmdOpts = opts 88 return nil 89 }) 90 cmd.SetArgs(argv) 91 cmd.SetIn(&bytes.Buffer{}) 92 cmd.SetOut(&bytes.Buffer{}) 93 cmd.SetErr(&bytes.Buffer{}) 94 95 _, err = cmd.ExecuteC() 96 if tt.wantErr { 97 assert.Error(t, err) 98 assert.EqualError(t, err, tt.wantErrMsg) 99 return 100 } 101 assert.NoError(t, err) 102 assert.Equal(t, tt.output.KeyID, cmdOpts.KeyID) 103 assert.Equal(t, tt.output.Confirmed, cmdOpts.Confirmed) 104 }) 105 } 106 } 107 108 func Test_deleteRun(t *testing.T) { 109 keysResp := "[{\"id\":123,\"key_id\":\"ABC123\"}]" 110 tests := []struct { 111 name string 112 tty bool 113 opts DeleteOptions 114 httpStubs func(*httpmock.Registry) 115 prompterStubs func(*prompter.PrompterMock) 116 wantStdout string 117 wantErr bool 118 wantErrMsg string 119 }{ 120 { 121 name: "delete tty", 122 tty: true, 123 opts: DeleteOptions{KeyID: "ABC123", Confirmed: false}, 124 prompterStubs: func(pm *prompter.PrompterMock) { 125 pm.ConfirmDeletionFunc = func(_ string) error { 126 return nil 127 } 128 }, 129 httpStubs: func(reg *httpmock.Registry) { 130 reg.Register(httpmock.REST("GET", "user/gpg_keys"), httpmock.StatusStringResponse(200, keysResp)) 131 reg.Register(httpmock.REST("DELETE", "user/gpg_keys/123"), httpmock.StatusStringResponse(204, "")) 132 }, 133 wantStdout: "✓ GPG key ABC123 deleted from your account\n", 134 }, 135 { 136 name: "delete with confirm flag tty", 137 tty: true, 138 opts: DeleteOptions{KeyID: "ABC123", Confirmed: true}, 139 httpStubs: func(reg *httpmock.Registry) { 140 reg.Register(httpmock.REST("GET", "user/gpg_keys"), httpmock.StatusStringResponse(200, keysResp)) 141 reg.Register(httpmock.REST("DELETE", "user/gpg_keys/123"), httpmock.StatusStringResponse(204, "")) 142 }, 143 wantStdout: "✓ GPG key ABC123 deleted from your account\n", 144 }, 145 { 146 name: "not found tty", 147 tty: true, 148 opts: DeleteOptions{KeyID: "ABC123", Confirmed: true}, 149 httpStubs: func(reg *httpmock.Registry) { 150 reg.Register(httpmock.REST("GET", "user/gpg_keys"), httpmock.StatusStringResponse(200, "[]")) 151 }, 152 wantErr: true, 153 wantErrMsg: "unable to delete GPG key ABC123: either the GPG key is not found or it is not owned by you", 154 }, 155 { 156 name: "delete no tty", 157 opts: DeleteOptions{KeyID: "ABC123", Confirmed: true}, 158 httpStubs: func(reg *httpmock.Registry) { 159 reg.Register(httpmock.REST("GET", "user/gpg_keys"), httpmock.StatusStringResponse(200, keysResp)) 160 reg.Register(httpmock.REST("DELETE", "user/gpg_keys/123"), httpmock.StatusStringResponse(204, "")) 161 }, 162 wantStdout: "", 163 }, 164 { 165 name: "not found no tty", 166 opts: DeleteOptions{KeyID: "ABC123", Confirmed: true}, 167 httpStubs: func(reg *httpmock.Registry) { 168 reg.Register(httpmock.REST("GET", "user/gpg_keys"), httpmock.StatusStringResponse(200, "[]")) 169 }, 170 wantErr: true, 171 wantErrMsg: "unable to delete GPG key ABC123: either the GPG key is not found or it is not owned by you", 172 }, 173 } 174 175 for _, tt := range tests { 176 pm := &prompter.PrompterMock{} 177 if tt.prompterStubs != nil { 178 tt.prompterStubs(pm) 179 } 180 tt.opts.Prompter = pm 181 182 reg := &httpmock.Registry{} 183 if tt.httpStubs != nil { 184 tt.httpStubs(reg) 185 } 186 187 tt.opts.HttpClient = func() (*http.Client, error) { 188 return &http.Client{Transport: reg}, nil 189 } 190 tt.opts.Config = func() (config.Config, error) { 191 return config.NewBlankConfig(), nil 192 } 193 ios, _, stdout, _ := iostreams.Test() 194 ios.SetStdinTTY(tt.tty) 195 ios.SetStdoutTTY(tt.tty) 196 tt.opts.IO = ios 197 198 t.Run(tt.name, func(t *testing.T) { 199 err := deleteRun(&tt.opts) 200 reg.Verify(t) 201 if tt.wantErr { 202 assert.Error(t, err) 203 assert.EqualError(t, err, tt.wantErrMsg) 204 return 205 } 206 assert.NoError(t, err) 207 assert.Equal(t, tt.wantStdout, stdout.String()) 208 }) 209 } 210 }