use prompter in issue delete

This commit is contained in:
Nate Smith 2023-08-16 21:48:30 -05:00
parent fc73c16fe8
commit 0d3b7db495
2 changed files with 28 additions and 36 deletions

View file

@ -3,16 +3,13 @@ package delete
import (
"fmt"
"net/http"
"strconv"
"github.com/AlecAivazis/survey/v2"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/pkg/cmd/issue/shared"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/cli/cli/v2/pkg/prompt"
"github.com/shurcooL/githubv4"
"github.com/spf13/cobra"
)
@ -22,16 +19,22 @@ type DeleteOptions struct {
Config func() (config.Config, error)
IO *iostreams.IOStreams
BaseRepo func() (ghrepo.Interface, error)
Prompter iprompter
SelectorArg string
Confirmed bool
}
type iprompter interface {
ConfirmDeletion(string) error
}
func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Command {
opts := &DeleteOptions{
IO: f.IOStreams,
HttpClient: f.HttpClient,
Config: f.Config,
Prompter: f.Prompter,
}
cmd := &cobra.Command{
@ -79,22 +82,12 @@ func deleteRun(opts *DeleteOptions) error {
// When executed in an interactive shell, require confirmation, unless
// already provided. Otherwise skip confirmation.
if opts.IO.CanPrompt() && !opts.Confirmed {
answer := ""
//nolint:staticcheck // SA1019: prompt.SurveyAskOne is deprecated: use Prompter
err = prompt.SurveyAskOne(
&survey.Input{
Message: fmt.Sprintf("You're going to delete issue #%d. This action cannot be reversed. To confirm, type the issue number:", issue.Number),
},
&answer,
)
cs := opts.IO.ColorScheme()
fmt.Printf("%s Deleted issues cannot be recovered.\n", cs.WarningIcon())
err := opts.Prompter.ConfirmDeletion(fmt.Sprintf("%d", issue.Number))
if err != nil {
return err
}
answerInt, err := strconv.Atoi(answer)
if err != nil || answerInt != issue.Number {
fmt.Fprintf(opts.IO.Out, "Issue #%d was not deleted.\n", issue.Number)
return nil
}
}
if err := apiDelete(httpClient, baseRepo, issue.ID); err != nil {

View file

@ -2,6 +2,7 @@ package delete
import (
"bytes"
"errors"
"io"
"net/http"
"regexp"
@ -9,16 +10,16 @@ import (
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/internal/prompter"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/httpmock"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/cli/cli/v2/pkg/prompt"
"github.com/cli/cli/v2/test"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
)
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
func runCommand(rt http.RoundTripper, pm *prompter.MockPrompter, isTTY bool, cli string) (*test.CmdOut, error) {
ios, _, stdout, stderr := iostreams.Test()
ios.SetStdoutTTY(isTTY)
ios.SetStdinTTY(isTTY)
@ -26,6 +27,7 @@ func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, err
factory := &cmdutil.Factory{
IOStreams: ios,
Prompter: pm,
HttpClient: func() (*http.Client, error) {
return &http.Client{Transport: rt}, nil
},
@ -76,11 +78,10 @@ func TestIssueDelete(t *testing.T) {
}),
)
//nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock
as := prompt.NewAskStubber(t)
as.StubPrompt("You're going to delete issue #13. This action cannot be reversed. To confirm, type the issue number:").AnswerWith("13")
pm := prompter.NewMockPrompter(t)
pm.RegisterConfirmDeletion("13", func(_ string) error { return nil })
output, err := runCommand(httpRegistry, true, "13")
output, err := runCommand(httpRegistry, pm, true, "13")
if err != nil {
t.Fatalf("error running command `issue delete`: %v", err)
}
@ -112,7 +113,7 @@ func TestIssueDelete_confirm(t *testing.T) {
}),
)
output, err := runCommand(httpRegistry, true, "13 --confirm")
output, err := runCommand(httpRegistry, nil, true, "13 --confirm")
if err != nil {
t.Fatalf("error running command `issue delete`: %v", err)
}
@ -137,19 +138,17 @@ func TestIssueDelete_cancel(t *testing.T) {
} } }`),
)
//nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock
as := prompt.NewAskStubber(t)
as.StubPrompt("You're going to delete issue #13. This action cannot be reversed. To confirm, type the issue number:").AnswerWith("14")
pm := prompter.NewMockPrompter(t)
pm.RegisterConfirmDeletion("13", func(_ string) error {
return errors.New("You entered 14")
})
output, err := runCommand(httpRegistry, true, "13")
if err != nil {
t.Fatalf("error running command `issue delete`: %v", err)
_, err := runCommand(httpRegistry, pm, true, "13")
if err == nil {
t.Fatalf("expected error")
}
r := regexp.MustCompile(`Issue #13 was not deleted`)
if !r.MatchString(output.String()) {
t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.String())
if err.Error() != "You entered 14" {
t.Fatalf("got unexpected error '%s'", err)
}
}
@ -166,7 +165,7 @@ func TestIssueDelete_doesNotExist(t *testing.T) {
`),
)
_, err := runCommand(httpRegistry, true, "13")
_, err := runCommand(httpRegistry, nil, true, "13")
if err == nil || err.Error() != "GraphQL: Could not resolve to an Issue with the number of 13." {
t.Errorf("error running command `issue delete`: %v", err)
}
@ -199,7 +198,7 @@ func TestIssueDelete_issuesDisabled(t *testing.T) {
}`),
)
_, err := runCommand(httpRegistry, true, "13")
_, err := runCommand(httpRegistry, nil, true, "13")
if err == nil || err.Error() != "the 'OWNER/REPO' repository has disabled issues" {
t.Fatalf("got error: %v", err)
}