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  }