Skip to content

Commit 155507d

Browse files
committed
Make comment command easier to test
1 parent de73b16 commit 155507d

File tree

2 files changed

+76
-82
lines changed

2 files changed

+76
-82
lines changed

pkg/cmd/issue/comment/comment.go

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,19 @@ import (
1313
"github.com/cli/cli/pkg/cmd/issue/shared"
1414
"github.com/cli/cli/pkg/cmdutil"
1515
"github.com/cli/cli/pkg/iostreams"
16-
"github.com/cli/cli/pkg/prompt"
1716
"github.com/cli/cli/pkg/surveyext"
1817
"github.com/cli/cli/utils"
1918
"github.com/spf13/cobra"
2019
)
2120

2221
type CommentOptions struct {
23-
HttpClient func() (*http.Client, error)
24-
Config func() (config.Config, error)
25-
IO *iostreams.IOStreams
26-
BaseRepo func() (ghrepo.Interface, error)
27-
Edit func(string) (string, error)
22+
HttpClient func() (*http.Client, error)
23+
IO *iostreams.IOStreams
24+
BaseRepo func() (ghrepo.Interface, error)
25+
EditSurvey func() (string, error)
26+
InputTypeSurvey func() (int, error)
27+
ConfirmSubmitSurvey func() (bool, error)
28+
OpenInBrowser func(string) error
2829

2930
SelectorArg string
3031
Interactive bool
@@ -40,12 +41,12 @@ const (
4041

4142
func NewCmdComment(f *cmdutil.Factory, runF func(*CommentOptions) error) *cobra.Command {
4243
opts := &CommentOptions{
43-
IO: f.IOStreams,
44-
HttpClient: f.HttpClient,
45-
Config: f.Config,
46-
Edit: func(editorCommand string) (string, error) {
47-
return surveyext.Edit(editorCommand, "*.md", "", f.IOStreams.In, f.IOStreams.Out, f.IOStreams.ErrOut, nil)
48-
},
44+
IO: f.IOStreams,
45+
HttpClient: f.HttpClient,
46+
EditSurvey: editSurvey(f.Config, f.IOStreams),
47+
InputTypeSurvey: inputTypeSurvey,
48+
ConfirmSubmitSurvey: confirmSubmitSurvey,
49+
OpenInBrowser: utils.OpenInBrowser,
4950
}
5051

5152
var webMode bool
@@ -96,6 +97,7 @@ func NewCmdComment(f *cmdutil.Factory, runF func(*CommentOptions) error) *cobra.
9697
return commentRun(opts)
9798
},
9899
}
100+
99101
cmd.Flags().StringVarP(&opts.Body, "body", "b", "", "Supply a body. Will prompt for one otherwise.")
100102
cmd.Flags().BoolVarP(&editorMode, "editor", "e", false, "Add body using editor")
101103
cmd.Flags().BoolVarP(&webMode, "web", "w", false, "Add body in browser")
@@ -116,7 +118,7 @@ func commentRun(opts *CommentOptions) error {
116118
}
117119

118120
if opts.Interactive {
119-
inputType, err := inputTypeSurvey()
121+
inputType, err := opts.InputTypeSurvey()
120122
if err != nil {
121123
return err
122124
}
@@ -129,13 +131,9 @@ func commentRun(opts *CommentOptions) error {
129131
if opts.IO.IsStdoutTTY() {
130132
fmt.Fprintf(opts.IO.ErrOut, "Opening %s in your browser.\n", utils.DisplayURL(openURL))
131133
}
132-
return utils.OpenInBrowser(openURL)
134+
return opts.OpenInBrowser(openURL)
133135
case editor:
134-
editorCommand, err := cmdutil.DetermineEditor(opts.Config)
135-
if err != nil {
136-
return err
137-
}
138-
body, err := opts.Edit(editorCommand)
136+
body, err := opts.EditSurvey()
139137
if err != nil {
140138
return err
141139
}
@@ -149,7 +147,7 @@ func commentRun(opts *CommentOptions) error {
149147
}
150148

151149
if opts.Interactive {
152-
cont, err := confirmSubmitSurvey()
150+
cont, err := opts.ConfirmSubmitSurvey()
153151
if err != nil {
154152
return err
155153
}
@@ -170,22 +168,32 @@ func commentRun(opts *CommentOptions) error {
170168
return nil
171169
}
172170

173-
func inputTypeSurvey() (int, error) {
171+
var inputTypeSurvey = func() (int, error) {
174172
var inputType int
175173
inputTypeQuestion := &survey.Select{
176174
Message: "Where do you want to draft your comment?",
177175
Options: []string{"Editor", "Web"},
178176
}
179-
err := prompt.SurveyAskOne(inputTypeQuestion, &inputType)
177+
err := survey.AskOne(inputTypeQuestion, &inputType)
180178
return inputType, err
181179
}
182180

183-
func confirmSubmitSurvey() (bool, error) {
181+
var confirmSubmitSurvey = func() (bool, error) {
184182
var confirm bool
185183
submit := &survey.Confirm{
186184
Message: "Submit?",
187185
Default: true,
188186
}
189-
err := prompt.SurveyAskOne(submit, &confirm)
187+
err := survey.AskOne(submit, &confirm)
190188
return confirm, err
191189
}
190+
191+
var editSurvey = func(cf func() (config.Config, error), io *iostreams.IOStreams) func() (string, error) {
192+
return func() (string, error) {
193+
editorCommand, err := cmdutil.DetermineEditor(cf)
194+
if err != nil {
195+
return "", err
196+
}
197+
return surveyext.Edit(editorCommand, "*.md", "", io.In, io.Out, io.ErrOut, nil)
198+
}
199+
}

pkg/cmd/issue/comment/comment_test.go

Lines changed: 44 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,12 @@ package comment
33
import (
44
"bytes"
55
"net/http"
6-
"os/exec"
76
"testing"
87

9-
"github.com/cli/cli/internal/config"
108
"github.com/cli/cli/internal/ghrepo"
11-
"github.com/cli/cli/internal/run"
129
"github.com/cli/cli/pkg/cmdutil"
1310
"github.com/cli/cli/pkg/httpmock"
1411
"github.com/cli/cli/pkg/iostreams"
15-
"github.com/cli/cli/pkg/prompt"
16-
"github.com/cli/cli/test"
1712
"github.com/google/shlex"
1813
"github.com/stretchr/testify/assert"
1914
)
@@ -155,69 +150,89 @@ func TestNewCmdComment(t *testing.T) {
155150

156151
func Test_commentRun(t *testing.T) {
157152
tests := []struct {
158-
name string
159-
input *CommentOptions
160-
testInputType int
161-
stdout string
162-
stderr string
163-
wantsErr bool
164-
errMsg string
153+
name string
154+
input *CommentOptions
155+
httpStubs func(*testing.T, *httpmock.Registry)
156+
stdout string
157+
stderr string
165158
}{
166159
{
167-
name: "interactive web",
168-
testInputType: web,
160+
name: "interactive web",
169161
input: &CommentOptions{
170162
SelectorArg: "123",
171163
Interactive: true,
172164
InputType: 0,
173165
Body: "",
166+
167+
InputTypeSurvey: func() (int, error) { return web, nil },
168+
OpenInBrowser: func(string) error { return nil },
169+
},
170+
httpStubs: func(t *testing.T, reg *httpmock.Registry) {
171+
mockIssueFromNumber(t, reg)
174172
},
175173
stderr: "Opening github.com/OWNER/REPO/issues/123 in your browser.\n",
176174
},
177175
{
178-
name: "interactive editor",
179-
testInputType: editor,
176+
name: "interactive editor",
180177
input: &CommentOptions{
181178
SelectorArg: "123",
182179
Interactive: true,
183180
InputType: 0,
184181
Body: "",
185-
Edit: func(string) (string, error) { return "comment body", nil },
182+
183+
EditSurvey: func() (string, error) { return "comment body", nil },
184+
InputTypeSurvey: func() (int, error) { return editor, nil },
185+
ConfirmSubmitSurvey: func() (bool, error) { return true, nil },
186+
},
187+
httpStubs: func(t *testing.T, reg *httpmock.Registry) {
188+
mockIssueFromNumber(t, reg)
189+
mockCommentCreate(t, reg)
186190
},
187191
stdout: "? Body <Received>\nhttps://github.com/OWNER/REPO/issues/123#issuecomment-456\n",
188192
},
189193
{
190-
name: "non-interactive web",
191-
testInputType: web,
194+
name: "non-interactive web",
192195
input: &CommentOptions{
193196
SelectorArg: "123",
194197
Interactive: false,
195198
InputType: web,
196199
Body: "",
200+
201+
OpenInBrowser: func(string) error { return nil },
202+
},
203+
httpStubs: func(t *testing.T, reg *httpmock.Registry) {
204+
mockIssueFromNumber(t, reg)
197205
},
198206
stderr: "Opening github.com/OWNER/REPO/issues/123 in your browser.\n",
199207
},
200208
{
201-
name: "non-interactive editor",
202-
testInputType: editor,
209+
name: "non-interactive editor",
203210
input: &CommentOptions{
204211
SelectorArg: "123",
205212
Interactive: false,
206213
InputType: editor,
207214
Body: "",
208-
Edit: func(string) (string, error) { return "comment body", nil },
215+
216+
EditSurvey: func() (string, error) { return "comment body", nil },
217+
},
218+
httpStubs: func(t *testing.T, reg *httpmock.Registry) {
219+
mockIssueFromNumber(t, reg)
220+
mockCommentCreate(t, reg)
209221
},
210222
stdout: "https://github.com/OWNER/REPO/issues/123#issuecomment-456\n",
211223
},
212224
{
213-
name: "non-interactive inline",
214-
testInputType: inline,
225+
name: "non-interactive inline",
215226
input: &CommentOptions{
216227
SelectorArg: "123",
217228
Interactive: false,
218229
InputType: inline,
219230
Body: "comment body",
220231
},
232+
httpStubs: func(t *testing.T, reg *httpmock.Registry) {
233+
mockIssueFromNumber(t, reg)
234+
mockCommentCreate(t, reg)
235+
},
221236
stdout: "https://github.com/OWNER/REPO/issues/123#issuecomment-456\n",
222237
},
223238
}
@@ -227,57 +242,28 @@ func Test_commentRun(t *testing.T) {
227242
io.SetStdinTTY(true)
228243
io.SetStderrTTY(true)
229244

230-
client := &httpmock.Registry{}
231-
defer client.Verify(t)
232-
mockIssueFromNumber(client)
233-
if tt.testInputType != web {
234-
mockCommentCreate(t, client)
235-
}
245+
reg := &httpmock.Registry{}
246+
defer reg.Verify(t)
247+
tt.httpStubs(t, reg)
236248

237249
tt.input.IO = io
238250
tt.input.HttpClient = func() (*http.Client, error) {
239-
return &http.Client{Transport: client}, nil
240-
}
241-
tt.input.Config = func() (config.Config, error) {
242-
return config.NewBlankConfig(), nil
251+
return &http.Client{Transport: reg}, nil
243252
}
244253
tt.input.BaseRepo = func() (ghrepo.Interface, error) {
245254
return ghrepo.New("OWNER", "REPO"), nil
246255
}
247256

248-
if tt.input.Interactive {
249-
as, teardown := prompt.InitAskStubber()
250-
defer teardown()
251-
// Input type select
252-
as.StubOne(tt.testInputType)
253-
if tt.testInputType == editor {
254-
// Confirm submit
255-
as.StubOne(true)
256-
}
257-
}
258-
259-
if tt.testInputType == web {
260-
// Stub browser open
261-
restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable {
262-
return &test.OutputStub{}
263-
})
264-
defer restoreCmd()
265-
}
266-
267257
t.Run(tt.name, func(t *testing.T) {
268258
err := commentRun(tt.input)
269-
if tt.wantsErr {
270-
assert.EqualError(t, err, tt.errMsg)
271-
return
272-
}
273259
assert.NoError(t, err)
274260
assert.Equal(t, tt.stdout, stdout.String())
275261
assert.Equal(t, tt.stderr, stderr.String())
276262
})
277263
}
278264
}
279265

280-
func mockIssueFromNumber(reg *httpmock.Registry) {
266+
func mockIssueFromNumber(_ *testing.T, reg *httpmock.Registry) {
281267
reg.Register(
282268
httpmock.GraphQL(`query IssueByNumber\b`),
283269
httpmock.StringResponse(`

0 commit comments

Comments
 (0)