github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/repo/rename/rename_test.go (about) 1 package rename 2 3 import ( 4 "bytes" 5 "net/http" 6 "testing" 7 8 "github.com/ungtb10d/cli/v2/context" 9 "github.com/ungtb10d/cli/v2/git" 10 "github.com/ungtb10d/cli/v2/internal/config" 11 "github.com/ungtb10d/cli/v2/internal/ghrepo" 12 "github.com/ungtb10d/cli/v2/internal/run" 13 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 14 "github.com/ungtb10d/cli/v2/pkg/httpmock" 15 "github.com/ungtb10d/cli/v2/pkg/iostreams" 16 "github.com/ungtb10d/cli/v2/pkg/prompt" 17 "github.com/google/shlex" 18 "github.com/stretchr/testify/assert" 19 ) 20 21 func TestNewCmdRename(t *testing.T) { 22 testCases := []struct { 23 name string 24 input string 25 output RenameOptions 26 errMsg string 27 tty bool 28 wantErr bool 29 }{ 30 { 31 name: "no arguments no tty", 32 input: "", 33 errMsg: "new name argument required when not running interactively", 34 wantErr: true, 35 }, 36 { 37 name: "one argument no tty confirmed", 38 input: "REPO --confirm", 39 output: RenameOptions{ 40 newRepoSelector: "REPO", 41 }, 42 }, 43 { 44 name: "one argument no tty", 45 input: "REPO", 46 errMsg: "--confirm required when passing a single argument", 47 wantErr: true, 48 }, 49 { 50 name: "one argument tty confirmed", 51 input: "REPO --confirm", 52 tty: true, 53 output: RenameOptions{ 54 newRepoSelector: "REPO", 55 }, 56 }, 57 { 58 name: "one argument tty", 59 input: "REPO", 60 tty: true, 61 output: RenameOptions{ 62 newRepoSelector: "REPO", 63 DoConfirm: true, 64 }, 65 }, 66 { 67 name: "full flag argument", 68 input: "--repo OWNER/REPO NEW_REPO", 69 output: RenameOptions{ 70 newRepoSelector: "NEW_REPO", 71 }, 72 }, 73 } 74 for _, tt := range testCases { 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 83 argv, err := shlex.Split(tt.input) 84 assert.NoError(t, err) 85 var gotOpts *RenameOptions 86 cmd := NewCmdRename(f, func(opts *RenameOptions) error { 87 gotOpts = 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.EqualError(t, err, tt.errMsg) 98 return 99 } 100 assert.NoError(t, err) 101 assert.Equal(t, tt.output.newRepoSelector, gotOpts.newRepoSelector) 102 }) 103 } 104 } 105 106 func TestRenameRun(t *testing.T) { 107 testCases := []struct { 108 name string 109 opts RenameOptions 110 httpStubs func(*httpmock.Registry) 111 execStubs func(*run.CommandStubber) 112 askStubs func(*prompt.AskStubber) 113 wantOut string 114 tty bool 115 }{ 116 { 117 name: "none argument", 118 wantOut: "✓ Renamed repository OWNER/NEW_REPO\n✓ Updated the \"origin\" remote\n", 119 askStubs: func(q *prompt.AskStubber) { 120 //nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt 121 q.StubOne("NEW_REPO") 122 }, 123 httpStubs: func(reg *httpmock.Registry) { 124 reg.Register( 125 httpmock.REST("PATCH", "repos/OWNER/REPO"), 126 httpmock.StatusStringResponse(200, `{"name":"NEW_REPO","owner":{"login":"OWNER"}}`)) 127 }, 128 execStubs: func(cs *run.CommandStubber) { 129 cs.Register(`git remote set-url origin https://github.com/OWNER/NEW_REPO.git`, 0, "") 130 }, 131 tty: true, 132 }, 133 { 134 name: "repo override", 135 opts: RenameOptions{ 136 HasRepoOverride: true, 137 }, 138 wantOut: "✓ Renamed repository OWNER/NEW_REPO\n", 139 askStubs: func(q *prompt.AskStubber) { 140 //nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt 141 q.StubOne("NEW_REPO") 142 }, 143 httpStubs: func(reg *httpmock.Registry) { 144 reg.Register( 145 httpmock.REST("PATCH", "repos/OWNER/REPO"), 146 httpmock.StatusStringResponse(200, `{"name":"NEW_REPO","owner":{"login":"OWNER"}}`)) 147 }, 148 tty: true, 149 }, 150 { 151 name: "owner repo change name argument tty", 152 opts: RenameOptions{ 153 newRepoSelector: "NEW_REPO", 154 }, 155 wantOut: "✓ Renamed repository OWNER/NEW_REPO\n✓ Updated the \"origin\" remote\n", 156 httpStubs: func(reg *httpmock.Registry) { 157 reg.Register( 158 httpmock.REST("PATCH", "repos/OWNER/REPO"), 159 httpmock.StatusStringResponse(200, `{"name":"NEW_REPO","owner":{"login":"OWNER"}}`)) 160 }, 161 execStubs: func(cs *run.CommandStubber) { 162 cs.Register(`git remote set-url origin https://github.com/OWNER/NEW_REPO.git`, 0, "") 163 }, 164 tty: true, 165 }, 166 { 167 name: "owner repo change name argument no tty", 168 opts: RenameOptions{ 169 newRepoSelector: "NEW_REPO", 170 }, 171 httpStubs: func(reg *httpmock.Registry) { 172 reg.Register( 173 httpmock.REST("PATCH", "repos/OWNER/REPO"), 174 httpmock.StatusStringResponse(200, `{"name":"NEW_REPO","owner":{"login":"OWNER"}}`)) 175 }, 176 execStubs: func(cs *run.CommandStubber) { 177 cs.Register(`git remote set-url origin https://github.com/OWNER/NEW_REPO.git`, 0, "") 178 }, 179 }, 180 { 181 name: "confirmation with yes", 182 tty: true, 183 opts: RenameOptions{ 184 newRepoSelector: "NEW_REPO", 185 DoConfirm: true, 186 }, 187 wantOut: "✓ Renamed repository OWNER/NEW_REPO\n✓ Updated the \"origin\" remote\n", 188 askStubs: func(q *prompt.AskStubber) { 189 //nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt 190 q.StubOne(true) 191 }, 192 httpStubs: func(reg *httpmock.Registry) { 193 reg.Register( 194 httpmock.REST("PATCH", "repos/OWNER/REPO"), 195 httpmock.StatusStringResponse(200, `{"name":"NEW_REPO","owner":{"login":"OWNER"}}`)) 196 }, 197 execStubs: func(cs *run.CommandStubber) { 198 cs.Register(`git remote set-url origin https://github.com/OWNER/NEW_REPO.git`, 0, "") 199 }, 200 }, 201 202 { 203 name: "confirmation with no", 204 tty: true, 205 opts: RenameOptions{ 206 newRepoSelector: "NEW_REPO", 207 DoConfirm: true, 208 }, 209 askStubs: func(q *prompt.AskStubber) { 210 //nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt 211 q.StubOne(false) 212 }, 213 wantOut: "", 214 }, 215 } 216 217 for _, tt := range testCases { 218 //nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber 219 q, teardown := prompt.InitAskStubber() 220 defer teardown() 221 if tt.askStubs != nil { 222 tt.askStubs(q) 223 } 224 225 repo, _ := ghrepo.FromFullName("OWNER/REPO") 226 tt.opts.BaseRepo = func() (ghrepo.Interface, error) { 227 return repo, nil 228 } 229 230 tt.opts.Config = func() (config.Config, error) { 231 return config.NewBlankConfig(), nil 232 } 233 234 tt.opts.Remotes = func() (context.Remotes, error) { 235 return []*context.Remote{ 236 { 237 Remote: &git.Remote{Name: "origin"}, 238 Repo: repo, 239 }, 240 }, nil 241 } 242 243 cs, restoreRun := run.Stub() 244 defer restoreRun(t) 245 if tt.execStubs != nil { 246 tt.execStubs(cs) 247 } 248 249 reg := &httpmock.Registry{} 250 if tt.httpStubs != nil { 251 tt.httpStubs(reg) 252 } 253 tt.opts.HttpClient = func() (*http.Client, error) { 254 return &http.Client{Transport: reg}, nil 255 } 256 257 ios, _, stdout, _ := iostreams.Test() 258 ios.SetStdinTTY(tt.tty) 259 ios.SetStdoutTTY(tt.tty) 260 tt.opts.IO = ios 261 262 tt.opts.GitClient = &git.Client{GitPath: "some/path/git"} 263 264 t.Run(tt.name, func(t *testing.T) { 265 defer reg.Verify(t) 266 err := renameRun(&tt.opts) 267 assert.NoError(t, err) 268 assert.Equal(t, tt.wantOut, stdout.String()) 269 }) 270 } 271 }