github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/pr/ready/ready_test.go (about) 1 package ready 2 3 import ( 4 "bytes" 5 "io" 6 "net/http" 7 "testing" 8 9 "github.com/ungtb10d/cli/v2/api" 10 "github.com/ungtb10d/cli/v2/internal/ghrepo" 11 "github.com/ungtb10d/cli/v2/pkg/cmd/pr/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/test" 16 "github.com/google/shlex" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 ) 20 21 func Test_NewCmdReady(t *testing.T) { 22 tests := []struct { 23 name string 24 args string 25 isTTY bool 26 want ReadyOptions 27 wantErr string 28 }{ 29 { 30 name: "number argument", 31 args: "123", 32 isTTY: true, 33 want: ReadyOptions{ 34 SelectorArg: "123", 35 }, 36 }, 37 { 38 name: "no argument", 39 args: "", 40 isTTY: true, 41 want: ReadyOptions{ 42 SelectorArg: "", 43 }, 44 }, 45 { 46 name: "no argument with --repo override", 47 args: "-R owner/repo", 48 isTTY: true, 49 wantErr: "argument required when using the --repo flag", 50 }, 51 } 52 for _, tt := range tests { 53 t.Run(tt.name, func(t *testing.T) { 54 ios, _, _, _ := iostreams.Test() 55 ios.SetStdoutTTY(tt.isTTY) 56 ios.SetStdinTTY(tt.isTTY) 57 ios.SetStderrTTY(tt.isTTY) 58 59 f := &cmdutil.Factory{ 60 IOStreams: ios, 61 } 62 63 var opts *ReadyOptions 64 cmd := NewCmdReady(f, func(o *ReadyOptions) 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(io.Discard) 76 cmd.SetErr(io.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.SelectorArg, opts.SelectorArg) 87 }) 88 } 89 } 90 91 func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) { 92 ios, _, stdout, stderr := iostreams.Test() 93 ios.SetStdoutTTY(isTTY) 94 ios.SetStdinTTY(isTTY) 95 ios.SetStderrTTY(isTTY) 96 97 factory := &cmdutil.Factory{ 98 IOStreams: ios, 99 HttpClient: func() (*http.Client, error) { 100 return &http.Client{Transport: rt}, nil 101 }, 102 } 103 104 cmd := NewCmdReady(factory, nil) 105 106 argv, err := shlex.Split(cli) 107 if err != nil { 108 return nil, err 109 } 110 cmd.SetArgs(argv) 111 112 cmd.SetIn(&bytes.Buffer{}) 113 cmd.SetOut(io.Discard) 114 cmd.SetErr(io.Discard) 115 116 _, err = cmd.ExecuteC() 117 return &test.CmdOut{ 118 OutBuf: stdout, 119 ErrBuf: stderr, 120 }, err 121 } 122 123 func TestPRReady(t *testing.T) { 124 http := &httpmock.Registry{} 125 defer http.Verify(t) 126 127 shared.RunCommandFinder("123", &api.PullRequest{ 128 ID: "THE-ID", 129 Number: 123, 130 State: "OPEN", 131 IsDraft: true, 132 }, ghrepo.New("OWNER", "REPO")) 133 134 http.Register( 135 httpmock.GraphQL(`mutation PullRequestReadyForReview\b`), 136 httpmock.GraphQLMutation(`{"id": "THE-ID"}`, 137 func(inputs map[string]interface{}) { 138 assert.Equal(t, inputs["pullRequestId"], "THE-ID") 139 }), 140 ) 141 142 output, err := runCommand(http, true, "123") 143 assert.NoError(t, err) 144 assert.Equal(t, "", output.String()) 145 assert.Equal(t, "✓ Pull request #123 is marked as \"ready for review\"\n", output.Stderr()) 146 } 147 148 func TestPRReady_alreadyReady(t *testing.T) { 149 http := &httpmock.Registry{} 150 defer http.Verify(t) 151 152 shared.RunCommandFinder("123", &api.PullRequest{ 153 ID: "THE-ID", 154 Number: 123, 155 State: "OPEN", 156 IsDraft: false, 157 }, ghrepo.New("OWNER", "REPO")) 158 159 output, err := runCommand(http, true, "123") 160 assert.NoError(t, err) 161 assert.Equal(t, "", output.String()) 162 assert.Equal(t, "! Pull request #123 is already \"ready for review\"\n", output.Stderr()) 163 } 164 165 func TestPRReadyUndo(t *testing.T) { 166 http := &httpmock.Registry{} 167 defer http.Verify(t) 168 169 shared.RunCommandFinder("123", &api.PullRequest{ 170 ID: "THE-ID", 171 Number: 123, 172 State: "OPEN", 173 IsDraft: false, 174 }, ghrepo.New("OWNER", "REPO")) 175 176 http.Register( 177 httpmock.GraphQL(`mutation ConvertPullRequestToDraft\b`), 178 httpmock.GraphQLMutation(`{"id": "THE-ID"}`, 179 func(inputs map[string]interface{}) { 180 assert.Equal(t, inputs["pullRequestId"], "THE-ID") 181 }), 182 ) 183 184 output, err := runCommand(http, true, "123 --undo") 185 assert.NoError(t, err) 186 assert.Equal(t, "", output.String()) 187 assert.Equal(t, "✓ Pull request #123 is converted to \"draft\"\n", output.Stderr()) 188 } 189 190 func TestPRReadyUndo_alreadyDraft(t *testing.T) { 191 http := &httpmock.Registry{} 192 defer http.Verify(t) 193 194 shared.RunCommandFinder("123", &api.PullRequest{ 195 ID: "THE-ID", 196 Number: 123, 197 State: "OPEN", 198 IsDraft: true, 199 }, ghrepo.New("OWNER", "REPO")) 200 201 output, err := runCommand(http, true, "123 --undo") 202 assert.NoError(t, err) 203 assert.Equal(t, "", output.String()) 204 assert.Equal(t, "! Pull request #123 is already \"in draft\"\n", output.Stderr()) 205 } 206 207 func TestPRReady_closed(t *testing.T) { 208 http := &httpmock.Registry{} 209 defer http.Verify(t) 210 211 shared.RunCommandFinder("123", &api.PullRequest{ 212 ID: "THE-ID", 213 Number: 123, 214 State: "CLOSED", 215 IsDraft: true, 216 }, ghrepo.New("OWNER", "REPO")) 217 218 output, err := runCommand(http, true, "123") 219 assert.EqualError(t, err, "SilentError") 220 assert.Equal(t, "", output.String()) 221 assert.Equal(t, "X Pull request #123 is closed. Only draft pull requests can be marked as \"ready for review\"\n", output.Stderr()) 222 }