github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/run/cancel/cancel_test.go (about) 1 package cancel 2 3 import ( 4 "bytes" 5 "io" 6 "net/http" 7 "testing" 8 9 "github.com/ungtb10d/cli/v2/internal/ghrepo" 10 "github.com/ungtb10d/cli/v2/pkg/cmd/run/shared" 11 workflowShared "github.com/ungtb10d/cli/v2/pkg/cmd/workflow/shared" 12 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 13 "github.com/ungtb10d/cli/v2/pkg/httpmock" 14 "github.com/ungtb10d/cli/v2/pkg/iostreams" 15 "github.com/ungtb10d/cli/v2/pkg/prompt" 16 "github.com/google/shlex" 17 "github.com/stretchr/testify/assert" 18 ) 19 20 func TestNewCmdCancel(t *testing.T) { 21 tests := []struct { 22 name string 23 cli string 24 tty bool 25 wants CancelOptions 26 wantsErr bool 27 }{ 28 { 29 name: "blank tty", 30 tty: true, 31 wants: CancelOptions{ 32 Prompt: true, 33 }, 34 }, 35 { 36 name: "blank nontty", 37 wantsErr: true, 38 }, 39 { 40 name: "with arg", 41 cli: "1234", 42 wants: CancelOptions{ 43 RunID: "1234", 44 }, 45 }, 46 } 47 48 for _, tt := range tests { 49 t.Run(tt.name, func(t *testing.T) { 50 ios, _, _, _ := iostreams.Test() 51 ios.SetStdinTTY(tt.tty) 52 ios.SetStdoutTTY(tt.tty) 53 54 f := &cmdutil.Factory{ 55 IOStreams: ios, 56 } 57 58 argv, err := shlex.Split(tt.cli) 59 assert.NoError(t, err) 60 61 var gotOpts *CancelOptions 62 cmd := NewCmdCancel(f, func(opts *CancelOptions) error { 63 gotOpts = opts 64 return nil 65 }) 66 67 cmd.SetArgs(argv) 68 cmd.SetIn(&bytes.Buffer{}) 69 cmd.SetOut(io.Discard) 70 cmd.SetErr(io.Discard) 71 72 _, err = cmd.ExecuteC() 73 if tt.wantsErr { 74 assert.Error(t, err) 75 return 76 } 77 78 assert.NoError(t, err) 79 80 assert.Equal(t, tt.wants.RunID, gotOpts.RunID) 81 }) 82 } 83 } 84 85 func TestRunCancel(t *testing.T) { 86 inProgressRun := shared.TestRun(1234, shared.InProgress, "") 87 completedRun := shared.TestRun(4567, shared.Completed, shared.Failure) 88 tests := []struct { 89 name string 90 httpStubs func(*httpmock.Registry) 91 askStubs func(*prompt.AskStubber) 92 opts *CancelOptions 93 wantErr bool 94 wantOut string 95 errMsg string 96 }{ 97 { 98 name: "cancel run", 99 opts: &CancelOptions{ 100 RunID: "1234", 101 }, 102 wantErr: false, 103 httpStubs: func(reg *httpmock.Registry) { 104 reg.Register( 105 httpmock.REST("GET", "repos/OWNER/REPO/actions/runs/1234"), 106 httpmock.JSONResponse(inProgressRun)) 107 reg.Register( 108 httpmock.REST("GET", "repos/OWNER/REPO/actions/workflows/123"), 109 httpmock.JSONResponse(shared.TestWorkflow)) 110 reg.Register( 111 httpmock.REST("POST", "repos/OWNER/REPO/actions/runs/1234/cancel"), 112 httpmock.StatusStringResponse(202, "{}")) 113 }, 114 wantOut: "✓ Request to cancel workflow submitted.\n", 115 }, 116 { 117 name: "not found", 118 opts: &CancelOptions{ 119 RunID: "1234", 120 }, 121 wantErr: true, 122 errMsg: "Could not find any workflow run with ID 1234", 123 httpStubs: func(reg *httpmock.Registry) { 124 reg.Register( 125 httpmock.REST("GET", "repos/OWNER/REPO/actions/runs/1234"), 126 httpmock.StatusStringResponse(404, "")) 127 }, 128 }, 129 { 130 name: "completed", 131 opts: &CancelOptions{ 132 RunID: "4567", 133 }, 134 wantErr: true, 135 errMsg: "Cannot cancel a workflow run that is completed", 136 httpStubs: func(reg *httpmock.Registry) { 137 reg.Register( 138 httpmock.REST("GET", "repos/OWNER/REPO/actions/runs/4567"), 139 httpmock.JSONResponse(completedRun)) 140 reg.Register( 141 httpmock.REST("GET", "repos/OWNER/REPO/actions/workflows/123"), 142 httpmock.JSONResponse(shared.TestWorkflow)) 143 reg.Register( 144 httpmock.REST("POST", "repos/OWNER/REPO/actions/runs/4567/cancel"), 145 httpmock.StatusStringResponse(409, ""), 146 ) 147 }, 148 }, 149 { 150 name: "prompt, no in progress runs", 151 opts: &CancelOptions{ 152 Prompt: true, 153 }, 154 wantErr: true, 155 errMsg: "found no in progress runs to cancel", 156 httpStubs: func(reg *httpmock.Registry) { 157 reg.Register( 158 httpmock.REST("GET", "repos/OWNER/REPO/actions/runs"), 159 httpmock.JSONResponse(shared.RunsPayload{ 160 WorkflowRuns: []shared.Run{ 161 completedRun, 162 }, 163 })) 164 reg.Register( 165 httpmock.REST("GET", "repos/OWNER/REPO/actions/workflows"), 166 httpmock.JSONResponse(workflowShared.WorkflowsPayload{ 167 Workflows: []workflowShared.Workflow{ 168 shared.TestWorkflow, 169 }, 170 })) 171 }, 172 }, 173 { 174 name: "prompt, cancel", 175 opts: &CancelOptions{ 176 Prompt: true, 177 }, 178 httpStubs: func(reg *httpmock.Registry) { 179 reg.Register( 180 httpmock.REST("GET", "repos/OWNER/REPO/actions/runs"), 181 httpmock.JSONResponse(shared.RunsPayload{ 182 WorkflowRuns: []shared.Run{ 183 inProgressRun, 184 }, 185 })) 186 reg.Register( 187 httpmock.REST("GET", "repos/OWNER/REPO/actions/workflows"), 188 httpmock.JSONResponse(workflowShared.WorkflowsPayload{ 189 Workflows: []workflowShared.Workflow{ 190 shared.TestWorkflow, 191 }, 192 })) 193 reg.Register( 194 httpmock.REST("POST", "repos/OWNER/REPO/actions/runs/1234/cancel"), 195 httpmock.StatusStringResponse(202, "{}")) 196 }, 197 askStubs: func(as *prompt.AskStubber) { 198 //nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt 199 as.StubOne(0) 200 }, 201 wantOut: "✓ Request to cancel workflow submitted.\n", 202 }, 203 } 204 205 for _, tt := range tests { 206 reg := &httpmock.Registry{} 207 tt.httpStubs(reg) 208 tt.opts.HttpClient = func() (*http.Client, error) { 209 return &http.Client{Transport: reg}, nil 210 } 211 212 ios, _, stdout, _ := iostreams.Test() 213 ios.SetStdoutTTY(true) 214 ios.SetStdinTTY(true) 215 tt.opts.IO = ios 216 tt.opts.BaseRepo = func() (ghrepo.Interface, error) { 217 return ghrepo.FromFullName("OWNER/REPO") 218 } 219 220 //nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber 221 as, teardown := prompt.InitAskStubber() 222 defer teardown() 223 if tt.askStubs != nil { 224 tt.askStubs(as) 225 } 226 227 t.Run(tt.name, func(t *testing.T) { 228 err := runCancel(tt.opts) 229 if tt.wantErr { 230 assert.Error(t, err) 231 if tt.errMsg != "" { 232 assert.Equal(t, tt.errMsg, err.Error()) 233 } 234 } else { 235 assert.NoError(t, err) 236 } 237 assert.Equal(t, tt.wantOut, stdout.String()) 238 reg.Verify(t) 239 }) 240 } 241 }