* Use standard JSON flags for project command Deprecates the --format flag and adds the standard JSON flags to properly filter, template, and write JSON. * Add format flags cmdutil Resolves PR feedback * Remove unnecessary fields from JSON format flags * Add standard format help to remaining commands * Add JSON format regression tests Also fixed a number of `project` commands that didn't format the right object as JSON. * Resolve PR feedback
726 lines
16 KiB
Go
726 lines
16 KiB
Go
package fieldcreate
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/cli/cli/v2/pkg/cmd/project/shared/queries"
|
|
"github.com/cli/cli/v2/pkg/cmdutil"
|
|
"github.com/cli/cli/v2/pkg/iostreams"
|
|
"github.com/google/shlex"
|
|
"github.com/stretchr/testify/assert"
|
|
"gopkg.in/h2non/gock.v1"
|
|
)
|
|
|
|
func TestNewCmdCreateField(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cli string
|
|
wants createFieldOpts
|
|
wantsErr bool
|
|
wantsErrMsg string
|
|
wantsExporter bool
|
|
}{
|
|
{
|
|
name: "missing-name-and-data-type",
|
|
cli: "",
|
|
wantsErr: true,
|
|
wantsErrMsg: "required flag(s) \"data-type\", \"name\" not set",
|
|
},
|
|
{
|
|
name: "not-a-number",
|
|
cli: "x --name n --data-type TEXT",
|
|
wantsErr: true,
|
|
wantsErrMsg: "invalid number: x",
|
|
},
|
|
{
|
|
name: "single-select-no-options",
|
|
cli: "123 --name n --data-type SINGLE_SELECT",
|
|
wantsErr: true,
|
|
wantsErrMsg: "passing `--single-select-options` is required for SINGLE_SELECT data type",
|
|
},
|
|
{
|
|
name: "number",
|
|
cli: "123 --name n --data-type TEXT",
|
|
wants: createFieldOpts{
|
|
number: 123,
|
|
name: "n",
|
|
dataType: "TEXT",
|
|
singleSelectOptions: []string{},
|
|
},
|
|
},
|
|
{
|
|
name: "owner",
|
|
cli: "--owner monalisa --name n --data-type TEXT",
|
|
wants: createFieldOpts{
|
|
owner: "monalisa",
|
|
name: "n",
|
|
dataType: "TEXT",
|
|
singleSelectOptions: []string{},
|
|
},
|
|
},
|
|
{
|
|
name: "single-select-options",
|
|
cli: "--name n --data-type TEXT --single-select-options a,b",
|
|
wants: createFieldOpts{
|
|
singleSelectOptions: []string{"a", "b"},
|
|
name: "n",
|
|
dataType: "TEXT",
|
|
},
|
|
},
|
|
{
|
|
name: "json",
|
|
cli: "--format json --name n --data-type TEXT ",
|
|
wants: createFieldOpts{
|
|
name: "n",
|
|
dataType: "TEXT",
|
|
singleSelectOptions: []string{},
|
|
},
|
|
wantsExporter: true,
|
|
},
|
|
}
|
|
|
|
t.Setenv("GH_TOKEN", "auth-token")
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ios, _, _, _ := iostreams.Test()
|
|
f := &cmdutil.Factory{
|
|
IOStreams: ios,
|
|
}
|
|
|
|
argv, err := shlex.Split(tt.cli)
|
|
assert.NoError(t, err)
|
|
|
|
var gotOpts createFieldOpts
|
|
cmd := NewCmdCreateField(f, func(config createFieldConfig) error {
|
|
gotOpts = config.opts
|
|
return nil
|
|
})
|
|
|
|
cmd.SetArgs(argv)
|
|
_, err = cmd.ExecuteC()
|
|
if tt.wantsErr {
|
|
assert.Error(t, err)
|
|
assert.Equal(t, tt.wantsErrMsg, err.Error())
|
|
return
|
|
}
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, tt.wants.number, gotOpts.number)
|
|
assert.Equal(t, tt.wants.owner, gotOpts.owner)
|
|
assert.Equal(t, tt.wants.name, gotOpts.name)
|
|
assert.Equal(t, tt.wants.dataType, gotOpts.dataType)
|
|
assert.Equal(t, tt.wants.singleSelectOptions, gotOpts.singleSelectOptions)
|
|
assert.Equal(t, tt.wantsExporter, gotOpts.exporter != nil)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRunCreateField_User(t *testing.T) {
|
|
defer gock.Off()
|
|
gock.Observe(gock.DumpRequest)
|
|
|
|
// get user ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query UserOrgOwner.*",
|
|
"variables": map[string]interface{}{
|
|
"login": "monalisa",
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"user": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
"errors": []interface{}{
|
|
map[string]interface{}{
|
|
"type": "NOT_FOUND",
|
|
"path": []string{"organization"},
|
|
},
|
|
},
|
|
})
|
|
|
|
// get project ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query UserProject.*",
|
|
"variables": map[string]interface{}{
|
|
"login": "monalisa",
|
|
"number": 1,
|
|
"firstItems": 0,
|
|
"afterItems": nil,
|
|
"firstFields": 0,
|
|
"afterFields": nil,
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"user": map[string]interface{}{
|
|
"projectV2": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
// create Field
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
BodyString(`{"query":"mutation CreateField.*","variables":{"input":{"projectId":"an ID","dataType":"TEXT","name":"a name"}}}`).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"createProjectV2Field": map[string]interface{}{
|
|
"projectV2Field": map[string]interface{}{
|
|
"id": "Field ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
client := queries.NewTestClient()
|
|
|
|
ios, _, stdout, _ := iostreams.Test()
|
|
ios.SetStdoutTTY(true)
|
|
config := createFieldConfig{
|
|
opts: createFieldOpts{
|
|
name: "a name",
|
|
owner: "monalisa",
|
|
number: 1,
|
|
dataType: "TEXT",
|
|
},
|
|
client: client,
|
|
io: ios,
|
|
}
|
|
|
|
err := runCreateField(config)
|
|
assert.NoError(t, err)
|
|
assert.Equal(
|
|
t,
|
|
"Created field\n",
|
|
stdout.String())
|
|
}
|
|
|
|
func TestRunCreateField_Org(t *testing.T) {
|
|
defer gock.Off()
|
|
gock.Observe(gock.DumpRequest)
|
|
|
|
// get org ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query UserOrgOwner.*",
|
|
"variables": map[string]interface{}{
|
|
"login": "github",
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"organization": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
"errors": []interface{}{
|
|
map[string]interface{}{
|
|
"type": "NOT_FOUND",
|
|
"path": []string{"user"},
|
|
},
|
|
},
|
|
})
|
|
|
|
// get project ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query OrgProject.*",
|
|
"variables": map[string]interface{}{
|
|
"login": "github",
|
|
"number": 1,
|
|
"firstItems": 0,
|
|
"afterItems": nil,
|
|
"firstFields": 0,
|
|
"afterFields": nil,
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"organization": map[string]interface{}{
|
|
"projectV2": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
// create Field
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
BodyString(`{"query":"mutation CreateField.*","variables":{"input":{"projectId":"an ID","dataType":"TEXT","name":"a name"}}}`).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"createProjectV2Field": map[string]interface{}{
|
|
"projectV2Field": map[string]interface{}{
|
|
"id": "Field ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
client := queries.NewTestClient()
|
|
|
|
ios, _, stdout, _ := iostreams.Test()
|
|
ios.SetStdoutTTY(true)
|
|
config := createFieldConfig{
|
|
opts: createFieldOpts{
|
|
name: "a name",
|
|
owner: "github",
|
|
number: 1,
|
|
dataType: "TEXT",
|
|
},
|
|
client: client,
|
|
io: ios,
|
|
}
|
|
|
|
err := runCreateField(config)
|
|
assert.NoError(t, err)
|
|
assert.Equal(
|
|
t,
|
|
"Created field\n",
|
|
stdout.String())
|
|
}
|
|
|
|
func TestRunCreateField_Me(t *testing.T) {
|
|
defer gock.Off()
|
|
gock.Observe(gock.DumpRequest)
|
|
// get viewer ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query ViewerOwner.*",
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"viewer": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
})
|
|
|
|
// get project ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query ViewerProject.*",
|
|
"variables": map[string]interface{}{
|
|
"number": 1,
|
|
"firstItems": 0,
|
|
"afterItems": nil,
|
|
"firstFields": 0,
|
|
"afterFields": nil,
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"viewer": map[string]interface{}{
|
|
"projectV2": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
// create Field
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
BodyString(`{"query":"mutation CreateField.*","variables":{"input":{"projectId":"an ID","dataType":"TEXT","name":"a name"}}}`).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"createProjectV2Field": map[string]interface{}{
|
|
"projectV2Field": map[string]interface{}{
|
|
"id": "Field ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
client := queries.NewTestClient()
|
|
|
|
ios, _, stdout, _ := iostreams.Test()
|
|
ios.SetStdoutTTY(true)
|
|
config := createFieldConfig{
|
|
opts: createFieldOpts{
|
|
owner: "@me",
|
|
number: 1,
|
|
name: "a name",
|
|
dataType: "TEXT",
|
|
},
|
|
client: client,
|
|
io: ios,
|
|
}
|
|
|
|
err := runCreateField(config)
|
|
assert.NoError(t, err)
|
|
assert.Equal(
|
|
t,
|
|
"Created field\n",
|
|
stdout.String())
|
|
}
|
|
|
|
func TestRunCreateField_TEXT(t *testing.T) {
|
|
defer gock.Off()
|
|
gock.Observe(gock.DumpRequest)
|
|
// get viewer ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query ViewerOwner.*",
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"viewer": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
})
|
|
|
|
// get project ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query ViewerProject.*",
|
|
"variables": map[string]interface{}{
|
|
"number": 1,
|
|
"firstItems": 0,
|
|
"afterItems": nil,
|
|
"firstFields": 0,
|
|
"afterFields": nil,
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"viewer": map[string]interface{}{
|
|
"projectV2": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
// create Field
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
BodyString(`{"query":"mutation CreateField.*","variables":{"input":{"projectId":"an ID","dataType":"TEXT","name":"a name"}}}`).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"createProjectV2Field": map[string]interface{}{
|
|
"projectV2Field": map[string]interface{}{
|
|
"id": "Field ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
client := queries.NewTestClient()
|
|
|
|
ios, _, stdout, _ := iostreams.Test()
|
|
ios.SetStdoutTTY(true)
|
|
config := createFieldConfig{
|
|
opts: createFieldOpts{
|
|
owner: "@me",
|
|
number: 1,
|
|
name: "a name",
|
|
dataType: "TEXT",
|
|
},
|
|
client: client,
|
|
io: ios,
|
|
}
|
|
|
|
err := runCreateField(config)
|
|
assert.NoError(t, err)
|
|
assert.Equal(
|
|
t,
|
|
"Created field\n",
|
|
stdout.String())
|
|
}
|
|
|
|
func TestRunCreateField_DATE(t *testing.T) {
|
|
defer gock.Off()
|
|
gock.Observe(gock.DumpRequest)
|
|
// get viewer ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query ViewerOwner.*",
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"viewer": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
})
|
|
|
|
// get project ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query ViewerProject.*",
|
|
"variables": map[string]interface{}{
|
|
"number": 1,
|
|
"firstItems": 0,
|
|
"afterItems": nil,
|
|
"firstFields": 0,
|
|
"afterFields": nil,
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"viewer": map[string]interface{}{
|
|
"projectV2": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
// create Field
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
BodyString(`{"query":"mutation CreateField.*","variables":{"input":{"projectId":"an ID","dataType":"DATE","name":"a name"}}}`).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"createProjectV2Field": map[string]interface{}{
|
|
"projectV2Field": map[string]interface{}{
|
|
"id": "Field ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
client := queries.NewTestClient()
|
|
|
|
ios, _, stdout, _ := iostreams.Test()
|
|
ios.SetStdoutTTY(true)
|
|
config := createFieldConfig{
|
|
opts: createFieldOpts{
|
|
owner: "@me",
|
|
number: 1,
|
|
name: "a name",
|
|
dataType: "DATE",
|
|
},
|
|
client: client,
|
|
io: ios,
|
|
}
|
|
|
|
err := runCreateField(config)
|
|
assert.NoError(t, err)
|
|
assert.Equal(
|
|
t,
|
|
"Created field\n",
|
|
stdout.String())
|
|
}
|
|
|
|
func TestRunCreateField_NUMBER(t *testing.T) {
|
|
defer gock.Off()
|
|
gock.Observe(gock.DumpRequest)
|
|
// get viewer ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query ViewerOwner.*",
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"viewer": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
})
|
|
|
|
// get project ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query ViewerProject.*",
|
|
"variables": map[string]interface{}{
|
|
"number": 1,
|
|
"firstItems": 0,
|
|
"afterItems": nil,
|
|
"firstFields": 0,
|
|
"afterFields": nil,
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"viewer": map[string]interface{}{
|
|
"projectV2": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
// create Field
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
BodyString(`{"query":"mutation CreateField.*","variables":{"input":{"projectId":"an ID","dataType":"NUMBER","name":"a name"}}}`).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"createProjectV2Field": map[string]interface{}{
|
|
"projectV2Field": map[string]interface{}{
|
|
"id": "Field ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
client := queries.NewTestClient()
|
|
|
|
ios, _, stdout, _ := iostreams.Test()
|
|
ios.SetStdoutTTY(true)
|
|
config := createFieldConfig{
|
|
opts: createFieldOpts{
|
|
owner: "@me",
|
|
number: 1,
|
|
name: "a name",
|
|
dataType: "NUMBER",
|
|
},
|
|
client: client,
|
|
io: ios,
|
|
}
|
|
|
|
err := runCreateField(config)
|
|
assert.NoError(t, err)
|
|
assert.Equal(
|
|
t,
|
|
"Created field\n",
|
|
stdout.String())
|
|
}
|
|
|
|
func TestRunCreateField_JSON(t *testing.T) {
|
|
defer gock.Off()
|
|
gock.Observe(gock.DumpRequest)
|
|
|
|
// get user ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query UserOrgOwner.*",
|
|
"variables": map[string]interface{}{
|
|
"login": "monalisa",
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"user": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
"errors": []interface{}{
|
|
map[string]interface{}{
|
|
"type": "NOT_FOUND",
|
|
"path": []string{"organization"},
|
|
},
|
|
},
|
|
})
|
|
|
|
// get project ID
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
MatchType("json").
|
|
JSON(map[string]interface{}{
|
|
"query": "query UserProject.*",
|
|
"variables": map[string]interface{}{
|
|
"login": "monalisa",
|
|
"number": 1,
|
|
"firstItems": 0,
|
|
"afterItems": nil,
|
|
"firstFields": 0,
|
|
"afterFields": nil,
|
|
},
|
|
}).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"user": map[string]interface{}{
|
|
"projectV2": map[string]interface{}{
|
|
"id": "an ID",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
// create Field
|
|
gock.New("https://api.github.com").
|
|
Post("/graphql").
|
|
BodyString(`{"query":"mutation CreateField.*","variables":{"input":{"projectId":"an ID","dataType":"TEXT","name":"a name"}}}`).
|
|
Reply(200).
|
|
JSON(map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"createProjectV2Field": map[string]interface{}{
|
|
"projectV2Field": map[string]interface{}{
|
|
"__typename": "ProjectV2Field",
|
|
"id": "Field ID",
|
|
"name": "a name",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
client := queries.NewTestClient()
|
|
|
|
ios, _, stdout, _ := iostreams.Test()
|
|
config := createFieldConfig{
|
|
opts: createFieldOpts{
|
|
name: "a name",
|
|
owner: "monalisa",
|
|
number: 1,
|
|
dataType: "TEXT",
|
|
exporter: cmdutil.NewJSONExporter(),
|
|
},
|
|
client: client,
|
|
io: ios,
|
|
}
|
|
|
|
err := runCreateField(config)
|
|
assert.NoError(t, err)
|
|
assert.JSONEq(
|
|
t,
|
|
`{"id":"Field ID","name":"a name","type":"ProjectV2Field"}`,
|
|
stdout.String())
|
|
}
|