shift gist validation to server rather than client

This commit is contained in:
Gowtham Munukutla 2021-05-04 18:50:27 +05:30 committed by Mislav Marohnić
parent 2f94adabb2
commit cc94dc762d
3 changed files with 83 additions and 12 deletions

View file

@ -153,6 +153,12 @@ func createRun(opts *CreateOptions) error {
if httpError.OAuthScopes != "" && !strings.Contains(httpError.OAuthScopes, "gist") {
return fmt.Errorf("This command requires the 'gist' OAuth scope.\nPlease re-authenticate by doing `gh config set -h github.com oauth_token ''` and running the command again.")
}
if httpError.StatusCode == http.StatusUnprocessableEntity {
if detectEmptyFiles(files) {
fmt.Fprintf(errOut, "%s Failed to create gist: %s", cs.FailureIcon(), "a gist file cannot be blank")
return cmdutil.SilentError
}
}
}
return fmt.Errorf("%s Failed to create gist: %w", cs.Red("X"), err)
}
@ -266,3 +272,12 @@ func createGist(client *http.Client, hostname, description string, public bool,
return &result, nil
}
func detectEmptyFiles(files map[string]*shared.GistFile) bool {
for _, file := range files {
if strings.TrimSpace(file.Content) == "" {
return true
}
}
return false
}

View file

@ -20,6 +20,7 @@ import (
const (
fixtureFile = "../fixture.txt"
emptyFile = "../empty.txt"
)
func Test_processFiles(t *testing.T) {
@ -165,14 +166,15 @@ func TestNewCmdCreate(t *testing.T) {
func Test_createRun(t *testing.T) {
tests := []struct {
name string
opts *CreateOptions
stdin string
wantOut string
wantStderr string
wantParams map[string]interface{}
wantErr bool
wantBrowse string
name string
opts *CreateOptions
stdin string
wantOut string
wantStderr string
wantParams map[string]interface{}
wantErr bool
wantBrowse string
responseStatus int
}{
{
name: "public",
@ -193,6 +195,7 @@ func Test_createRun(t *testing.T) {
},
},
},
responseStatus: http.StatusOK,
},
{
name: "with description",
@ -213,6 +216,7 @@ func Test_createRun(t *testing.T) {
},
},
},
responseStatus: http.StatusOK,
},
{
name: "multiple files",
@ -236,6 +240,25 @@ func Test_createRun(t *testing.T) {
},
},
},
responseStatus: http.StatusOK,
},
{
name: "file with empty content",
opts: &CreateOptions{
Filenames: []string{emptyFile},
},
wantOut: "",
wantStderr: "- Creating gist empty.txt\nX Failed to create gist: a gist file cannot be blank",
wantErr: true,
wantParams: map[string]interface{}{
"description": "",
"updated_at": "0001-01-01T00:00:00Z",
"public": false,
"files": map[string]interface{}{
"empty.txt": map[string]interface{}{},
},
},
responseStatus: http.StatusUnprocessableEntity,
},
{
name: "stdin arg",
@ -256,6 +279,7 @@ func Test_createRun(t *testing.T) {
},
},
},
responseStatus: http.StatusOK,
},
{
name: "web arg",
@ -277,14 +301,20 @@ func Test_createRun(t *testing.T) {
},
},
},
responseStatus: http.StatusOK,
},
}
for _, tt := range tests {
reg := &httpmock.Registry{}
reg.Register(httpmock.REST("POST", "gists"),
httpmock.JSONResponse(struct {
Html_url string
}{"https://gist.github.com/aa5a315d61ae9438b18d"}))
if tt.responseStatus == http.StatusUnprocessableEntity {
reg.Register(httpmock.REST("POST", "gists"),
httpmock.StatusStringResponse(http.StatusUnprocessableEntity, ""))
} else {
reg.Register(httpmock.REST("POST", "gists"),
httpmock.JSONResponse(struct {
Html_url string
}{"https://gist.github.com/aa5a315d61ae9438b18d"}))
}
mockClient := func() (*http.Client, error) {
return &http.Client{Transport: reg}, nil
@ -325,6 +355,32 @@ func Test_createRun(t *testing.T) {
}
}
func Test_detectEmptyFiles(t *testing.T) {
tests := []struct {
content string
isEmptyFile bool
}{
{
content: "{}",
isEmptyFile: false,
},
{
content: "\n\t",
isEmptyFile: true,
},
}
for _, tt := range tests {
files := map[string]*shared.GistFile{}
files["file"] = &shared.GistFile{
Content: tt.content,
}
isEmptyFile := detectEmptyFiles(files)
assert.Equal(t, tt.isEmptyFile, isEmptyFile)
}
}
func Test_CreateRun_reauth(t *testing.T) {
reg := &httpmock.Registry{}
reg.Register(httpmock.REST("POST", "gists"), func(req *http.Request) (*http.Response, error) {

0
pkg/cmd/gist/empty.txt Normal file
View file