From d0c2c81f2d1e9d70945c5a99efdecf3875011b97 Mon Sep 17 00:00:00 2001 From: AliabbasMerchant Date: Thu, 27 Aug 2020 13:39:21 +0530 Subject: [PATCH 1/3] Interactive template selection test for issue create --- pkg/cmd/issue/create/create.go | 7 +- pkg/cmd/issue/create/create_test.go | 71 ++++++++++++++++++- .../.github/ISSUE_TEMPLATE/bug_report.md | 9 +++ .../.github/ISSUE_TEMPLATE/enhancement.md | 9 +++ 4 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/enhancement.md diff --git a/pkg/cmd/issue/create/create.go b/pkg/cmd/issue/create/create.go index 8d47e4e27..4190fba3f 100644 --- a/pkg/cmd/issue/create/create.go +++ b/pkg/cmd/issue/create/create.go @@ -23,6 +23,8 @@ type CreateOptions struct { IO *iostreams.IOStreams BaseRepo func() (ghrepo.Interface, error) + RootDirOverride string + RepoOverride string WebMode bool @@ -94,9 +96,10 @@ func createRun(opts *CreateOptions) error { } var nonLegacyTemplateFiles []string - if opts.RepoOverride == "" { + if opts.RootDirOverride != "" { + nonLegacyTemplateFiles = githubtemplate.FindNonLegacy(opts.RootDirOverride, "ISSUE_TEMPLATE") + } else if opts.RepoOverride == "" { if rootDir, err := git.ToplevelDir(); err == nil { - // TODO: figure out how to stub this in tests nonLegacyTemplateFiles = githubtemplate.FindNonLegacy(rootDir, "ISSUE_TEMPLATE") } } diff --git a/pkg/cmd/issue/create/create_test.go b/pkg/cmd/issue/create/create_test.go index b483d090b..9a3cd119f 100644 --- a/pkg/cmd/issue/create/create_test.go +++ b/pkg/cmd/issue/create/create_test.go @@ -16,6 +16,7 @@ import ( "github.com/cli/cli/pkg/cmdutil" "github.com/cli/cli/pkg/httpmock" "github.com/cli/cli/pkg/iostreams" + "github.com/cli/cli/pkg/prompt" "github.com/cli/cli/test" "github.com/google/shlex" "github.com/stretchr/testify/assert" @@ -29,6 +30,10 @@ func eq(t *testing.T, got interface{}, expected interface{}) { } func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) { + return runCommandWithRootDirOverridden(rt, isTTY, cli, "") +} + +func runCommandWithRootDirOverridden(rt http.RoundTripper, isTTY bool, cli string, rootDir string) (*test.CmdOut, error) { io, _, stdout, stderr := iostreams.Test() io.SetStdoutTTY(isTTY) io.SetStdinTTY(isTTY) @@ -47,7 +52,10 @@ func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, err }, } - cmd := NewCmdCreate(factory, nil) + cmd := NewCmdCreate(factory, func(opts *CreateOptions) error { + opts.RootDirOverride = rootDir + return createRun(opts) + }) argv, err := shlex.Split(cli) if err != nil { @@ -126,6 +134,67 @@ func TestIssueCreate(t *testing.T) { eq(t, output.String(), "https://github.com/OWNER/REPO/issues/12\n") } +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" + } } } } + `)) + + as, teardown := prompt.InitAskStubber() + defer teardown() + as.Stub([]*prompt.QuestionStub{ + { + Name: "index", + Value: 1, + }, + }) + as.Stub([]*prompt.QuestionStub{ + { + Name: "body", + Default: true, + }, + }) + as.Stub([]*prompt.QuestionStub{ + { + Name: "confirmation", + Value: 0, + }, + }) + + output, err := runCommandWithRootDirOverridden(http, true, `-t hello`, "./repoWithNonLegacyIssueTemplates") + 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, "I have a suggestion for an enhancement") + + eq(t, output.String(), "https://github.com/OWNER/REPO/issues/12\n") +} + func TestIssueCreate_metadata(t *testing.T) { http := &httpmock.Registry{} defer http.Verify(t) diff --git a/pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/bug_report.md b/pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..d57082bcf --- /dev/null +++ b/pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,9 @@ +--- +name: Bug report +about: Report a bug or unexpected behavior +title: Bug Report +labels: bug + +--- + +I wanna report a bug \ No newline at end of file diff --git a/pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/enhancement.md b/pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/enhancement.md new file mode 100644 index 000000000..0fe84afa3 --- /dev/null +++ b/pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/enhancement.md @@ -0,0 +1,9 @@ +--- +name: Submit a request +about: Propose an improvement +title: Enhancement Proposal +labels: enhancement + +--- + +I have a suggestion for an enhancement \ No newline at end of file From 51c5595cad70de1316050773be3767b4c30f6dcd Mon Sep 17 00:00:00 2001 From: AliabbasMerchant Date: Wed, 2 Sep 2020 09:56:28 +0530 Subject: [PATCH 2/3] Interactive template selection test for PR create --- pkg/cmd/issue/create/create_test.go | 2 +- .../.github/ISSUE_TEMPLATE/bug_report.md | 0 .../.github/ISSUE_TEMPLATE/enhancement.md | 0 pkg/cmd/pr/create/create.go | 9 +- pkg/cmd/pr/create/create_test.go | 83 ++++++++++++++++++- .../.github/PULL_REQUEST_TEMPLATE/bug_fix.md | 8 ++ 6 files changed, 98 insertions(+), 4 deletions(-) rename pkg/cmd/issue/create/{ => fixtures}/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/bug_report.md (100%) rename pkg/cmd/issue/create/{ => fixtures}/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/enhancement.md (100%) create mode 100644 pkg/cmd/pr/create/fixtures/repoWithNonLegacyPRTemplates/.github/PULL_REQUEST_TEMPLATE/bug_fix.md diff --git a/pkg/cmd/issue/create/create_test.go b/pkg/cmd/issue/create/create_test.go index 9a3cd119f..fb46e6e1e 100644 --- a/pkg/cmd/issue/create/create_test.go +++ b/pkg/cmd/issue/create/create_test.go @@ -171,7 +171,7 @@ func TestIssueCreate_nonLegacyTemplate(t *testing.T) { }, }) - output, err := runCommandWithRootDirOverridden(http, true, `-t hello`, "./repoWithNonLegacyIssueTemplates") + output, err := runCommandWithRootDirOverridden(http, true, `-t hello`, "./fixtures/repoWithNonLegacyIssueTemplates") if err != nil { t.Errorf("error running command `issue create`: %v", err) } diff --git a/pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/bug_report.md b/pkg/cmd/issue/create/fixtures/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/bug_report.md rename to pkg/cmd/issue/create/fixtures/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/bug_report.md diff --git a/pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/enhancement.md b/pkg/cmd/issue/create/fixtures/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/enhancement.md similarity index 100% rename from pkg/cmd/issue/create/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/enhancement.md rename to pkg/cmd/issue/create/fixtures/repoWithNonLegacyIssueTemplates/.github/ISSUE_TEMPLATE/enhancement.md diff --git a/pkg/cmd/pr/create/create.go b/pkg/cmd/pr/create/create.go index c9e1fb6ab..156244ea5 100644 --- a/pkg/cmd/pr/create/create.go +++ b/pkg/cmd/pr/create/create.go @@ -28,6 +28,8 @@ type CreateOptions struct { Remotes func() (context.Remotes, error) Branch func() (string, error) + RootDirOverride string + RepoOverride string Autofill bool @@ -246,8 +248,11 @@ func createRun(opts *CreateOptions) error { if !opts.WebMode && !opts.Autofill && interactive { var nonLegacyTemplateFiles []string var legacyTemplateFile *string - if rootDir, err := git.ToplevelDir(); err == nil { - // TODO: figure out how to stub this in tests + + if opts.RootDirOverride != "" { + nonLegacyTemplateFiles = githubtemplate.FindNonLegacy(opts.RootDirOverride, "PULL_REQUEST_TEMPLATE") + legacyTemplateFile = githubtemplate.FindLegacy(opts.RootDirOverride, "PULL_REQUEST_TEMPLATE") + } else if rootDir, err := git.ToplevelDir(); err == nil { nonLegacyTemplateFiles = githubtemplate.FindNonLegacy(rootDir, "PULL_REQUEST_TEMPLATE") legacyTemplateFile = githubtemplate.FindLegacy(rootDir, "PULL_REQUEST_TEMPLATE") } diff --git a/pkg/cmd/pr/create/create_test.go b/pkg/cmd/pr/create/create_test.go index e50a72c63..439b4dac1 100644 --- a/pkg/cmd/pr/create/create_test.go +++ b/pkg/cmd/pr/create/create_test.go @@ -31,6 +31,10 @@ func eq(t *testing.T, got interface{}, expected interface{}) { } func runCommand(rt http.RoundTripper, remotes context.Remotes, branch string, isTTY bool, cli string) (*test.CmdOut, error) { + return runCommandWithRootDirOverridden(rt, remotes, branch, isTTY, cli, "") +} + +func runCommandWithRootDirOverridden(rt http.RoundTripper, remotes context.Remotes, branch string, isTTY bool, cli string, rootDir string) (*test.CmdOut, error) { io, _, stdout, stderr := iostreams.Test() io.SetStdoutTTY(isTTY) io.SetStdinTTY(isTTY) @@ -60,7 +64,10 @@ func runCommand(rt http.RoundTripper, remotes context.Remotes, branch string, is }, } - cmd := NewCmdCreate(factory, nil) + cmd := NewCmdCreate(factory, func(opts *CreateOptions) error { + opts.RootDirOverride = rootDir + return createRun(opts) + }) cmd.PersistentFlags().StringP("repo", "R", "", "") argv, err := shlex.Split(cli) @@ -239,6 +246,80 @@ func TestPRCreate(t *testing.T) { eq(t, output.String(), "https://github.com/OWNER/REPO/pull/12\n") } +func TestPRCreate_nonLegacyTemplate(t *testing.T) { + http := initFakeHTTP() + defer http.Verify(t) + + http.StubRepoResponse("OWNER", "REPO") + http.StubResponse(200, bytes.NewBufferString(` + { "data": { "repository": { "forks": { "nodes": [ + ] } } } } + `)) + 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" + } } } } + `)) + + cs, cmdTeardown := test.InitCmdStubber() + defer cmdTeardown() + + cs.Stub("") // git config --get-regexp (determineTrackingBranch) + cs.Stub("") // git show-ref --verify (determineTrackingBranch) + cs.Stub("") // git status + cs.Stub("1234567890,commit 0\n2345678901,commit 1") // git log + cs.Stub("") // git push + + as, teardown := prompt.InitAskStubber() + defer teardown() + as.Stub([]*prompt.QuestionStub{ + { + Name: "index", + Value: 0, + }, + }) + as.Stub([]*prompt.QuestionStub{ + { + Name: "body", + Default: true, + }, + }) + as.Stub([]*prompt.QuestionStub{ + { + Name: "confirmation", + Value: 0, + }, + }) + + output, err := runCommandWithRootDirOverridden(http, nil, "feature", true, `-t "my title"`, "./fixtures/repoWithNonLegacyPRTemplates") + require.NoError(t, err) + + bodyBytes, _ := ioutil.ReadAll(http.Requests[3].Body) + reqBody := struct { + Variables struct { + Input struct { + RepositoryID string + Title string + Body string + BaseRefName string + HeadRefName string + } + } + }{} + _ = json.Unmarshal(bodyBytes, &reqBody) + + eq(t, reqBody.Variables.Input.RepositoryID, "REPOID") + eq(t, reqBody.Variables.Input.Title, "my title") + eq(t, reqBody.Variables.Input.Body, "Fixes a bug \nCloses an issue") + eq(t, reqBody.Variables.Input.BaseRefName, "master") + eq(t, reqBody.Variables.Input.HeadRefName, "feature") + + eq(t, output.String(), "https://github.com/OWNER/REPO/pull/12\n") +} func TestPRCreate_metadata(t *testing.T) { http := initFakeHTTP() diff --git a/pkg/cmd/pr/create/fixtures/repoWithNonLegacyPRTemplates/.github/PULL_REQUEST_TEMPLATE/bug_fix.md b/pkg/cmd/pr/create/fixtures/repoWithNonLegacyPRTemplates/.github/PULL_REQUEST_TEMPLATE/bug_fix.md new file mode 100644 index 000000000..644463118 --- /dev/null +++ b/pkg/cmd/pr/create/fixtures/repoWithNonLegacyPRTemplates/.github/PULL_REQUEST_TEMPLATE/bug_fix.md @@ -0,0 +1,8 @@ +--- +name: "Bug fix" +about: Fix a bug + +--- + +Fixes a bug +Closes an issue \ No newline at end of file From 9e7279604d92416c3b3a79d6632cb5d19aa4998e Mon Sep 17 00:00:00 2001 From: AliabbasMerchant Date: Wed, 2 Sep 2020 10:03:56 +0530 Subject: [PATCH 3/3] Fix failing tests for Windows (due to line-ending issues) --- pkg/cmd/pr/create/create_test.go | 2 +- .../.github/PULL_REQUEST_TEMPLATE/bug_fix.md | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/cmd/pr/create/create_test.go b/pkg/cmd/pr/create/create_test.go index 439b4dac1..6b79551bf 100644 --- a/pkg/cmd/pr/create/create_test.go +++ b/pkg/cmd/pr/create/create_test.go @@ -314,7 +314,7 @@ func TestPRCreate_nonLegacyTemplate(t *testing.T) { eq(t, reqBody.Variables.Input.RepositoryID, "REPOID") eq(t, reqBody.Variables.Input.Title, "my title") - eq(t, reqBody.Variables.Input.Body, "Fixes a bug \nCloses an issue") + eq(t, reqBody.Variables.Input.Body, "Fixes a bug and Closes an issue") eq(t, reqBody.Variables.Input.BaseRefName, "master") eq(t, reqBody.Variables.Input.HeadRefName, "feature") diff --git a/pkg/cmd/pr/create/fixtures/repoWithNonLegacyPRTemplates/.github/PULL_REQUEST_TEMPLATE/bug_fix.md b/pkg/cmd/pr/create/fixtures/repoWithNonLegacyPRTemplates/.github/PULL_REQUEST_TEMPLATE/bug_fix.md index 644463118..5e98de344 100644 --- a/pkg/cmd/pr/create/fixtures/repoWithNonLegacyPRTemplates/.github/PULL_REQUEST_TEMPLATE/bug_fix.md +++ b/pkg/cmd/pr/create/fixtures/repoWithNonLegacyPRTemplates/.github/PULL_REQUEST_TEMPLATE/bug_fix.md @@ -4,5 +4,4 @@ about: Fix a bug --- -Fixes a bug -Closes an issue \ No newline at end of file +Fixes a bug and Closes an issue \ No newline at end of file