Make MetadataSurvey testable by accepting an interface

This commit is contained in:
Mislav Marohnić 2020-12-03 17:47:40 +01:00
parent d6add864b8
commit be39f4363b
4 changed files with 184 additions and 13 deletions

View file

@ -207,7 +207,13 @@ func createRun(opts *CreateOptions) (err error) {
}
if action == prShared.MetadataAction {
err = prShared.MetadataSurvey(opts.IO, apiClient, baseRepo, &tb)
fetcher := &prShared.MetadataFetcher{
IO: opts.IO,
APIClient: apiClient,
Repo: baseRepo,
State: &tb,
}
err = prShared.MetadataSurvey(opts.IO, baseRepo, fetcher, &tb)
if err != nil {
return
}

View file

@ -259,7 +259,13 @@ func createRun(opts *CreateOptions) (err error) {
}
if action == shared.MetadataAction {
err = shared.MetadataSurvey(opts.IO, client, ctx.BaseRepo, state)
fetcher := &shared.MetadataFetcher{
IO: opts.IO,
APIClient: client,
Repo: ctx.BaseRepo,
State: state,
}
err = shared.MetadataSurvey(opts.IO, ctx.BaseRepo, fetcher, state)
if err != nil {
return
}

View file

@ -12,7 +12,6 @@ import (
"github.com/cli/cli/pkg/iostreams"
"github.com/cli/cli/pkg/prompt"
"github.com/cli/cli/pkg/surveyext"
"github.com/cli/cli/utils"
)
type Action int
@ -196,7 +195,26 @@ func TitleSurvey(state *IssueMetadataState) error {
return nil
}
func MetadataSurvey(io *iostreams.IOStreams, client *api.Client, baseRepo ghrepo.Interface, state *IssueMetadataState) error {
type MetadataFetcher struct {
IO *iostreams.IOStreams
APIClient *api.Client
Repo ghrepo.Interface
State *IssueMetadataState
}
func (mf *MetadataFetcher) RepoMetadataFetch(input api.RepoMetadataInput) (*api.RepoMetadataResult, error) {
mf.IO.StartProgressIndicator()
metadataResult, err := api.RepoMetadata(mf.APIClient, mf.Repo, input)
mf.IO.StopProgressIndicator()
mf.State.MetadataResult = metadataResult
return metadataResult, err
}
type RepoMetadataFetcher interface {
RepoMetadataFetch(api.RepoMetadataInput) (*api.RepoMetadataResult, error)
}
func MetadataSurvey(io *iostreams.IOStreams, baseRepo ghrepo.Interface, fetcher RepoMetadataFetcher, state *IssueMetadataState) error {
isChosen := func(m string) bool {
for _, c := range state.Metadata {
if m == c {
@ -234,32 +252,29 @@ func MetadataSurvey(io *iostreams.IOStreams, client *api.Client, baseRepo ghrepo
Projects: isChosen("Projects"),
Milestones: isChosen("Milestone"),
}
s := utils.Spinner(io.ErrOut)
utils.StartSpinner(s)
state.MetadataResult, err = api.RepoMetadata(client, baseRepo, metadataInput)
utils.StopSpinner(s)
metadataResult, err := fetcher.RepoMetadataFetch(metadataInput)
if err != nil {
return fmt.Errorf("error fetching metadata options: %w", err)
}
var users []string
for _, u := range state.MetadataResult.AssignableUsers {
for _, u := range metadataResult.AssignableUsers {
users = append(users, u.Login)
}
var teams []string
for _, t := range state.MetadataResult.Teams {
for _, t := range metadataResult.Teams {
teams = append(teams, fmt.Sprintf("%s/%s", baseRepo.RepoOwner(), t.Slug))
}
var labels []string
for _, l := range state.MetadataResult.Labels {
for _, l := range metadataResult.Labels {
labels = append(labels, l.Name)
}
var projects []string
for _, l := range state.MetadataResult.Projects {
for _, l := range metadataResult.Projects {
projects = append(projects, l.Name)
}
milestones := []string{noMilestone}
for _, m := range state.MetadataResult.Milestones {
for _, m := range metadataResult.Milestones {
milestones = append(milestones, m.Title)
}

View file

@ -0,0 +1,144 @@
package shared
import (
"testing"
"github.com/cli/cli/api"
"github.com/cli/cli/internal/ghrepo"
"github.com/cli/cli/pkg/iostreams"
"github.com/cli/cli/pkg/prompt"
"github.com/stretchr/testify/assert"
)
type metadataFetcher struct {
metadataResult *api.RepoMetadataResult
}
func (mf *metadataFetcher) RepoMetadataFetch(input api.RepoMetadataInput) (*api.RepoMetadataResult, error) {
return mf.metadataResult, nil
}
func TestMetadataSurvey_selectAll(t *testing.T) {
io, _, stdout, stderr := iostreams.Test()
repo := ghrepo.New("OWNER", "REPO")
fetcher := &metadataFetcher{
metadataResult: &api.RepoMetadataResult{
AssignableUsers: []api.RepoAssignee{
{Login: "hubot"},
{Login: "monalisa"},
},
Labels: []api.RepoLabel{
{Name: "help wanted"},
{Name: "good first issue"},
},
Projects: []api.RepoProject{
{Name: "Huge Refactoring"},
{Name: "The road to 1.0"},
},
Milestones: []api.RepoMilestone{
{Title: "1.2 patch release"},
},
},
}
as, restoreAsk := prompt.InitAskStubber()
defer restoreAsk()
as.Stub([]*prompt.QuestionStub{
{
Name: "metadata",
Value: []string{"Labels", "Projects", "Assignees", "Reviewers", "Milestone"},
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "reviewers",
Value: []string{"monalisa"},
},
{
Name: "assignees",
Value: []string{"hubot"},
},
{
Name: "labels",
Value: []string{"good first issue"},
},
{
Name: "projects",
Value: []string{"The road to 1.0"},
},
{
Name: "milestone",
Value: []string{"(none)"},
},
})
state := &IssueMetadataState{
Assignees: []string{"hubot"},
}
err := MetadataSurvey(io, repo, fetcher, state)
assert.NoError(t, err)
assert.Equal(t, "", stdout.String())
assert.Equal(t, "", stderr.String())
assert.Equal(t, []string{"hubot"}, state.Assignees)
assert.Equal(t, []string{"monalisa"}, state.Reviewers)
assert.Equal(t, []string{"good first issue"}, state.Labels)
assert.Equal(t, []string{"The road to 1.0"}, state.Projects)
assert.Equal(t, []string{}, state.Milestones)
}
func TestMetadataSurvey_keepExisting(t *testing.T) {
io, _, stdout, stderr := iostreams.Test()
repo := ghrepo.New("OWNER", "REPO")
fetcher := &metadataFetcher{
metadataResult: &api.RepoMetadataResult{
Labels: []api.RepoLabel{
{Name: "help wanted"},
{Name: "good first issue"},
},
Projects: []api.RepoProject{
{Name: "Huge Refactoring"},
{Name: "The road to 1.0"},
},
},
}
as, restoreAsk := prompt.InitAskStubber()
defer restoreAsk()
as.Stub([]*prompt.QuestionStub{
{
Name: "metadata",
Value: []string{"Labels", "Projects"},
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "labels",
Value: []string{"good first issue"},
},
{
Name: "projects",
Value: []string{"The road to 1.0"},
},
})
state := &IssueMetadataState{
Assignees: []string{"hubot"},
}
err := MetadataSurvey(io, repo, fetcher, state)
assert.NoError(t, err)
assert.Equal(t, "", stdout.String())
assert.Equal(t, "", stderr.String())
assert.Equal(t, []string{"hubot"}, state.Assignees)
assert.Equal(t, []string{"good first issue"}, state.Labels)
assert.Equal(t, []string{"The road to 1.0"}, state.Projects)
}