diff --git a/api/client_test.go b/api/client_test.go index 35a45af8c..4c272aa58 100644 --- a/api/client_test.go +++ b/api/client_test.go @@ -32,7 +32,11 @@ func TestGraphQL(t *testing.T) { } }{} - http.StubResponse(200, bytes.NewBufferString(`{"data":{"viewer":{"login":"hubot"}}}`)) + http.Register( + httpmock.GraphQL("QUERY"), + httpmock.StringResponse(`{"data":{"viewer":{"login":"hubot"}}}`), + ) + err := client.GraphQL("github.com", "QUERY", vars, &response) eq(t, err, nil) eq(t, response.Viewer.Login, "hubot") @@ -48,12 +52,17 @@ func TestGraphQLError(t *testing.T) { client := NewClient(ReplaceTripper(http)) response := struct{}{} - http.StubResponse(200, bytes.NewBufferString(` - { "errors": [ - {"message":"OH NO"}, - {"message":"this is fine"} - ] - }`)) + + http.Register( + httpmock.GraphQL(""), + httpmock.StringResponse(` + { "errors": [ + {"message":"OH NO"}, + {"message":"this is fine"} + ] + } + `), + ) err := client.GraphQL("github.com", "", nil, &response) if err == nil || err.Error() != "GraphQL error: OH NO\nthis is fine" { @@ -68,7 +77,10 @@ func TestRESTGetDelete(t *testing.T) { ReplaceTripper(http), ) - http.StubResponse(204, bytes.NewBuffer([]byte{})) + http.Register( + httpmock.REST("DELETE", "applications/CLIENTID/grant"), + httpmock.StatusStringResponse(204, "{}"), + ) r := bytes.NewReader([]byte(`{}`)) err := client.REST("github.com", "DELETE", "applications/CLIENTID/grant", r, nil) diff --git a/api/queries_issue_test.go b/api/queries_issue_test.go index 83dee55b7..e6aca1907 100644 --- a/api/queries_issue_test.go +++ b/api/queries_issue_test.go @@ -1,7 +1,6 @@ package api import ( - "bytes" "encoding/json" "io/ioutil" "testing" @@ -16,30 +15,36 @@ func TestIssueList(t *testing.T) { http := &httpmock.Registry{} client := NewClient(ReplaceTripper(http)) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": true, - "issues": { - "nodes": [], - "pageInfo": { - "hasNextPage": true, - "endCursor": "ENDCURSOR" - } - } - } } } - `)) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": true, - "issues": { - "nodes": [], - "pageInfo": { - "hasNextPage": false, - "endCursor": "ENDCURSOR" - } - } - } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueList\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": true, + "issues": { + "nodes": [], + "pageInfo": { + "hasNextPage": true, + "endCursor": "ENDCURSOR" + } + } + } } } + `), + ) + http.Register( + httpmock.GraphQL(`query IssueList\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": true, + "issues": { + "nodes": [], + "pageInfo": { + "hasNextPage": false, + "endCursor": "ENDCURSOR" + } + } + } } } + `), + ) repo, _ := ghrepo.FromFullName("OWNER/REPO") _, err := IssueList(client, repo, "open", []string{}, "", 251, "", "", "") @@ -75,44 +80,51 @@ func TestIssueList_pagination(t *testing.T) { http := &httpmock.Registry{} client := NewClient(ReplaceTripper(http)) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": true, - "issues": { - "nodes": [ - { - "title": "issue1", - "labels": { "nodes": [ { "name": "bug" } ], "totalCount": 1 }, - "assignees": { "nodes": [ { "login": "user1" } ], "totalCount": 1 } + http.Register( + httpmock.GraphQL(`query IssueList\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": true, + "issues": { + "nodes": [ + { + "title": "issue1", + "labels": { "nodes": [ { "name": "bug" } ], "totalCount": 1 }, + "assignees": { "nodes": [ { "login": "user1" } ], "totalCount": 1 } + } + ], + "pageInfo": { + "hasNextPage": true, + "endCursor": "ENDCURSOR" + }, + "totalCount": 2 } - ], - "pageInfo": { - "hasNextPage": true, - "endCursor": "ENDCURSOR" - }, - "totalCount": 2 - } - } } } - `)) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": true, - "issues": { - "nodes": [ - { - "title": "issue2", - "labels": { "nodes": [ { "name": "enhancement" } ], "totalCount": 1 }, - "assignees": { "nodes": [ { "login": "user2" } ], "totalCount": 1 } + } } } + `), + ) + + http.Register( + httpmock.GraphQL(`query IssueList\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": true, + "issues": { + "nodes": [ + { + "title": "issue2", + "labels": { "nodes": [ { "name": "enhancement" } ], "totalCount": 1 }, + "assignees": { "nodes": [ { "login": "user2" } ], "totalCount": 1 } + } + ], + "pageInfo": { + "hasNextPage": false, + "endCursor": "ENDCURSOR" + }, + "totalCount": 2 } - ], - "pageInfo": { - "hasNextPage": false, - "endCursor": "ENDCURSOR" - }, - "totalCount": 2 - } - } } } - `)) + } } } + `), + ) repo := ghrepo.New("OWNER", "REPO") res, err := IssueList(client, repo, "", nil, "", 0, "", "", "") diff --git a/internal/update/update_test.go b/internal/update/update_test.go index 2fcb2d6ab..024122983 100644 --- a/internal/update/update_test.go +++ b/internal/update/update_test.go @@ -1,7 +1,6 @@ package update import ( - "bytes" "fmt" "io/ioutil" "log" @@ -54,10 +53,14 @@ func TestCheckForUpdate(t *testing.T) { t.Run(s.Name, func(t *testing.T) { http := &httpmock.Registry{} client := api.NewClient(api.ReplaceTripper(http)) - http.StubResponse(200, bytes.NewBufferString(fmt.Sprintf(`{ - "tag_name": "%s", - "html_url": "%s" - }`, s.LatestVersion, s.LatestURL))) + + http.Register( + httpmock.REST("GET", "repos/OWNER/REPO/releases/latest"), + httpmock.StringResponse(fmt.Sprintf(`{ + "tag_name": "%s", + "html_url": "%s" + }`, s.LatestVersion, s.LatestURL)), + ) rel, err := CheckForUpdate(client, tempFilePath(), "OWNER/REPO", s.CurrentVersion) if err != nil { diff --git a/pkg/cmd/gist/delete/delete_test.go b/pkg/cmd/gist/delete/delete_test.go index 682a92d50..21480803c 100644 --- a/pkg/cmd/gist/delete/delete_test.go +++ b/pkg/cmd/gist/delete/delete_test.go @@ -2,6 +2,9 @@ package delete import ( "bytes" + "net/http" + "testing" + "github.com/cli/cli/pkg/cmd/gist/shared" "github.com/cli/cli/pkg/cmdutil" "github.com/cli/cli/pkg/httpmock" @@ -9,8 +12,6 @@ import ( "github.com/cli/cli/pkg/prompt" "github.com/google/shlex" "github.com/stretchr/testify/assert" - "net/http" - "testing" ) func TestNewCmdDelete(t *testing.T) { @@ -98,7 +99,7 @@ func Test_deleteRun(t *testing.T) { }, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("DELETE", "gists/1234"), - httpmock.StatusStringResponse(200, "{}")) + httpmock.StringResponse("{}")) }, wantErr: false, }, diff --git a/pkg/cmd/issue/close/close_test.go b/pkg/cmd/issue/close/close_test.go index eadf7f440..5a2054309 100644 --- a/pkg/cmd/issue/close/close_test.go +++ b/pkg/cmd/issue/close/close_test.go @@ -14,6 +14,7 @@ import ( "github.com/cli/cli/pkg/iostreams" "github.com/cli/cli/test" "github.com/google/shlex" + "github.com/stretchr/testify/assert" ) func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) { @@ -58,14 +59,21 @@ func TestIssueClose(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": true, - "issue": { "number": 13, "title": "The title of the issue"} - } } } - `)) - - http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": true, + "issue": { "id": "THE-ID", "number": 13, "title": "The title of the issue"} + } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation IssueClose\b`), + httpmock.GraphQLMutation(`{"id": "THE-ID"}`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["issueId"], "THE-ID") + }), + ) output, err := runCommand(http, true, "13") if err != nil { @@ -83,12 +91,14 @@ func TestIssueClose_alreadyClosed(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": true, - "issue": { "number": 13, "title": "The title of the issue", "closed": true} - } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": true, + "issue": { "number": 13, "title": "The title of the issue", "closed": true} + } } }`), + ) output, err := runCommand(http, true, "13") if err != nil { @@ -106,11 +116,13 @@ func TestIssueClose_issuesDisabled(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": false - } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": false + } } }`), + ) _, err := runCommand(http, true, "13") if err == nil || err.Error() != "the 'OWNER/REPO' repository has disabled issues" { diff --git a/pkg/cmd/issue/create/create_test.go b/pkg/cmd/issue/create/create_test.go index d7e6b4ec0..21177164a 100644 --- a/pkg/cmd/issue/create/create_test.go +++ b/pkg/cmd/issue/create/create_test.go @@ -94,39 +94,32 @@ func TestIssueCreate(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "id": "REPOID", - "hasIssuesEnabled": true - } } } - `)) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "createIssue": { "issue": { - "URL": "https://github.com/OWNER/REPO/issues/12" - } } } } - `)) + http.Register( + httpmock.GraphQL(`query RepositoryInfo\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "id": "REPOID", + "hasIssuesEnabled": true + } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation IssueCreate\b`), + httpmock.GraphQLMutation(` + { "data": { "createIssue": { "issue": { + "URL": "https://github.com/OWNER/REPO/issues/12" + } } } }`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["repositoryId"], "REPOID") + assert.Equal(t, inputs["title"], "hello") + assert.Equal(t, inputs["body"], "cash rules everything around me") + }), + ) output, err := runCommand(http, true, `-t hello -b "cash rules everything around me"`) if err != nil { t.Errorf("error running command `issue create`: %v", err) } - bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body) - reqBody := struct { - Variables struct { - Input struct { - RepositoryID string - Title string - Body string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - eq(t, reqBody.Variables.Input.RepositoryID, "REPOID") - eq(t, reqBody.Variables.Input.Title, "hello") - eq(t, reqBody.Variables.Input.Body, "cash rules everything around me") - eq(t, output.String(), "https://github.com/OWNER/REPO/issues/12\n") } @@ -134,12 +127,13 @@ func TestIssueCreate_recover(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "id": "REPOID", - "hasIssuesEnabled": true - } } } - `)) + http.Register( + httpmock.GraphQL(`query RepositoryInfo\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "id": "REPOID", + "hasIssuesEnabled": true + } } }`)) http.Register( httpmock.GraphQL(`query RepositoryResolveMetadataIDs\b`), httpmock.StringResponse(` @@ -214,17 +208,26 @@ func TestIssueCreate_nonLegacyTemplate(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "id": "REPOID", - "hasIssuesEnabled": true - } } } - `)) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "createIssue": { "issue": { - "URL": "https://github.com/OWNER/REPO/issues/12" - } } } } - `)) + http.Register( + httpmock.GraphQL(`query RepositoryInfo\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "id": "REPOID", + "hasIssuesEnabled": true + } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation IssueCreate\b`), + httpmock.GraphQLMutation(` + { "data": { "createIssue": { "issue": { + "URL": "https://github.com/OWNER/REPO/issues/12" + } } } }`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["repositoryId"], "REPOID") + assert.Equal(t, inputs["title"], "hello") + assert.Equal(t, inputs["body"], "I have a suggestion for an enhancement") + }), + ) as, teardown := prompt.InitAskStubber() defer teardown() @@ -256,22 +259,6 @@ func TestIssueCreate_nonLegacyTemplate(t *testing.T) { t.Errorf("error running command `issue create`: %v", err) } - bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body) - reqBody := struct { - Variables struct { - Input struct { - RepositoryID string - Title string - Body string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - eq(t, reqBody.Variables.Input.RepositoryID, "REPOID") - eq(t, reqBody.Variables.Input.Title, "hello") - eq(t, reqBody.Variables.Input.Body, "I have a suggestion for an enhancement") - eq(t, output.String(), "https://github.com/OWNER/REPO/issues/12\n") } @@ -279,12 +266,14 @@ func TestIssueCreate_continueInBrowser(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "id": "REPOID", - "hasIssuesEnabled": true - } } } - `)) + http.Register( + httpmock.GraphQL(`query RepositoryInfo\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "id": "REPOID", + "hasIssuesEnabled": true + } } }`), + ) as, teardown := prompt.InitAskStubber() defer teardown() @@ -413,12 +402,14 @@ func TestIssueCreate_disabledIssues(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "id": "REPOID", - "hasIssuesEnabled": false - } } } - `)) + http.Register( + httpmock.GraphQL(`query RepositoryInfo\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "id": "REPOID", + "hasIssuesEnabled": false + } } }`), + ) _, err := runCommand(http, true, `-t heres -b johnny`) if err == nil || err.Error() != "the 'OWNER/REPO' repository has disabled issues" { diff --git a/pkg/cmd/issue/list/list_test.go b/pkg/cmd/issue/list/list_test.go index ff202b6f3..456741a91 100644 --- a/pkg/cmd/issue/list/list_test.go +++ b/pkg/cmd/issue/list/list_test.go @@ -169,12 +169,14 @@ func TestIssueList_nullAssigneeLabels(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": true, - "issues": { "nodes": [] } - } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueList\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": true, + "issues": { "nodes": [] } + } } }`), + ) _, err := runCommand(http, true, "") if err != nil { @@ -197,11 +199,13 @@ func TestIssueList_disabledIssues(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": false - } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueList\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": false + } } }`), + ) _, err := runCommand(http, true, "") if err == nil || err.Error() != "the 'OWNER/REPO' repository has disabled issues" { diff --git a/pkg/cmd/issue/reopen/reopen_test.go b/pkg/cmd/issue/reopen/reopen_test.go index df8e8ecd7..bce4bc882 100644 --- a/pkg/cmd/issue/reopen/reopen_test.go +++ b/pkg/cmd/issue/reopen/reopen_test.go @@ -14,6 +14,7 @@ import ( "github.com/cli/cli/pkg/iostreams" "github.com/cli/cli/test" "github.com/google/shlex" + "github.com/stretchr/testify/assert" ) func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) { @@ -58,14 +59,21 @@ func TestIssueReopen(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": true, - "issue": { "number": 2, "closed": true, "title": "The title of the issue"} - } } } - `)) - - http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": true, + "issue": { "id": "THE-ID", "number": 2, "closed": true, "title": "The title of the issue"} + } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation IssueReopen\b`), + httpmock.GraphQLMutation(`{"id": "THE-ID"}`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["issueId"], "THE-ID") + }), + ) output, err := runCommand(http, true, "2") if err != nil { @@ -83,12 +91,14 @@ func TestIssueReopen_alreadyOpen(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": true, - "issue": { "number": 2, "closed": false, "title": "The title of the issue"} - } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": true, + "issue": { "number": 2, "closed": false, "title": "The title of the issue"} + } } }`), + ) output, err := runCommand(http, true, "2") if err != nil { @@ -106,11 +116,13 @@ func TestIssueReopen_issuesDisabled(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "hasIssuesEnabled": false - } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "hasIssuesEnabled": false + } } }`), + ) _, err := runCommand(http, true, "2") if err == nil || err.Error() != "the 'OWNER/REPO' repository has disabled issues" { diff --git a/pkg/cmd/issue/view/view_test.go b/pkg/cmd/issue/view/view_test.go index 2b94c5a70..82890eac9 100644 --- a/pkg/cmd/issue/view/view_test.go +++ b/pkg/cmd/issue/view/view_test.go @@ -63,12 +63,15 @@ func TestIssueView_web(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "hasIssuesEnabled": true, "issue": { - "number": 123, - "url": "https://github.com/OWNER/REPO/issues/123" - } } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { "hasIssuesEnabled": true, "issue": { + "number": 123, + "url": "https://github.com/OWNER/REPO/issues/123" + } } } } + `), + ) var seenCmd *exec.Cmd restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable { @@ -96,12 +99,15 @@ func TestIssueView_web_numberArgWithHash(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "hasIssuesEnabled": true, "issue": { - "number": 123, - "url": "https://github.com/OWNER/REPO/issues/123" - } } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { "hasIssuesEnabled": true, "issue": { + "number": 123, + "url": "https://github.com/OWNER/REPO/issues/123" + } } } } + `), + ) var seenCmd *exec.Cmd restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable { @@ -265,11 +271,14 @@ func TestIssueView_web_notFound(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "errors": [ - { "message": "Could not resolve to an Issue with the number of 9999." } - ] } - `)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "errors": [ + { "message": "Could not resolve to an Issue with the number of 9999." } + ] } + `), + ) var seenCmd *exec.Cmd restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable { @@ -292,12 +301,15 @@ func TestIssueView_disabledIssues(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "id": "REPOID", - "hasIssuesEnabled": false - } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "id": "REPOID", + "hasIssuesEnabled": false + } } } + `), + ) _, err := runCommand(http, true, `6666`) if err == nil || err.Error() != "the 'OWNER/REPO' repository has disabled issues" { @@ -309,12 +321,15 @@ func TestIssueView_web_urlArg(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "hasIssuesEnabled": true, "issue": { - "number": 123, - "url": "https://github.com/OWNER/REPO/issues/123" - } } } } - `)) + http.Register( + httpmock.GraphQL(`query IssueByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { "hasIssuesEnabled": true, "issue": { + "number": 123, + "url": "https://github.com/OWNER/REPO/issues/123" + } } } } + `), + ) var seenCmd *exec.Cmd restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable { diff --git a/pkg/cmd/pr/checks/checks_test.go b/pkg/cmd/pr/checks/checks_test.go index 4e31eade6..64565a963 100644 --- a/pkg/cmd/pr/checks/checks_test.go +++ b/pkg/cmd/pr/checks/checks_test.go @@ -88,11 +88,13 @@ func Test_checksRun(t *testing.T) { { name: "no checks", stubs: func(reg *httpmock.Registry) { - reg.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 123, "commits": { "nodes": [{"commit": {"oid": "abc"}}]}, "baseRefName": "master" } - } } } - `)) + reg.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "number": 123, "commits": { "nodes": [{"commit": {"oid": "abc"}}]}, "baseRefName": "master" } + } } } + `)) }, wantOut: "", wantErr: "no checks reported on the 'master' branch", @@ -125,10 +127,12 @@ func Test_checksRun(t *testing.T) { name: "no checks", nontty: true, stubs: func(reg *httpmock.Registry) { - reg.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 123, "commits": { "nodes": [{"commit": {"oid": "abc"}}]}, "baseRefName": "master" } - } } } + reg.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "number": 123, "commits": { "nodes": [{"commit": {"oid": "abc"}}]}, "baseRefName": "master" } + } } } `)) }, wantOut: "", diff --git a/pkg/cmd/pr/close/close_test.go b/pkg/cmd/pr/close/close_test.go index 136554b4f..3154b4e4b 100644 --- a/pkg/cmd/pr/close/close_test.go +++ b/pkg/cmd/pr/close/close_test.go @@ -14,6 +14,7 @@ import ( "github.com/cli/cli/pkg/iostreams" "github.com/cli/cli/test" "github.com/google/shlex" + "github.com/stretchr/testify/assert" ) func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) { @@ -61,13 +62,20 @@ func TestPrClose(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 96, "title": "The title of the PR" } - } } } - `)) - - http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "id": "THE-ID", "number": 96, "title": "The title of the PR" } + } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestClose\b`), + httpmock.GraphQLMutation(`{"id": "THE-ID"}`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["pullRequestId"], "THE-ID") + }), + ) output, err := runCommand(http, true, "96") if err != nil { @@ -85,11 +93,13 @@ func TestPrClose_alreadyClosed(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 101, "title": "The title of the PR", "closed": true } - } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "number": 101, "title": "The title of the PR", "closed": true } + } } }`), + ) output, err := runCommand(http, true, "101") if err != nil { @@ -106,12 +116,21 @@ func TestPrClose_alreadyClosed(t *testing.T) { func TestPrClose_deleteBranch(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 96, "title": "The title of the PR", "headRefName":"blueberries", "headRepositoryOwner": {"login": "OWNER"}} - } } } - `)) - http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "id": "THE-ID", "number": 96, "title": "The title of the PR", "headRefName":"blueberries", "headRepositoryOwner": {"login": "OWNER"}} + } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestClose\b`), + httpmock.GraphQLMutation(`{"id": "THE-ID"}`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["pullRequestId"], "THE-ID") + }), + ) http.Register( httpmock.REST("DELETE", "repos/OWNER/REPO/git/refs/heads/blueberries"), httpmock.StringResponse(`{}`)) diff --git a/pkg/cmd/pr/create/create_test.go b/pkg/cmd/pr/create/create_test.go index 171207ea8..63963aa77 100644 --- a/pkg/cmd/pr/create/create_test.go +++ b/pkg/cmd/pr/create/create_test.go @@ -233,15 +233,26 @@ func TestPRCreate_nontty(t *testing.T) { defer http.Verify(t) http.StubRepoInfoResponse("OWNER", "REPO", "master") - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes" : [ - ] } } } } - `)) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "createPullRequest": { "pullRequest": { - "URL": "https://github.com/OWNER/REPO/pull/12" - } } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes" : [ + ] } } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestCreate\b`), + httpmock.GraphQLMutation(` + { "data": { "createPullRequest": { "pullRequest": { + "URL": "https://github.com/OWNER/REPO/pull/12" + } } } }`, + func(input map[string]interface{}) { + assert.Equal(t, "REPOID", input["repositoryId"]) + assert.Equal(t, "my title", input["title"]) + assert.Equal(t, "my body", input["body"]) + assert.Equal(t, "master", input["baseRefName"]) + assert.Equal(t, "feature", input["headRefName"]) + }), + ) cs, cmdTeardown := test.InitCmdStubber() defer cmdTeardown() @@ -252,26 +263,6 @@ func TestPRCreate_nontty(t *testing.T) { output, err := runCommand(http, nil, "feature", false, `-t "my title" -b "my body" -H feature`) require.NoError(t, err) - bodyBytes, _ := ioutil.ReadAll(http.Requests[2].Body) - reqBody := struct { - Variables struct { - Input struct { - RepositoryID string - Title string - Body string - BaseRefName string - HeadRefName string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - assert.Equal(t, "REPOID", reqBody.Variables.Input.RepositoryID) - assert.Equal(t, "my title", reqBody.Variables.Input.Title) - assert.Equal(t, "my body", reqBody.Variables.Input.Body) - assert.Equal(t, "master", reqBody.Variables.Input.BaseRefName) - assert.Equal(t, "feature", reqBody.Variables.Input.HeadRefName) - assert.Equal(t, "", output.Stderr()) assert.Equal(t, "https://github.com/OWNER/REPO/pull/12\n", output.String()) } @@ -661,13 +652,15 @@ func TestPRCreate_alreadyExists(t *testing.T) { defer http.Verify(t) http.StubRepoInfoResponse("OWNER", "REPO", "master") - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "url": "https://github.com/OWNER/REPO/pull/123", - "headRefName": "feature", - "baseRefName": "master" } - ] } } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "url": "https://github.com/OWNER/REPO/pull/123", + "headRefName": "feature", + "baseRefName": "master" } + ] } } } }`), + ) cs, cmdTeardown := test.InitCmdStubber() defer cmdTeardown() diff --git a/pkg/cmd/pr/diff/diff_test.go b/pkg/cmd/pr/diff/diff_test.go index 3e0b23adc..6b6af4eaa 100644 --- a/pkg/cmd/pr/diff/diff_test.go +++ b/pkg/cmd/pr/diff/diff_test.go @@ -164,9 +164,15 @@ func runCommand(rt http.RoundTripper, remotes context.Remotes, isTTY bool, cli s func TestPRDiff_no_current_pr(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [] } } } } - `)) + + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequests": { "nodes": [] } + } } }`), + ) + _, err := runCommand(http, nil, false, "") if err == nil { t.Fatal("expected error") @@ -177,12 +183,19 @@ func TestPRDiff_no_current_pr(t *testing.T) { func TestPRDiff_argument_not_found(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 123 } - } } } -`)) - http.StubResponse(404, bytes.NewBufferString("")) + + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "number": 123 } + } } }`), + ) + http.Register( + httpmock.REST("GET", "repos/OWNER/REPO/pulls/123"), + httpmock.StatusStringResponse(404, ""), + ) + _, err := runCommand(http, nil, false, "123") if err == nil { t.Fatal("expected error", err) @@ -193,15 +206,23 @@ func TestPRDiff_argument_not_found(t *testing.T) { func TestPRDiff_notty(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "url": "https://github.com/OWNER/REPO/pull/123", - "number": 123, - "id": "foobar123", - "headRefName": "feature", - "baseRefName": "master" } - ] } } } }`)) - http.StubResponse(200, bytes.NewBufferString(testDiff)) + + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "url": "https://github.com/OWNER/REPO/pull/123", + "number": 123, + "id": "foobar123", + "headRefName": "feature", + "baseRefName": "master" } + ] } } } }`), + ) + http.Register( + httpmock.REST("GET", "repos/OWNER/REPO/pulls/123"), + httpmock.StringResponse(testDiff), + ) + output, err := runCommand(http, nil, false, "") if err != nil { t.Fatalf("unexpected error: %s", err) @@ -214,15 +235,23 @@ func TestPRDiff_notty(t *testing.T) { func TestPRDiff_tty(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "url": "https://github.com/OWNER/REPO/pull/123", - "number": 123, - "id": "foobar123", - "headRefName": "feature", - "baseRefName": "master" } - ] } } } }`)) - http.StubResponse(200, bytes.NewBufferString(testDiff)) + + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "url": "https://github.com/OWNER/REPO/pull/123", + "number": 123, + "id": "foobar123", + "headRefName": "feature", + "baseRefName": "master" } + ] } } } }`), + ) + http.Register( + httpmock.REST("GET", "repos/OWNER/REPO/pulls/123"), + httpmock.StringResponse(testDiff), + ) + output, err := runCommand(http, nil, true, "") if err != nil { t.Fatalf("unexpected error: %s", err) diff --git a/pkg/cmd/pr/ready/ready_test.go b/pkg/cmd/pr/ready/ready_test.go index 4dc5d9eee..caf2c7e5f 100644 --- a/pkg/cmd/pr/ready/ready_test.go +++ b/pkg/cmd/pr/ready/ready_test.go @@ -143,12 +143,20 @@ func TestPRReady(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 444, "closed": false, "isDraft": true} - } } } - `)) - http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "id": "THE-ID", "number": 444, "closed": false, "isDraft": true} + } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestReadyForReview\b`), + httpmock.GraphQLMutation(`{"id": "THE-ID"}`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["pullRequestId"], "THE-ID") + }), + ) output, err := runCommand(http, true, "444") if err != nil { @@ -166,11 +174,13 @@ func TestPRReady_alreadyReady(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 445, "closed": false, "isDraft": false} - } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "number": 445, "closed": false, "isDraft": false} + } } }`), + ) output, err := runCommand(http, true, "445") if err != nil { @@ -188,11 +198,13 @@ func TestPRReady_closed(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 446, "closed": true, "isDraft": true} - } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "number": 446, "closed": true, "isDraft": true} + } } }`), + ) output, err := runCommand(http, true, "446") if err == nil { diff --git a/pkg/cmd/pr/reopen/reopen_test.go b/pkg/cmd/pr/reopen/reopen_test.go index 24dfa488f..19c4a1e6a 100644 --- a/pkg/cmd/pr/reopen/reopen_test.go +++ b/pkg/cmd/pr/reopen/reopen_test.go @@ -14,6 +14,7 @@ import ( "github.com/cli/cli/pkg/iostreams" "github.com/cli/cli/test" "github.com/google/shlex" + "github.com/stretchr/testify/assert" ) func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) { @@ -58,13 +59,20 @@ func TestPRReopen(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 666, "title": "The title of the PR", "closed": true} - } } } - `)) - - http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "id": "THE-ID", "number": 666, "title": "The title of the PR", "closed": true} + } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestReopen\b`), + httpmock.GraphQLMutation(`{"id": "THE-ID"}`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["pullRequestId"], "THE-ID") + }), + ) output, err := runCommand(http, true, "666") if err != nil { @@ -82,11 +90,13 @@ func TestPRReopen_alreadyOpen(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 666, "title": "The title of the PR", "closed": false} - } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "number": 666, "title": "The title of the PR", "closed": false} + } } }`), + ) output, err := runCommand(http, true, "666") if err != nil { @@ -104,11 +114,13 @@ func TestPRReopen_alreadyMerged(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { - "pullRequest": { "number": 666, "title": "The title of the PR", "closed": true, "state": "MERGED"} - } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { + "pullRequest": { "number": 666, "title": "The title of the PR", "closed": true, "state": "MERGED"} + } } }`), + ) output, err := runCommand(http, true, "666") if err == nil { diff --git a/pkg/cmd/pr/review/review_test.go b/pkg/cmd/pr/review/review_test.go index 2184c264c..749495c7a 100644 --- a/pkg/cmd/pr/review/review_test.go +++ b/pkg/cmd/pr/review/review_test.go @@ -2,7 +2,6 @@ package review import ( "bytes" - "encoding/json" "io/ioutil" "net/http" "regexp" @@ -183,24 +182,36 @@ func runCommand(rt http.RoundTripper, remotes context.Remotes, isTTY bool, cli s func TestPRReview_url_arg(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequest": { - "id": "foobar123", - "number": 123, - "headRefName": "feature", - "headRepositoryOwner": { - "login": "hubot" - }, - "headRepository": { - "name": "REPO", - "defaultBranchRef": { - "name": "master" - } - }, - "isCrossRepository": false, - "maintainerCanModify": false - } } } } `)) - http.StubResponse(200, bytes.NewBufferString(`{"data": {} }`)) + + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequest": { + "id": "foobar123", + "number": 123, + "headRefName": "feature", + "headRepositoryOwner": { + "login": "hubot" + }, + "headRepository": { + "name": "REPO", + "defaultBranchRef": { + "name": "master" + } + }, + "isCrossRepository": false, + "maintainerCanModify": false + } } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestReviewAdd\b`), + httpmock.GraphQLMutation(`{"data": {} }`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["pullRequestId"], "foobar123") + assert.Equal(t, inputs["event"], "APPROVE") + assert.Equal(t, inputs["body"], "") + }), + ) output, err := runCommand(http, nil, true, "--approve https://github.com/OWNER/REPO/pull/123") if err != nil { @@ -208,45 +219,41 @@ func TestPRReview_url_arg(t *testing.T) { } test.ExpectLines(t, output.Stderr(), "Approved pull request #123") - - bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body) - reqBody := struct { - Variables struct { - Input struct { - PullRequestID string - Event string - Body string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - assert.Equal(t, "foobar123", reqBody.Variables.Input.PullRequestID) - assert.Equal(t, "APPROVE", reqBody.Variables.Input.Event) - assert.Equal(t, "", reqBody.Variables.Input.Body) } func TestPRReview_number_arg(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequest": { - "id": "foobar123", - "number": 123, - "headRefName": "feature", - "headRepositoryOwner": { - "login": "hubot" - }, - "headRepository": { - "name": "REPO", - "defaultBranchRef": { - "name": "master" - } - }, - "isCrossRepository": false, - "maintainerCanModify": false - } } } } `)) - http.StubResponse(200, bytes.NewBufferString(`{"data": {} }`)) + + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequest": { + "id": "foobar123", + "number": 123, + "headRefName": "feature", + "headRepositoryOwner": { + "login": "hubot" + }, + "headRepository": { + "name": "REPO", + "defaultBranchRef": { + "name": "master" + } + }, + "isCrossRepository": false, + "maintainerCanModify": false + } } } } `), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestReviewAdd`), + httpmock.GraphQLMutation(`{"data": {} }`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["pullRequestId"], "foobar123") + assert.Equal(t, inputs["event"], "APPROVE") + assert.Equal(t, inputs["body"], "") + }), + ) output, err := runCommand(http, nil, true, "--approve 123") if err != nil { @@ -254,36 +261,32 @@ func TestPRReview_number_arg(t *testing.T) { } test.ExpectLines(t, output.Stderr(), "Approved pull request #123") - - bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body) - reqBody := struct { - Variables struct { - Input struct { - PullRequestID string - Event string - Body string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - assert.Equal(t, "foobar123", reqBody.Variables.Input.PullRequestID) - assert.Equal(t, "APPROVE", reqBody.Variables.Input.Event) - assert.Equal(t, "", reqBody.Variables.Input.Body) } func TestPRReview_no_arg(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "url": "https://github.com/OWNER/REPO/pull/123", - "number": 123, - "id": "foobar123", - "headRefName": "feature", - "baseRefName": "master" } - ] } } } }`)) - http.StubResponse(200, bytes.NewBufferString(`{"data": {} }`)) + + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "url": "https://github.com/OWNER/REPO/pull/123", + "number": 123, + "id": "foobar123", + "headRefName": "feature", + "baseRefName": "master" } + ] } } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestReviewAdd\b`), + httpmock.GraphQLMutation(`{"data": {} }`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["pullRequestId"], "foobar123") + assert.Equal(t, inputs["event"], "COMMENT") + assert.Equal(t, inputs["body"], "cool story") + }), + ) output, err := runCommand(http, nil, true, `--comment -b "cool story"`) if err != nil { @@ -291,22 +294,6 @@ func TestPRReview_no_arg(t *testing.T) { } test.ExpectLines(t, output.Stderr(), "Reviewed pull request #123") - - bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body) - reqBody := struct { - Variables struct { - Input struct { - PullRequestID string - Event string - Body string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - assert.Equal(t, "foobar123", reqBody.Variables.Input.PullRequestID) - assert.Equal(t, "COMMENT", reqBody.Variables.Input.Event) - assert.Equal(t, "cool story", reqBody.Variables.Input.Body) } func TestPRReview(t *testing.T) { @@ -326,34 +313,30 @@ func TestPRReview(t *testing.T) { t.Run(kase.Cmd, func(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` + + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` { "data": { "repository": { "pullRequests": { "nodes": [ { "url": "https://github.com/OWNER/REPO/pull/123", "id": "foobar123", "headRefName": "feature", "baseRefName": "master" } - ] } } } } - `)) - http.StubResponse(200, bytes.NewBufferString(`{"data": {} }`)) + ] } } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestReviewAdd\b`), + httpmock.GraphQLMutation(`{"data": {} }`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["event"], kase.ExpectedEvent) + assert.Equal(t, inputs["body"], kase.ExpectedBody) + }), + ) _, err := runCommand(http, nil, false, kase.Cmd) if err != nil { t.Fatalf("got unexpected error running %s: %s", kase.Cmd, err) } - - bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body) - reqBody := struct { - Variables struct { - Input struct { - Event string - Body string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - assert.Equal(t, kase.ExpectedEvent, reqBody.Variables.Input.Event) - assert.Equal(t, kase.ExpectedBody, reqBody.Variables.Input.Body) }) } } @@ -361,17 +344,27 @@ func TestPRReview(t *testing.T) { func TestPRReview_nontty(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "url": "https://github.com/OWNER/REPO/pull/123", - "number": 123, - "id": "foobar123", - "headRefName": "feature", - "baseRefName": "master" } - ] } } } } - `)) - http.StubResponse(200, bytes.NewBufferString(`{"data": {} }`)) + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "url": "https://github.com/OWNER/REPO/pull/123", + "number": 123, + "id": "foobar123", + "headRefName": "feature", + "baseRefName": "master" } + ] } } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestReviewAdd\b`), + httpmock.GraphQLMutation(`{"data": {} }`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["event"], "COMMENT") + assert.Equal(t, inputs["body"], "cool") + }), + ) + output, err := runCommand(http, nil, false, "-c -bcool") if err != nil { t.Fatalf("unexpected error running command: %s", err) @@ -379,35 +372,32 @@ func TestPRReview_nontty(t *testing.T) { assert.Equal(t, "", output.String()) assert.Equal(t, "", output.Stderr()) - - bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body) - reqBody := struct { - Variables struct { - Input struct { - Event string - Body string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - assert.Equal(t, "COMMENT", reqBody.Variables.Input.Event) - assert.Equal(t, "cool", reqBody.Variables.Input.Body) } func TestPRReview_interactive(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "url": "https://github.com/OWNER/REPO/pull/123", - "number": 123, - "id": "foobar123", - "headRefName": "feature", - "baseRefName": "master" } - ] } } } } - `)) - http.StubResponse(200, bytes.NewBufferString(`{"data": {} }`)) + + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "url": "https://github.com/OWNER/REPO/pull/123", + "number": 123, + "id": "foobar123", + "headRefName": "feature", + "baseRefName": "master" } + ] } } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestReviewAdd\b`), + httpmock.GraphQLMutation(`{"data": {} }`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["event"], "APPROVE") + assert.Equal(t, inputs["body"], "cool story") + }), + ) + as, teardown := prompt.InitAskStubber() defer teardown() @@ -440,33 +430,22 @@ func TestPRReview_interactive(t *testing.T) { test.ExpectLines(t, output.String(), "Got:", "cool.*story") - - bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body) - reqBody := struct { - Variables struct { - Input struct { - Event string - Body string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - assert.Equal(t, "APPROVE", reqBody.Variables.Input.Event) - assert.Equal(t, "cool story", reqBody.Variables.Input.Body) } func TestPRReview_interactive_no_body(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "url": "https://github.com/OWNER/REPO/pull/123", - "id": "foobar123", - "headRefName": "feature", - "baseRefName": "master" } - ] } } } } - `)) + + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "url": "https://github.com/OWNER/REPO/pull/123", + "id": "foobar123", + "headRefName": "feature", + "baseRefName": "master" } + ] } } } }`), + ) as, teardown := prompt.InitAskStubber() defer teardown() @@ -500,16 +479,27 @@ func TestPRReview_interactive_no_body(t *testing.T) { func TestPRReview_interactive_blank_approve(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "url": "https://github.com/OWNER/REPO/pull/123", - "number": 123, - "id": "foobar123", - "headRefName": "feature", - "baseRefName": "master" } - ] } } } } - `)) - http.StubResponse(200, bytes.NewBufferString(`{"data": {} }`)) + + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "url": "https://github.com/OWNER/REPO/pull/123", + "number": 123, + "id": "foobar123", + "headRefName": "feature", + "baseRefName": "master" } + ] } } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestReviewAdd\b`), + httpmock.GraphQLMutation(`{"data": {} }`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["event"], "APPROVE") + assert.Equal(t, inputs["body"], "") + }), + ) + as, teardown := prompt.InitAskStubber() defer teardown() @@ -543,18 +533,4 @@ func TestPRReview_interactive_blank_approve(t *testing.T) { } test.ExpectLines(t, output.Stderr(), "Approved pull request #123") - - bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body) - reqBody := struct { - Variables struct { - Input struct { - Event string - Body string - } - } - }{} - _ = json.Unmarshal(bodyBytes, &reqBody) - - assert.Equal(t, "APPROVE", reqBody.Variables.Input.Event) - assert.Equal(t, "", reqBody.Variables.Input.Body) } diff --git a/pkg/cmd/pr/view/view_test.go b/pkg/cmd/pr/view/view_test.go index 678629831..e61ccd614 100644 --- a/pkg/cmd/pr/view/view_test.go +++ b/pkg/cmd/pr/view/view_test.go @@ -553,11 +553,13 @@ func TestPRView_web_numberArg(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequest": { - "url": "https://github.com/OWNER/REPO/pull/23" - } } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequest": { + "url": "https://github.com/OWNER/REPO/pull/23" + } } } }`), + ) var seenCmd *exec.Cmd restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable { @@ -584,11 +586,13 @@ func TestPRView_web_numberArgWithHash(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequest": { - "url": "https://github.com/OWNER/REPO/pull/23" - } } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequest": { + "url": "https://github.com/OWNER/REPO/pull/23" + } } } }`), + ) var seenCmd *exec.Cmd restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable { @@ -614,11 +618,14 @@ func TestPRView_web_numberArgWithHash(t *testing.T) { func TestPRView_web_urlArg(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequest": { - "url": "https://github.com/OWNER/REPO/pull/23" - } } } } - `)) + + http.Register( + httpmock.GraphQL(`query PullRequestByNumber\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequest": { + "url": "https://github.com/OWNER/REPO/pull/23" + } } } }`), + ) var seenCmd *exec.Cmd restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable { @@ -645,13 +652,15 @@ func TestPRView_web_branchArg(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "headRefName": "blueberries", - "isCrossRepository": false, - "url": "https://github.com/OWNER/REPO/pull/23" } - ] } } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "headRefName": "blueberries", + "isCrossRepository": false, + "url": "https://github.com/OWNER/REPO/pull/23" } + ] } } } }`), + ) var seenCmd *exec.Cmd restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable { @@ -678,14 +687,16 @@ func TestPRView_web_branchWithOwnerArg(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) - http.StubResponse(200, bytes.NewBufferString(` - { "data": { "repository": { "pullRequests": { "nodes": [ - { "headRefName": "blueberries", - "isCrossRepository": true, - "headRepositoryOwner": { "login": "hubot" }, - "url": "https://github.com/hubot/REPO/pull/23" } - ] } } } } - `)) + http.Register( + httpmock.GraphQL(`query PullRequestForBranch\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes": [ + { "headRefName": "blueberries", + "isCrossRepository": true, + "headRepositoryOwner": { "login": "hubot" }, + "url": "https://github.com/hubot/REPO/pull/23" } + ] } } } }`), + ) var seenCmd *exec.Cmd restoreCmd := run.SetPrepareCmd(func(cmd *exec.Cmd) run.Runnable { diff --git a/pkg/cmd/repo/create/http_test.go b/pkg/cmd/repo/create/http_test.go index 360403538..240a1b625 100644 --- a/pkg/cmd/repo/create/http_test.go +++ b/pkg/cmd/repo/create/http_test.go @@ -1,20 +1,25 @@ package create import ( - "bytes" - "encoding/json" - "io/ioutil" "testing" "github.com/cli/cli/api" "github.com/cli/cli/pkg/httpmock" + "github.com/stretchr/testify/assert" ) func Test_RepoCreate(t *testing.T) { reg := &httpmock.Registry{} httpClient := api.NewHTTPClient(api.ReplaceTripper(reg)) - reg.StubResponse(200, bytes.NewBufferString(`{}`)) + reg.Register( + httpmock.GraphQL(`mutation RepositoryCreate\b`), + httpmock.GraphQLMutation(`{}`, + func(inputs map[string]interface{}) { + assert.Equal(t, inputs["description"], "roasted chestnuts") + assert.Equal(t, inputs["homepageUrl"], "http://example.com") + }), + ) input := repoCreateInput{ Description: "roasted chestnuts", @@ -29,20 +34,4 @@ func Test_RepoCreate(t *testing.T) { if len(reg.Requests) != 1 { t.Fatalf("expected 1 HTTP request, seen %d", len(reg.Requests)) } - - var reqBody struct { - Query string - Variables struct { - Input map[string]interface{} - } - } - - bodyBytes, _ := ioutil.ReadAll(reg.Requests[0].Body) - _ = json.Unmarshal(bodyBytes, &reqBody) - if description := reqBody.Variables.Input["description"].(string); description != "roasted chestnuts" { - t.Errorf("expected description to be %q, got %q", "roasted chestnuts", description) - } - if homepage := reqBody.Variables.Input["homepageUrl"].(string); homepage != "http://example.com" { - t.Errorf("expected homepageUrl to be %q, got %q", "http://example.com", homepage) - } } diff --git a/pkg/httpmock/legacy.go b/pkg/httpmock/legacy.go index c6f9e56db..071876cc1 100644 --- a/pkg/httpmock/legacy.go +++ b/pkg/httpmock/legacy.go @@ -2,19 +2,12 @@ package httpmock import ( "fmt" - "io" "net/http" "os" ) // TODO: clean up methods in this file when there are no more callers -func (r *Registry) StubResponse(status int, body io.Reader) { - r.Register(MatchAny, func(req *http.Request) (*http.Response, error) { - return httpResponse(status, req, body), nil - }) -} - func (r *Registry) StubWithFixturePath(status int, fixturePath string) func() { fixtureFile, err := os.Open(fixturePath) r.Register(MatchAny, func(req *http.Request) (*http.Response, error) {