github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/issue/delete/delete_test.go (about) 1 package delete 2 3 import ( 4 "bytes" 5 "io" 6 "net/http" 7 "regexp" 8 "testing" 9 10 "github.com/ungtb10d/cli/v2/internal/config" 11 "github.com/ungtb10d/cli/v2/internal/ghrepo" 12 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 13 "github.com/ungtb10d/cli/v2/pkg/httpmock" 14 "github.com/ungtb10d/cli/v2/pkg/iostreams" 15 "github.com/ungtb10d/cli/v2/pkg/prompt" 16 "github.com/ungtb10d/cli/v2/test" 17 "github.com/google/shlex" 18 "github.com/stretchr/testify/assert" 19 ) 20 21 func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) { 22 ios, _, stdout, stderr := iostreams.Test() 23 ios.SetStdoutTTY(isTTY) 24 ios.SetStdinTTY(isTTY) 25 ios.SetStderrTTY(isTTY) 26 27 factory := &cmdutil.Factory{ 28 IOStreams: ios, 29 HttpClient: func() (*http.Client, error) { 30 return &http.Client{Transport: rt}, nil 31 }, 32 Config: func() (config.Config, error) { 33 return config.NewBlankConfig(), nil 34 }, 35 BaseRepo: func() (ghrepo.Interface, error) { 36 return ghrepo.New("OWNER", "REPO"), nil 37 }, 38 } 39 40 cmd := NewCmdDelete(factory, nil) 41 42 argv, err := shlex.Split(cli) 43 if err != nil { 44 return nil, err 45 } 46 cmd.SetArgs(argv) 47 48 cmd.SetIn(&bytes.Buffer{}) 49 cmd.SetOut(io.Discard) 50 cmd.SetErr(io.Discard) 51 52 _, err = cmd.ExecuteC() 53 return &test.CmdOut{ 54 OutBuf: stdout, 55 ErrBuf: stderr, 56 }, err 57 } 58 59 func TestIssueDelete(t *testing.T) { 60 httpRegistry := &httpmock.Registry{} 61 defer httpRegistry.Verify(t) 62 63 httpRegistry.Register( 64 httpmock.GraphQL(`query IssueByNumber\b`), 65 httpmock.StringResponse(` 66 { "data": { "repository": { 67 "hasIssuesEnabled": true, 68 "issue": { "id": "THE-ID", "number": 13, "title": "The title of the issue"} 69 } } }`), 70 ) 71 httpRegistry.Register( 72 httpmock.GraphQL(`mutation IssueDelete\b`), 73 httpmock.GraphQLMutation(`{"id": "THE-ID"}`, 74 func(inputs map[string]interface{}) { 75 assert.Equal(t, inputs["issueId"], "THE-ID") 76 }), 77 ) 78 79 //nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock 80 as := prompt.NewAskStubber(t) 81 as.StubPrompt("You're going to delete issue #13. This action cannot be reversed. To confirm, type the issue number:").AnswerWith("13") 82 83 output, err := runCommand(httpRegistry, true, "13") 84 if err != nil { 85 t.Fatalf("error running command `issue delete`: %v", err) 86 } 87 88 r := regexp.MustCompile(`Deleted issue #13 \(The title of the issue\)`) 89 90 if !r.MatchString(output.Stderr()) { 91 t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) 92 } 93 } 94 95 func TestIssueDelete_confirm(t *testing.T) { 96 httpRegistry := &httpmock.Registry{} 97 defer httpRegistry.Verify(t) 98 99 httpRegistry.Register( 100 httpmock.GraphQL(`query IssueByNumber\b`), 101 httpmock.StringResponse(` 102 { "data": { "repository": { 103 "hasIssuesEnabled": true, 104 "issue": { "id": "THE-ID", "number": 13, "title": "The title of the issue"} 105 } } }`), 106 ) 107 httpRegistry.Register( 108 httpmock.GraphQL(`mutation IssueDelete\b`), 109 httpmock.GraphQLMutation(`{"id": "THE-ID"}`, 110 func(inputs map[string]interface{}) { 111 assert.Equal(t, inputs["issueId"], "THE-ID") 112 }), 113 ) 114 115 output, err := runCommand(httpRegistry, true, "13 --confirm") 116 if err != nil { 117 t.Fatalf("error running command `issue delete`: %v", err) 118 } 119 120 r := regexp.MustCompile(`Deleted issue #13 \(The title of the issue\)`) 121 122 if !r.MatchString(output.Stderr()) { 123 t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.Stderr()) 124 } 125 } 126 127 func TestIssueDelete_cancel(t *testing.T) { 128 httpRegistry := &httpmock.Registry{} 129 defer httpRegistry.Verify(t) 130 131 httpRegistry.Register( 132 httpmock.GraphQL(`query IssueByNumber\b`), 133 httpmock.StringResponse(` 134 { "data": { "repository": { 135 "hasIssuesEnabled": true, 136 "issue": { "id": "THE-ID", "number": 13, "title": "The title of the issue"} 137 } } }`), 138 ) 139 140 //nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock 141 as := prompt.NewAskStubber(t) 142 as.StubPrompt("You're going to delete issue #13. This action cannot be reversed. To confirm, type the issue number:").AnswerWith("14") 143 144 output, err := runCommand(httpRegistry, true, "13") 145 if err != nil { 146 t.Fatalf("error running command `issue delete`: %v", err) 147 } 148 149 r := regexp.MustCompile(`Issue #13 was not deleted`) 150 151 if !r.MatchString(output.String()) { 152 t.Fatalf("output did not match regexp /%s/\n> output\n%q\n", r, output.String()) 153 } 154 } 155 156 func TestIssueDelete_doesNotExist(t *testing.T) { 157 httpRegistry := &httpmock.Registry{} 158 defer httpRegistry.Verify(t) 159 160 httpRegistry.Register( 161 httpmock.GraphQL(`query IssueByNumber\b`), 162 httpmock.StringResponse(` 163 { "errors": [ 164 { "message": "Could not resolve to an Issue with the number of 13." } 165 ] } 166 `), 167 ) 168 169 _, err := runCommand(httpRegistry, true, "13") 170 if err == nil || err.Error() != "GraphQL: Could not resolve to an Issue with the number of 13." { 171 t.Errorf("error running command `issue delete`: %v", err) 172 } 173 } 174 175 func TestIssueDelete_issuesDisabled(t *testing.T) { 176 httpRegistry := &httpmock.Registry{} 177 defer httpRegistry.Verify(t) 178 179 httpRegistry.Register( 180 httpmock.GraphQL(`query IssueByNumber\b`), 181 httpmock.StringResponse(` 182 { 183 "data": { 184 "repository": { 185 "hasIssuesEnabled": false, 186 "issue": null 187 } 188 }, 189 "errors": [ 190 { 191 "type": "NOT_FOUND", 192 "path": [ 193 "repository", 194 "issue" 195 ], 196 "message": "Could not resolve to an issue or pull request with the number of 13." 197 } 198 ] 199 }`), 200 ) 201 202 _, err := runCommand(httpRegistry, true, "13") 203 if err == nil || err.Error() != "the 'OWNER/REPO' repository has disabled issues" { 204 t.Fatalf("got error: %v", err) 205 } 206 }