Skip to content

Commit

Permalink
Add a command to delete a gist (cli#2265)
Browse files Browse the repository at this point in the history
* Add a command to delete a gist

* minor cleanup

Co-authored-by: vilmibm <[email protected]>
  • Loading branch information
alexpjohnson and vilmibm authored Nov 16, 2020
1 parent 116d581 commit 99574f8
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 0 deletions.
88 changes: 88 additions & 0 deletions pkg/cmd/gist/delete/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package delete

import (
"fmt"
"github.com/cli/cli/api"
"github.com/cli/cli/internal/ghinstance"
"github.com/cli/cli/pkg/cmd/gist/shared"
"github.com/cli/cli/pkg/cmdutil"
"github.com/cli/cli/pkg/iostreams"
"github.com/spf13/cobra"
"net/http"
"strings"
)

type DeleteOptions struct {
IO *iostreams.IOStreams
HttpClient func() (*http.Client, error)

Selector string
}

func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Command {
opts := DeleteOptions{
IO: f.IOStreams,
HttpClient: f.HttpClient,
}

cmd := &cobra.Command{
Use: "delete {<gist ID> | <gist URL>}",
Short: "Delete a gist",
Args: cobra.ExactArgs(1),
RunE: func(c *cobra.Command, args []string) error {
opts.Selector = args[0]
if runF != nil {
return runF(&opts)
}
return deleteRun(&opts)
},
}
return cmd
}

func deleteRun(opts *DeleteOptions) error {
gistID := opts.Selector

if strings.Contains(gistID, "/") {
id, err := shared.GistIDFromURL(gistID)
if err != nil {
return err
}
gistID = id
}
client, err := opts.HttpClient()
if err != nil {
return err
}

apiClient := api.NewClientFromHTTP(client)

gist, err := shared.GetGist(client, ghinstance.OverridableDefault(), gistID)
if err != nil {
return err
}
username, err := api.CurrentLoginName(apiClient, ghinstance.OverridableDefault())
if err != nil {
return err
}

if username != gist.Owner.Login {
return fmt.Errorf("You do not own this gist.")
}

err = deleteGist(apiClient, ghinstance.OverridableDefault(), gistID)
if err != nil {
return err
}

return nil
}

func deleteGist(apiClient *api.Client, hostname string, gistID string) error {
path := "gists/" + gistID
err := apiClient.REST(hostname, "DELETE", path, nil, nil)
if err != nil {
return err
}
return nil
}
156 changes: 156 additions & 0 deletions pkg/cmd/gist/delete/delete_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package delete

import (
"bytes"
"github.com/cli/cli/pkg/cmd/gist/shared"
"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/google/shlex"
"github.com/stretchr/testify/assert"
"net/http"
"testing"
)

func TestNewCmdDelete(t *testing.T) {
tests := []struct {
name string
cli string
wants DeleteOptions
}{
{
name: "valid selector",
cli: "123",
wants: DeleteOptions{
Selector: "123",
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := &cmdutil.Factory{}

argv, err := shlex.Split(tt.cli)
assert.NoError(t, err)
var gotOpts *DeleteOptions
cmd := NewCmdDelete(f, func(opts *DeleteOptions) error {
gotOpts = opts
return nil
})

cmd.SetArgs(argv)
cmd.SetIn(&bytes.Buffer{})
cmd.SetOut(&bytes.Buffer{})
cmd.SetErr(&bytes.Buffer{})

_, err = cmd.ExecuteC()
assert.NoError(t, err)

assert.Equal(t, tt.wants.Selector, gotOpts.Selector)
})
}
}

func Test_deleteRun(t *testing.T) {
tests := []struct {
name string
opts *DeleteOptions
gist *shared.Gist
httpStubs func(*httpmock.Registry)
askStubs func(*prompt.AskStubber)
nontty bool
wantErr bool
wantStderr string
wantParams map[string]interface{}
}{
{
name: "no such gist",
wantErr: true,
}, {
name: "another user's gist",
gist: &shared.Gist{
ID: "1234",
Files: map[string]*shared.GistFile{
"cicada.txt": {
Filename: "cicada.txt",
Content: "bwhiizzzbwhuiiizzzz",
Type: "text/plain",
},
},
Owner: &shared.GistOwner{Login: "octocat2"},
},
wantErr: true,
wantStderr: "You do not own this gist.",
}, {
name: "successfully delete",
gist: &shared.Gist{
ID: "1234",
Files: map[string]*shared.GistFile{
"cicada.txt": {
Filename: "cicada.txt",
Content: "bwhiizzzbwhuiiizzzz",
Type: "text/plain",
},
},
Owner: &shared.GistOwner{Login: "octocat"},
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("DELETE", "gists/1234"),
httpmock.StatusStringResponse(200, "{}"))
},
wantErr: false,
},
}

for _, tt := range tests {
reg := &httpmock.Registry{}
if tt.gist == nil {
reg.Register(httpmock.REST("GET", "gists/1234"),
httpmock.StatusStringResponse(404, "Not Found"))
} else {
reg.Register(httpmock.REST("GET", "gists/1234"),
httpmock.JSONResponse(tt.gist))
reg.Register(httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"octocat"}}}`))
}

if tt.httpStubs != nil {
tt.httpStubs(reg)
}

as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(as)
}

if tt.opts == nil {
tt.opts = &DeleteOptions{}
}

tt.opts.HttpClient = func() (*http.Client, error) {
return &http.Client{Transport: reg}, nil
}
io, _, _, _ := iostreams.Test()
io.SetStdoutTTY(!tt.nontty)
io.SetStdinTTY(!tt.nontty)
tt.opts.IO = io
tt.opts.Selector = "1234"

t.Run(tt.name, func(t *testing.T) {
err := deleteRun(tt.opts)
reg.Verify(t)
if tt.wantErr {
assert.Error(t, err)
if tt.wantStderr != "" {
assert.EqualError(t, err, tt.wantStderr)
}
return
}
assert.NoError(t, err)

})
}
}
2 changes: 2 additions & 0 deletions pkg/cmd/gist/gist.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gist
import (
"github.com/MakeNowJust/heredoc"
gistCreateCmd "github.com/cli/cli/pkg/cmd/gist/create"
gistDeleteCmd "github.com/cli/cli/pkg/cmd/gist/delete"
gistEditCmd "github.com/cli/cli/pkg/cmd/gist/edit"
gistListCmd "github.com/cli/cli/pkg/cmd/gist/list"
gistViewCmd "github.com/cli/cli/pkg/cmd/gist/view"
Expand All @@ -29,6 +30,7 @@ func NewCmdGist(f *cmdutil.Factory) *cobra.Command {
cmd.AddCommand(gistListCmd.NewCmdList(f, nil))
cmd.AddCommand(gistViewCmd.NewCmdView(f, nil))
cmd.AddCommand(gistEditCmd.NewCmdEdit(f, nil))
cmd.AddCommand(gistDeleteCmd.NewCmdDelete(f, nil))

return cmd
}

0 comments on commit 99574f8

Please sign in to comment.