Skip to content

Commit 3215666

Browse files
committed
fix: error in ci when interactive inputs are required
1 parent 5ee9e10 commit 3215666

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

internal/iostreams/prompts.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,18 +192,30 @@ func errInteractivityFlags(cfg PromptConfig) error {
192192
// ConfirmPrompt prompts the user for a "yes" or "no" (true or false) value for
193193
// the message
194194
func (io *IOStreams) ConfirmPrompt(ctx context.Context, message string, defaultValue bool) (bool, error) {
195+
if !io.IsTTY() {
196+
return false, errInteractivityFlags(ConfirmPromptConfig{})
197+
}
195198
return confirmForm(io, ctx, message, defaultValue)
196199
}
197200

198201
// InputPrompt prompts the user for a string value for the message, which can
199202
// optionally be made required
200203
func (io *IOStreams) InputPrompt(ctx context.Context, message string, cfg InputPromptConfig) (string, error) {
204+
if !io.IsTTY() {
205+
if cfg.IsRequired() {
206+
return "", errInteractivityFlags(cfg)
207+
}
208+
return "", nil
209+
}
201210
return inputForm(io, ctx, message, cfg)
202211
}
203212

204213
// MultiSelectPrompt prompts the user to select multiple values in a list and
205214
// returns the selected values
206215
func (io *IOStreams) MultiSelectPrompt(ctx context.Context, message string, options []string) ([]string, error) {
216+
if !io.IsTTY() {
217+
return nil, errInteractivityFlags(MultiSelectPromptConfig{})
218+
}
207219
return multiSelectForm(io, ctx, message, options)
208220
}
209221

internal/iostreams/prompts_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,97 @@ func TestPasswordPrompt(t *testing.T) {
273273
}
274274
}
275275

276+
func TestConfirmPrompt(t *testing.T) {
277+
tests := map[string]struct {
278+
expectedError string
279+
}{
280+
"error if non-TTY": {
281+
expectedError: slackerror.ErrPrompt,
282+
},
283+
}
284+
for name, tc := range tests {
285+
t.Run(name, func(t *testing.T) {
286+
ctx := slackcontext.MockContext(t.Context())
287+
288+
fsMock := slackdeps.NewFsMock()
289+
osMock := slackdeps.NewOsMock()
290+
osMock.On("Stdout").Return(&slackdeps.FileMock{FileInfo: &slackdeps.FileInfoNamedPipe{}})
291+
cfg := config.NewConfig(fsMock, osMock)
292+
io := NewIOStreams(cfg, fsMock, osMock)
293+
294+
_, err := io.ConfirmPrompt(ctx, "Continue?", false)
295+
296+
assert.Error(t, err)
297+
assert.Equal(t, tc.expectedError, slackerror.ToSlackError(err).Code)
298+
})
299+
}
300+
}
301+
302+
func TestInputPrompt(t *testing.T) {
303+
tests := map[string]struct {
304+
required bool
305+
expectedError string
306+
expectedValue string
307+
}{
308+
"error if non-TTY and required": {
309+
required: true,
310+
expectedError: slackerror.ErrPrompt,
311+
},
312+
"no error if non-TTY and optional": {
313+
required: false,
314+
expectedValue: "",
315+
},
316+
}
317+
for name, tc := range tests {
318+
t.Run(name, func(t *testing.T) {
319+
ctx := slackcontext.MockContext(t.Context())
320+
321+
fsMock := slackdeps.NewFsMock()
322+
osMock := slackdeps.NewOsMock()
323+
osMock.On("Stdout").Return(&slackdeps.FileMock{FileInfo: &slackdeps.FileInfoNamedPipe{}})
324+
cfg := config.NewConfig(fsMock, osMock)
325+
io := NewIOStreams(cfg, fsMock, osMock)
326+
327+
value, err := io.InputPrompt(ctx, "Enter name", InputPromptConfig{
328+
Required: tc.required,
329+
})
330+
331+
if err != nil {
332+
assert.Equal(t, tc.expectedError, slackerror.ToSlackError(err).Code)
333+
} else {
334+
assert.NoError(t, err)
335+
assert.Equal(t, tc.expectedValue, value)
336+
}
337+
})
338+
}
339+
}
340+
341+
func TestMultiSelectPrompt(t *testing.T) {
342+
tests := map[string]struct {
343+
expectedError string
344+
}{
345+
"error if non-TTY": {
346+
expectedError: slackerror.ErrPrompt,
347+
},
348+
}
349+
for name, tc := range tests {
350+
t.Run(name, func(t *testing.T) {
351+
ctx := slackcontext.MockContext(t.Context())
352+
353+
fsMock := slackdeps.NewFsMock()
354+
osMock := slackdeps.NewOsMock()
355+
osMock.On("Stdout").Return(&slackdeps.FileMock{FileInfo: &slackdeps.FileInfoNamedPipe{}})
356+
cfg := config.NewConfig(fsMock, osMock)
357+
io := NewIOStreams(cfg, fsMock, osMock)
358+
359+
_, err := io.MultiSelectPrompt(ctx, "Pick items", []string{"a", "b"})
360+
361+
assert.Error(t, err)
362+
assert.Equal(t, tc.expectedError, slackerror.ToSlackError(err).Code)
363+
})
364+
}
365+
}
366+
276367
func TestSelectPrompt(t *testing.T) {
277368
tests := map[string]struct {
278369
flagValue string

0 commit comments

Comments
 (0)