1package delete 2 3import ( 4 "bytes" 5 "io/ioutil" 6 "net/http" 7 "testing" 8 9 "github.com/MakeNowJust/heredoc" 10 "github.com/cli/cli/v2/internal/ghrepo" 11 "github.com/cli/cli/v2/pkg/cmdutil" 12 "github.com/cli/cli/v2/pkg/httpmock" 13 "github.com/cli/cli/v2/pkg/iostreams" 14 "github.com/google/shlex" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17) 18 19func Test_NewCmdDelete(t *testing.T) { 20 tests := []struct { 21 name string 22 args string 23 isTTY bool 24 want DeleteOptions 25 wantErr string 26 }{ 27 { 28 name: "version argument", 29 args: "v1.2.3", 30 isTTY: true, 31 want: DeleteOptions{ 32 TagName: "v1.2.3", 33 SkipConfirm: false, 34 }, 35 }, 36 { 37 name: "skip confirm", 38 args: "v1.2.3 -y", 39 isTTY: true, 40 want: DeleteOptions{ 41 TagName: "v1.2.3", 42 SkipConfirm: true, 43 }, 44 }, 45 { 46 name: "no arguments", 47 args: "", 48 isTTY: true, 49 wantErr: "accepts 1 arg(s), received 0", 50 }, 51 } 52 for _, tt := range tests { 53 t.Run(tt.name, func(t *testing.T) { 54 io, _, _, _ := iostreams.Test() 55 io.SetStdoutTTY(tt.isTTY) 56 io.SetStdinTTY(tt.isTTY) 57 io.SetStderrTTY(tt.isTTY) 58 59 f := &cmdutil.Factory{ 60 IOStreams: io, 61 } 62 63 var opts *DeleteOptions 64 cmd := NewCmdDelete(f, func(o *DeleteOptions) error { 65 opts = o 66 return nil 67 }) 68 cmd.PersistentFlags().StringP("repo", "R", "", "") 69 70 argv, err := shlex.Split(tt.args) 71 require.NoError(t, err) 72 cmd.SetArgs(argv) 73 74 cmd.SetIn(&bytes.Buffer{}) 75 cmd.SetOut(ioutil.Discard) 76 cmd.SetErr(ioutil.Discard) 77 78 _, err = cmd.ExecuteC() 79 if tt.wantErr != "" { 80 require.EqualError(t, err, tt.wantErr) 81 return 82 } else { 83 require.NoError(t, err) 84 } 85 86 assert.Equal(t, tt.want.TagName, opts.TagName) 87 assert.Equal(t, tt.want.SkipConfirm, opts.SkipConfirm) 88 }) 89 } 90} 91 92func Test_deleteRun(t *testing.T) { 93 tests := []struct { 94 name string 95 isTTY bool 96 opts DeleteOptions 97 wantErr string 98 wantStdout string 99 wantStderr string 100 }{ 101 { 102 name: "skipping confirmation", 103 isTTY: true, 104 opts: DeleteOptions{ 105 TagName: "v1.2.3", 106 SkipConfirm: true, 107 }, 108 wantStdout: ``, 109 wantStderr: heredoc.Doc(` 110 ✓ Deleted release v1.2.3 111 ! Note that the v1.2.3 git tag still remains in the repository 112 `), 113 }, 114 { 115 name: "non-interactive", 116 isTTY: false, 117 opts: DeleteOptions{ 118 TagName: "v1.2.3", 119 SkipConfirm: false, 120 }, 121 wantStdout: ``, 122 wantStderr: ``, 123 }, 124 } 125 for _, tt := range tests { 126 t.Run(tt.name, func(t *testing.T) { 127 io, _, stdout, stderr := iostreams.Test() 128 io.SetStdoutTTY(tt.isTTY) 129 io.SetStdinTTY(tt.isTTY) 130 io.SetStderrTTY(tt.isTTY) 131 132 fakeHTTP := &httpmock.Registry{} 133 fakeHTTP.Register(httpmock.REST("GET", "repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StringResponse(`{ 134 "tag_name": "v1.2.3", 135 "draft": false, 136 "url": "https://api.github.com/repos/OWNER/REPO/releases/23456" 137 }`)) 138 fakeHTTP.Register(httpmock.REST("DELETE", "repos/OWNER/REPO/releases/23456"), httpmock.StatusStringResponse(204, "")) 139 140 tt.opts.IO = io 141 tt.opts.HttpClient = func() (*http.Client, error) { 142 return &http.Client{Transport: fakeHTTP}, nil 143 } 144 tt.opts.BaseRepo = func() (ghrepo.Interface, error) { 145 return ghrepo.FromFullName("OWNER/REPO") 146 } 147 148 err := deleteRun(&tt.opts) 149 if tt.wantErr != "" { 150 require.EqualError(t, err, tt.wantErr) 151 return 152 } else { 153 require.NoError(t, err) 154 } 155 156 assert.Equal(t, tt.wantStdout, stdout.String()) 157 assert.Equal(t, tt.wantStderr, stderr.String()) 158 }) 159 } 160} 161