|
8 | 8 | "net/http" |
9 | 9 | "os" |
10 | 10 | "path/filepath" |
| 11 | + "strings" |
11 | 12 | "testing" |
12 | 13 |
|
13 | 14 | "github.com/MakeNowJust/heredoc" |
@@ -134,6 +135,156 @@ func TestNewCmdCreate(t *testing.T) { |
134 | 135 | } |
135 | 136 | } |
136 | 137 |
|
| 138 | +func Test_createRun(t *testing.T) { |
| 139 | + tests := []struct { |
| 140 | + name string |
| 141 | + opts CreateOptions |
| 142 | + httpStubs func(*httpmock.Registry) |
| 143 | + wantsStdout string |
| 144 | + wantsStderr string |
| 145 | + wantsBrowse string |
| 146 | + wantsErr string |
| 147 | + }{ |
| 148 | + { |
| 149 | + name: "no args", |
| 150 | + opts: CreateOptions{ |
| 151 | + WebMode: true, |
| 152 | + }, |
| 153 | + wantsBrowse: "https://github.com/OWNER/REPO/issues/new", |
| 154 | + wantsStderr: "Opening github.com/OWNER/REPO/issues/new in your browser.\n", |
| 155 | + }, |
| 156 | + { |
| 157 | + name: "title and body", |
| 158 | + opts: CreateOptions{ |
| 159 | + WebMode: true, |
| 160 | + Title: "myissue", |
| 161 | + Body: "hello cli", |
| 162 | + }, |
| 163 | + wantsBrowse: "https://github.com/OWNER/REPO/issues/new?body=hello+cli&title=myissue", |
| 164 | + wantsStderr: "Opening github.com/OWNER/REPO/issues/new in your browser.\n", |
| 165 | + }, |
| 166 | + { |
| 167 | + name: "assignee", |
| 168 | + opts: CreateOptions{ |
| 169 | + WebMode: true, |
| 170 | + Assignees: []string{"monalisa"}, |
| 171 | + }, |
| 172 | + wantsBrowse: "https://github.com/OWNER/REPO/issues/new?assignees=monalisa", |
| 173 | + wantsStderr: "Opening github.com/OWNER/REPO/issues/new in your browser.\n", |
| 174 | + }, |
| 175 | + { |
| 176 | + name: "@me", |
| 177 | + opts: CreateOptions{ |
| 178 | + WebMode: true, |
| 179 | + Assignees: []string{"@me"}, |
| 180 | + }, |
| 181 | + httpStubs: func(r *httpmock.Registry) { |
| 182 | + r.Register( |
| 183 | + httpmock.GraphQL(`query UserCurrent\b`), |
| 184 | + httpmock.StringResponse(` |
| 185 | + { "data": { |
| 186 | + "viewer": { "login": "MonaLisa" } |
| 187 | + } }`)) |
| 188 | + }, |
| 189 | + wantsBrowse: "https://github.com/OWNER/REPO/issues/new?assignees=MonaLisa", |
| 190 | + wantsStderr: "Opening github.com/OWNER/REPO/issues/new in your browser.\n", |
| 191 | + }, |
| 192 | + { |
| 193 | + name: "project", |
| 194 | + opts: CreateOptions{ |
| 195 | + WebMode: true, |
| 196 | + Projects: []string{"cleanup"}, |
| 197 | + }, |
| 198 | + httpStubs: func(r *httpmock.Registry) { |
| 199 | + r.Register( |
| 200 | + httpmock.GraphQL(`query RepositoryProjectList\b`), |
| 201 | + httpmock.StringResponse(` |
| 202 | + { "data": { "repository": { "projects": { |
| 203 | + "nodes": [ |
| 204 | + { "name": "Cleanup", "id": "CLEANUPID", "resourcePath": "/OWNER/REPO/projects/1" } |
| 205 | + ], |
| 206 | + "pageInfo": { "hasNextPage": false } |
| 207 | + } } } }`)) |
| 208 | + r.Register( |
| 209 | + httpmock.GraphQL(`query OrganizationProjectList\b`), |
| 210 | + httpmock.StringResponse(` |
| 211 | + { "data": { "organization": { "projects": { |
| 212 | + "nodes": [ |
| 213 | + { "name": "Triage", "id": "TRIAGEID", "resourcePath": "/orgs/ORG/projects/1" } |
| 214 | + ], |
| 215 | + "pageInfo": { "hasNextPage": false } |
| 216 | + } } } }`)) |
| 217 | + }, |
| 218 | + wantsBrowse: "https://github.com/OWNER/REPO/issues/new?projects=OWNER%2FREPO%2F1", |
| 219 | + wantsStderr: "Opening github.com/OWNER/REPO/issues/new in your browser.\n", |
| 220 | + }, |
| 221 | + { |
| 222 | + name: "has templates", |
| 223 | + opts: CreateOptions{ |
| 224 | + WebMode: true, |
| 225 | + }, |
| 226 | + httpStubs: func(r *httpmock.Registry) { |
| 227 | + r.Register( |
| 228 | + httpmock.GraphQL(`query IssueTemplates\b`), |
| 229 | + httpmock.StringResponse(` |
| 230 | + { "data": { "repository": { "issueTemplates": [ |
| 231 | + { "name": "Bug report", |
| 232 | + "body": "Does not work :((" }, |
| 233 | + { "name": "Submit a request", |
| 234 | + "body": "I have a suggestion for an enhancement" } |
| 235 | + ] } } }`), |
| 236 | + ) |
| 237 | + }, |
| 238 | + wantsBrowse: "https://github.com/OWNER/REPO/issues/new/choose", |
| 239 | + wantsStderr: "Opening github.com/OWNER/REPO/issues/new/choose in your browser.\n", |
| 240 | + }, |
| 241 | + { |
| 242 | + name: "too long body", |
| 243 | + opts: CreateOptions{ |
| 244 | + WebMode: true, |
| 245 | + Body: strings.Repeat("A", 9216), |
| 246 | + }, |
| 247 | + wantsErr: "cannot open in browser: maximum URL length exceeded", |
| 248 | + }, |
| 249 | + } |
| 250 | + for _, tt := range tests { |
| 251 | + t.Run(tt.name, func(t *testing.T) { |
| 252 | + httpReg := &httpmock.Registry{} |
| 253 | + defer httpReg.Verify(t) |
| 254 | + if tt.httpStubs != nil { |
| 255 | + tt.httpStubs(httpReg) |
| 256 | + } |
| 257 | + |
| 258 | + io, _, stdout, stderr := iostreams.Test() |
| 259 | + io.SetStdoutTTY(true) |
| 260 | + opts := &tt.opts |
| 261 | + opts.IO = io |
| 262 | + opts.HttpClient = func() (*http.Client, error) { |
| 263 | + return &http.Client{Transport: httpReg}, nil |
| 264 | + } |
| 265 | + opts.BaseRepo = func() (ghrepo.Interface, error) { |
| 266 | + return ghrepo.New("OWNER", "REPO"), nil |
| 267 | + } |
| 268 | + browser := &cmdutil.TestBrowser{} |
| 269 | + opts.Browser = browser |
| 270 | + |
| 271 | + err := createRun(opts) |
| 272 | + if tt.wantsErr == "" { |
| 273 | + require.NoError(t, err) |
| 274 | + } else { |
| 275 | + assert.EqualError(t, err, tt.wantsErr) |
| 276 | + return |
| 277 | + } |
| 278 | + |
| 279 | + assert.Equal(t, tt.wantsStdout, stdout.String()) |
| 280 | + assert.Equal(t, tt.wantsStderr, stderr.String()) |
| 281 | + browser.Verify(t, tt.wantsBrowse) |
| 282 | + }) |
| 283 | + } |
| 284 | +} |
| 285 | + |
| 286 | +/*** LEGACY TESTS ***/ |
| 287 | + |
137 | 288 | func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) { |
138 | 289 | return runCommandWithRootDirOverridden(rt, isTTY, cli, "") |
139 | 290 | } |
@@ -506,84 +657,6 @@ func TestIssueCreate_disabledIssues(t *testing.T) { |
506 | 657 | } |
507 | 658 | } |
508 | 659 |
|
509 | | -func TestIssueCreate_web(t *testing.T) { |
510 | | - http := &httpmock.Registry{} |
511 | | - defer http.Verify(t) |
512 | | - |
513 | | - http.Register( |
514 | | - httpmock.GraphQL(`query UserCurrent\b`), |
515 | | - httpmock.StringResponse(` |
516 | | - { "data": { |
517 | | - "viewer": { "login": "MonaLisa" } |
518 | | - } } |
519 | | - `), |
520 | | - ) |
521 | | - |
522 | | - _, cmdTeardown := run.Stub() |
523 | | - defer cmdTeardown(t) |
524 | | - |
525 | | - output, err := runCommand(http, true, `--web -a @me`) |
526 | | - if err != nil { |
527 | | - t.Errorf("error running command `issue create`: %v", err) |
528 | | - } |
529 | | - |
530 | | - assert.Equal(t, "", output.String()) |
531 | | - assert.Equal(t, "Opening github.com/OWNER/REPO/issues/new in your browser.\n", output.Stderr()) |
532 | | - assert.Equal(t, "https://github.com/OWNER/REPO/issues/new?assignees=MonaLisa", output.BrowsedURL) |
533 | | -} |
534 | | - |
535 | | -func TestIssueCreate_webLongURL(t *testing.T) { |
536 | | - longBodyFile := filepath.Join(t.TempDir(), "long-body.txt") |
537 | | - err := ioutil.WriteFile(longBodyFile, make([]byte, 9216), 0600) |
538 | | - require.NoError(t, err) |
539 | | - |
540 | | - _, err = runCommand(nil, true, fmt.Sprintf("-F '%s' --web", longBodyFile)) |
541 | | - require.EqualError(t, err, "cannot open in browser: maximum URL length exceeded") |
542 | | -} |
543 | | - |
544 | | -func TestIssueCreate_webTitleBody(t *testing.T) { |
545 | | - http := &httpmock.Registry{} |
546 | | - defer http.Verify(t) |
547 | | - |
548 | | - _, cmdTeardown := run.Stub() |
549 | | - defer cmdTeardown(t) |
550 | | - |
551 | | - output, err := runCommand(http, true, `-w -t mytitle -b mybody`) |
552 | | - if err != nil { |
553 | | - t.Errorf("error running command `issue create`: %v", err) |
554 | | - } |
555 | | - |
556 | | - assert.Equal(t, "", output.String()) |
557 | | - assert.Equal(t, "Opening github.com/OWNER/REPO/issues/new in your browser.\n", output.Stderr()) |
558 | | - assert.Equal(t, "https://github.com/OWNER/REPO/issues/new?body=mybody&title=mytitle", output.BrowsedURL) |
559 | | -} |
560 | | - |
561 | | -func TestIssueCreate_webTitleBodyAtMeAssignee(t *testing.T) { |
562 | | - http := &httpmock.Registry{} |
563 | | - defer http.Verify(t) |
564 | | - |
565 | | - http.Register( |
566 | | - httpmock.GraphQL(`query UserCurrent\b`), |
567 | | - httpmock.StringResponse(` |
568 | | - { "data": { |
569 | | - "viewer": { "login": "MonaLisa" } |
570 | | - } } |
571 | | - `), |
572 | | - ) |
573 | | - |
574 | | - _, cmdTeardown := run.Stub() |
575 | | - defer cmdTeardown(t) |
576 | | - |
577 | | - output, err := runCommand(http, true, `-w -t mytitle -b mybody -a @me`) |
578 | | - if err != nil { |
579 | | - t.Errorf("error running command `issue create`: %v", err) |
580 | | - } |
581 | | - |
582 | | - assert.Equal(t, "", output.String()) |
583 | | - assert.Equal(t, "Opening github.com/OWNER/REPO/issues/new in your browser.\n", output.Stderr()) |
584 | | - assert.Equal(t, "https://github.com/OWNER/REPO/issues/new?assignees=MonaLisa&body=mybody&title=mytitle", output.BrowsedURL) |
585 | | -} |
586 | | - |
587 | 660 | func TestIssueCreate_AtMeAssignee(t *testing.T) { |
588 | 661 | http := &httpmock.Registry{} |
589 | 662 | defer http.Verify(t) |
@@ -636,41 +709,3 @@ func TestIssueCreate_AtMeAssignee(t *testing.T) { |
636 | 709 |
|
637 | 710 | assert.Equal(t, "https://github.com/OWNER/REPO/issues/12\n", output.String()) |
638 | 711 | } |
639 | | - |
640 | | -func TestIssueCreate_webProject(t *testing.T) { |
641 | | - http := &httpmock.Registry{} |
642 | | - defer http.Verify(t) |
643 | | - |
644 | | - http.Register( |
645 | | - httpmock.GraphQL(`query RepositoryProjectList\b`), |
646 | | - httpmock.StringResponse(` |
647 | | - { "data": { "repository": { "projects": { |
648 | | - "nodes": [ |
649 | | - { "name": "Cleanup", "id": "CLEANUPID", "resourcePath": "/OWNER/REPO/projects/1" } |
650 | | - ], |
651 | | - "pageInfo": { "hasNextPage": false } |
652 | | - } } } } |
653 | | - `)) |
654 | | - http.Register( |
655 | | - httpmock.GraphQL(`query OrganizationProjectList\b`), |
656 | | - httpmock.StringResponse(` |
657 | | - { "data": { "organization": { "projects": { |
658 | | - "nodes": [ |
659 | | - { "name": "Triage", "id": "TRIAGEID", "resourcePath": "/orgs/ORG/projects/1" } |
660 | | - ], |
661 | | - "pageInfo": { "hasNextPage": false } |
662 | | - } } } } |
663 | | - `)) |
664 | | - |
665 | | - _, cmdTeardown := run.Stub() |
666 | | - defer cmdTeardown(t) |
667 | | - |
668 | | - output, err := runCommand(http, true, `-w -t Title -p Cleanup`) |
669 | | - if err != nil { |
670 | | - t.Errorf("error running command `issue create`: %v", err) |
671 | | - } |
672 | | - |
673 | | - assert.Equal(t, "", output.String()) |
674 | | - assert.Equal(t, "Opening github.com/OWNER/REPO/issues/new in your browser.\n", output.Stderr()) |
675 | | - assert.Equal(t, "https://github.com/OWNER/REPO/issues/new?projects=OWNER%2FREPO%2F1&title=Title", output.BrowsedURL) |
676 | | -} |
|
0 commit comments