github.com/andrewhsu/cli/v2@v2.0.1-0.20210910131313-d4b4061f5b89/pkg/cmd/pr/status/status_test.go (about) 1 package status 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "net/http" 7 "regexp" 8 "strings" 9 "testing" 10 11 "github.com/andrewhsu/cli/v2/context" 12 "github.com/andrewhsu/cli/v2/git" 13 "github.com/andrewhsu/cli/v2/internal/config" 14 "github.com/andrewhsu/cli/v2/internal/ghrepo" 15 "github.com/andrewhsu/cli/v2/pkg/cmdutil" 16 "github.com/andrewhsu/cli/v2/pkg/httpmock" 17 "github.com/andrewhsu/cli/v2/pkg/iostreams" 18 "github.com/andrewhsu/cli/v2/test" 19 "github.com/google/shlex" 20 ) 21 22 func runCommand(rt http.RoundTripper, branch string, isTTY bool, cli string) (*test.CmdOut, error) { 23 io, _, stdout, stderr := iostreams.Test() 24 io.SetStdoutTTY(isTTY) 25 io.SetStdinTTY(isTTY) 26 io.SetStderrTTY(isTTY) 27 28 factory := &cmdutil.Factory{ 29 IOStreams: io, 30 HttpClient: func() (*http.Client, error) { 31 return &http.Client{Transport: rt}, nil 32 }, 33 Config: func() (config.Config, error) { 34 return config.NewBlankConfig(), nil 35 }, 36 BaseRepo: func() (ghrepo.Interface, error) { 37 return ghrepo.New("OWNER", "REPO"), nil 38 }, 39 Remotes: func() (context.Remotes, error) { 40 return context.Remotes{ 41 { 42 Remote: &git.Remote{Name: "origin"}, 43 Repo: ghrepo.New("OWNER", "REPO"), 44 }, 45 }, nil 46 }, 47 Branch: func() (string, error) { 48 if branch == "" { 49 return "", git.ErrNotOnAnyBranch 50 } 51 return branch, nil 52 }, 53 } 54 55 cmd := NewCmdStatus(factory, nil) 56 cmd.PersistentFlags().StringP("repo", "R", "", "") 57 58 argv, err := shlex.Split(cli) 59 if err != nil { 60 return nil, err 61 } 62 cmd.SetArgs(argv) 63 64 cmd.SetIn(&bytes.Buffer{}) 65 cmd.SetOut(ioutil.Discard) 66 cmd.SetErr(ioutil.Discard) 67 68 _, err = cmd.ExecuteC() 69 return &test.CmdOut{ 70 OutBuf: stdout, 71 ErrBuf: stderr, 72 }, err 73 } 74 75 func initFakeHTTP() *httpmock.Registry { 76 return &httpmock.Registry{} 77 } 78 79 func TestPRStatus(t *testing.T) { 80 http := initFakeHTTP() 81 defer http.Verify(t) 82 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.FileResponse("./fixtures/prStatus.json")) 83 84 output, err := runCommand(http, "blueberries", true, "") 85 if err != nil { 86 t.Errorf("error running command `pr status`: %v", err) 87 } 88 89 expectedPrs := []*regexp.Regexp{ 90 regexp.MustCompile(`#8.*\[strawberries\]`), 91 regexp.MustCompile(`#9.*\[apples\]`), 92 regexp.MustCompile(`#10.*\[blueberries\]`), 93 regexp.MustCompile(`#11.*\[figs\]`), 94 } 95 96 for _, r := range expectedPrs { 97 if !r.MatchString(output.String()) { 98 t.Errorf("output did not match regexp /%s/", r) 99 } 100 } 101 } 102 103 func TestPRStatus_reviewsAndChecks(t *testing.T) { 104 http := initFakeHTTP() 105 defer http.Verify(t) 106 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.FileResponse("./fixtures/prStatusChecks.json")) 107 108 output, err := runCommand(http, "blueberries", true, "") 109 if err != nil { 110 t.Errorf("error running command `pr status`: %v", err) 111 } 112 113 expected := []string{ 114 "✓ Checks passing + Changes requested", 115 "- Checks pending ✓ Approved", 116 "× 1/3 checks failing - Review required", 117 } 118 119 for _, line := range expected { 120 if !strings.Contains(output.String(), line) { 121 t.Errorf("output did not contain %q: %q", line, output.String()) 122 } 123 } 124 } 125 126 func TestPRStatus_currentBranch_showTheMostRecentPR(t *testing.T) { 127 http := initFakeHTTP() 128 defer http.Verify(t) 129 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.FileResponse("./fixtures/prStatusCurrentBranch.json")) 130 131 output, err := runCommand(http, "blueberries", true, "") 132 if err != nil { 133 t.Errorf("error running command `pr status`: %v", err) 134 } 135 136 expectedLine := regexp.MustCompile(`#10 Blueberries are certainly a good fruit \[blueberries\]`) 137 if !expectedLine.MatchString(output.String()) { 138 t.Errorf("output did not match regexp /%s/\n> output\n%s\n", expectedLine, output) 139 return 140 } 141 142 unexpectedLines := []*regexp.Regexp{ 143 regexp.MustCompile(`#9 Blueberries are a good fruit \[blueberries\] - Merged`), 144 regexp.MustCompile(`#8 Blueberries are probably a good fruit \[blueberries\] - Closed`), 145 } 146 for _, r := range unexpectedLines { 147 if r.MatchString(output.String()) { 148 t.Errorf("output unexpectedly match regexp /%s/\n> output\n%s\n", r, output) 149 return 150 } 151 } 152 } 153 154 func TestPRStatus_currentBranch_defaultBranch(t *testing.T) { 155 http := initFakeHTTP() 156 defer http.Verify(t) 157 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.FileResponse("./fixtures/prStatusCurrentBranch.json")) 158 159 output, err := runCommand(http, "blueberries", true, "") 160 if err != nil { 161 t.Errorf("error running command `pr status`: %v", err) 162 } 163 164 expectedLine := regexp.MustCompile(`#10 Blueberries are certainly a good fruit \[blueberries\]`) 165 if !expectedLine.MatchString(output.String()) { 166 t.Errorf("output did not match regexp /%s/\n> output\n%s\n", expectedLine, output) 167 return 168 } 169 } 170 171 func TestPRStatus_currentBranch_defaultBranch_repoFlag(t *testing.T) { 172 http := initFakeHTTP() 173 defer http.Verify(t) 174 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.FileResponse("./fixtures/prStatusCurrentBranchClosedOnDefaultBranch.json")) 175 176 output, err := runCommand(http, "blueberries", true, "-R OWNER/REPO") 177 if err != nil { 178 t.Errorf("error running command `pr status`: %v", err) 179 } 180 181 expectedLine := regexp.MustCompile(`#8 Blueberries are a good fruit \[blueberries\]`) 182 if expectedLine.MatchString(output.String()) { 183 t.Errorf("output not expected to match regexp /%s/\n> output\n%s\n", expectedLine, output) 184 return 185 } 186 } 187 188 func TestPRStatus_currentBranch_Closed(t *testing.T) { 189 http := initFakeHTTP() 190 defer http.Verify(t) 191 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.FileResponse("./fixtures/prStatusCurrentBranchClosed.json")) 192 193 output, err := runCommand(http, "blueberries", true, "") 194 if err != nil { 195 t.Errorf("error running command `pr status`: %v", err) 196 } 197 198 expectedLine := regexp.MustCompile(`#8 Blueberries are a good fruit \[blueberries\] - Closed`) 199 if !expectedLine.MatchString(output.String()) { 200 t.Errorf("output did not match regexp /%s/\n> output\n%s\n", expectedLine, output) 201 return 202 } 203 } 204 205 func TestPRStatus_currentBranch_Closed_defaultBranch(t *testing.T) { 206 http := initFakeHTTP() 207 defer http.Verify(t) 208 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.FileResponse("./fixtures/prStatusCurrentBranchClosedOnDefaultBranch.json")) 209 210 output, err := runCommand(http, "blueberries", true, "") 211 if err != nil { 212 t.Errorf("error running command `pr status`: %v", err) 213 } 214 215 expectedLine := regexp.MustCompile(`There is no pull request associated with \[blueberries\]`) 216 if !expectedLine.MatchString(output.String()) { 217 t.Errorf("output did not match regexp /%s/\n> output\n%s\n", expectedLine, output) 218 return 219 } 220 } 221 222 func TestPRStatus_currentBranch_Merged(t *testing.T) { 223 http := initFakeHTTP() 224 defer http.Verify(t) 225 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.FileResponse("./fixtures/prStatusCurrentBranchMerged.json")) 226 227 output, err := runCommand(http, "blueberries", true, "") 228 if err != nil { 229 t.Errorf("error running command `pr status`: %v", err) 230 } 231 232 expectedLine := regexp.MustCompile(`#8 Blueberries are a good fruit \[blueberries\] - Merged`) 233 if !expectedLine.MatchString(output.String()) { 234 t.Errorf("output did not match regexp /%s/\n> output\n%s\n", expectedLine, output) 235 return 236 } 237 } 238 239 func TestPRStatus_currentBranch_Merged_defaultBranch(t *testing.T) { 240 http := initFakeHTTP() 241 defer http.Verify(t) 242 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.FileResponse("./fixtures/prStatusCurrentBranchMergedOnDefaultBranch.json")) 243 244 output, err := runCommand(http, "blueberries", true, "") 245 if err != nil { 246 t.Errorf("error running command `pr status`: %v", err) 247 } 248 249 expectedLine := regexp.MustCompile(`There is no pull request associated with \[blueberries\]`) 250 if !expectedLine.MatchString(output.String()) { 251 t.Errorf("output did not match regexp /%s/\n> output\n%s\n", expectedLine, output) 252 return 253 } 254 } 255 256 func TestPRStatus_blankSlate(t *testing.T) { 257 http := initFakeHTTP() 258 defer http.Verify(t) 259 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.StringResponse(`{"data": {}}`)) 260 261 output, err := runCommand(http, "blueberries", true, "") 262 if err != nil { 263 t.Errorf("error running command `pr status`: %v", err) 264 } 265 266 expected := ` 267 Relevant pull requests in OWNER/REPO 268 269 Current branch 270 There is no pull request associated with [blueberries] 271 272 Created by you 273 You have no open pull requests 274 275 Requesting a code review from you 276 You have no pull requests to review 277 278 ` 279 if output.String() != expected { 280 t.Errorf("expected %q, got %q", expected, output.String()) 281 } 282 } 283 284 func TestPRStatus_detachedHead(t *testing.T) { 285 http := initFakeHTTP() 286 defer http.Verify(t) 287 http.Register(httpmock.GraphQL(`query PullRequestStatus\b`), httpmock.StringResponse(`{"data": {}}`)) 288 289 output, err := runCommand(http, "", true, "") 290 if err != nil { 291 t.Errorf("error running command `pr status`: %v", err) 292 } 293 294 expected := ` 295 Relevant pull requests in OWNER/REPO 296 297 Current branch 298 There is no current branch 299 300 Created by you 301 You have no open pull requests 302 303 Requesting a code review from you 304 You have no pull requests to review 305 306 ` 307 if output.String() != expected { 308 t.Errorf("expected %q, got %q", expected, output.String()) 309 } 310 }