package queries import ( "reflect" "testing" "github.com/stretchr/testify/assert" "gopkg.in/h2non/gock.v1" ) func TestProjectItems_DefaultLimit(t *testing.T) { defer gock.Off() gock.Observe(gock.DumpRequest) // list project items gock.New("https://api.github.com"). Post("/graphql"). JSON(map[string]interface{}{ "query": "query UserProjectWithItems.*", "variables": map[string]interface{}{ "firstItems": LimitMax, "afterItems": nil, "firstFields": LimitMax, "afterFields": nil, "login": "monalisa", "number": 1, }, }). Reply(200). JSON(map[string]interface{}{ "data": map[string]interface{}{ "user": map[string]interface{}{ "projectV2": map[string]interface{}{ "items": map[string]interface{}{ "nodes": []map[string]interface{}{ { "id": "issue ID", }, { "id": "pull request ID", }, { "id": "draft issue ID", }, }, }, }, }, }, }) client := NewTestClient() owner := &Owner{ Type: "USER", Login: "monalisa", ID: "user ID", } project, err := client.ProjectItems(owner, 1, LimitMax) assert.NoError(t, err) assert.Len(t, project.Items.Nodes, 3) } func TestProjectItems_LowerLimit(t *testing.T) { defer gock.Off() gock.Observe(gock.DumpRequest) // list project items gock.New("https://api.github.com"). Post("/graphql"). JSON(map[string]interface{}{ "query": "query UserProjectWithItems.*", "variables": map[string]interface{}{ "firstItems": 2, "afterItems": nil, "firstFields": LimitMax, "afterFields": nil, "login": "monalisa", "number": 1, }, }). Reply(200). JSON(map[string]interface{}{ "data": map[string]interface{}{ "user": map[string]interface{}{ "projectV2": map[string]interface{}{ "items": map[string]interface{}{ "nodes": []map[string]interface{}{ { "id": "issue ID", }, { "id": "pull request ID", }, }, }, }, }, }, }) client := NewTestClient() owner := &Owner{ Type: "USER", Login: "monalisa", ID: "user ID", } project, err := client.ProjectItems(owner, 1, 2) assert.NoError(t, err) assert.Len(t, project.Items.Nodes, 2) } func TestProjectItems_NoLimit(t *testing.T) { defer gock.Off() gock.Observe(gock.DumpRequest) // list project items gock.New("https://api.github.com"). Post("/graphql"). JSON(map[string]interface{}{ "query": "query UserProjectWithItems.*", "variables": map[string]interface{}{ "firstItems": LimitDefault, "afterItems": nil, "firstFields": LimitMax, "afterFields": nil, "login": "monalisa", "number": 1, }, }). Reply(200). JSON(map[string]interface{}{ "data": map[string]interface{}{ "user": map[string]interface{}{ "projectV2": map[string]interface{}{ "items": map[string]interface{}{ "nodes": []map[string]interface{}{ { "id": "issue ID", }, { "id": "pull request ID", }, { "id": "draft issue ID", }, }, }, }, }, }, }) client := NewTestClient() owner := &Owner{ Type: "USER", Login: "monalisa", ID: "user ID", } project, err := client.ProjectItems(owner, 1, 0) assert.NoError(t, err) assert.Len(t, project.Items.Nodes, 3) } func TestProjectFields_LowerLimit(t *testing.T) { defer gock.Off() gock.Observe(gock.DumpRequest) // list project fields gock.New("https://api.github.com"). Post("/graphql"). JSON(map[string]interface{}{ "query": "query UserProject.*", "variables": map[string]interface{}{ "login": "monalisa", "number": 1, "firstItems": LimitMax, "afterItems": nil, "firstFields": 2, "afterFields": nil, }, }). Reply(200). JSON(map[string]interface{}{ "data": map[string]interface{}{ "user": map[string]interface{}{ "projectV2": map[string]interface{}{ "fields": map[string]interface{}{ "nodes": []map[string]interface{}{ { "id": "field ID", }, { "id": "status ID", }, }, }, }, }, }, }) client := NewTestClient() owner := &Owner{ Type: "USER", Login: "monalisa", ID: "user ID", } project, err := client.ProjectFields(owner, 1, 2) assert.NoError(t, err) assert.Len(t, project.Fields.Nodes, 2) } func TestProjectFields_DefaultLimit(t *testing.T) { defer gock.Off() gock.Observe(gock.DumpRequest) // list project fields // list project fields gock.New("https://api.github.com"). Post("/graphql"). JSON(map[string]interface{}{ "query": "query UserProject.*", "variables": map[string]interface{}{ "login": "monalisa", "number": 1, "firstItems": LimitMax, "afterItems": nil, "firstFields": LimitMax, "afterFields": nil, }, }). Reply(200). JSON(map[string]interface{}{ "data": map[string]interface{}{ "user": map[string]interface{}{ "projectV2": map[string]interface{}{ "fields": map[string]interface{}{ "nodes": []map[string]interface{}{ { "id": "field ID", }, { "id": "status ID", }, { "id": "iteration ID", }, }, }, }, }, }, }) client := NewTestClient() owner := &Owner{ Type: "USER", Login: "monalisa", ID: "user ID", } project, err := client.ProjectFields(owner, 1, LimitMax) assert.NoError(t, err) assert.Len(t, project.Fields.Nodes, 3) } func TestProjectFields_NoLimit(t *testing.T) { defer gock.Off() gock.Observe(gock.DumpRequest) // list project fields gock.New("https://api.github.com"). Post("/graphql"). JSON(map[string]interface{}{ "query": "query UserProject.*", "variables": map[string]interface{}{ "login": "monalisa", "number": 1, "firstItems": LimitMax, "afterItems": nil, "firstFields": LimitDefault, "afterFields": nil, }, }). Reply(200). JSON(map[string]interface{}{ "data": map[string]interface{}{ "user": map[string]interface{}{ "projectV2": map[string]interface{}{ "fields": map[string]interface{}{ "nodes": []map[string]interface{}{ { "id": "field ID", }, { "id": "status ID", }, { "id": "iteration ID", }, }, }, }, }, }, }) client := NewTestClient() owner := &Owner{ Type: "USER", Login: "monalisa", ID: "user ID", } project, err := client.ProjectFields(owner, 1, 0) assert.NoError(t, err) assert.Len(t, project.Fields.Nodes, 3) } func Test_requiredScopesFromServerMessage(t *testing.T) { tests := []struct { name string msg string want []string }{ { name: "no scopes", msg: "SERVER OOPSIE", want: []string(nil), }, { name: "one scope", msg: "Your token has not been granted the required scopes to execute this query. The 'dataType' field requires one of the following scopes: ['read:project'], but your token has only been granted the: ['codespace', repo'] scopes. Please modify your token's scopes at: https://github.com/settings/tokens.", want: []string{"read:project"}, }, { name: "multiple scopes", msg: "Your token has not been granted the required scopes to execute this query. The 'dataType' field requires one of the following scopes: ['read:project', 'read:discussion', 'codespace'], but your token has only been granted the: [repo'] scopes. Please modify your token's scopes at: https://github.com/settings/tokens.", want: []string{"read:project", "read:discussion", "codespace"}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := requiredScopesFromServerMessage(tt.msg); !reflect.DeepEqual(got, tt.want) { t.Errorf("requiredScopesFromServerMessage() = %v, want %v", got, tt.want) } }) } } func TestNewProject_nonTTY(t *testing.T) { client := NewTestClient() _, err := client.NewProject(false, &Owner{}, 0, false) assert.EqualError(t, err, "project number is required when not running interactively") } func TestNewOwner_nonTTY(t *testing.T) { client := NewTestClient() _, err := client.NewOwner(false, "") assert.EqualError(t, err, "owner is required when not running interactively") } func TestProjectItems_FieldTitle(t *testing.T) { defer gock.Off() gock.Observe(gock.DumpRequest) // list project items gock.New("https://api.github.com"). Post("/graphql"). JSON(map[string]interface{}{ "query": "query UserProjectWithItems.*", "variables": map[string]interface{}{ "firstItems": LimitMax, "afterItems": nil, "firstFields": LimitMax, "afterFields": nil, "login": "monalisa", "number": 1, }, }). Reply(200). JSON(map[string]interface{}{ "data": map[string]interface{}{ "user": map[string]interface{}{ "projectV2": map[string]interface{}{ "items": map[string]interface{}{ "nodes": []map[string]interface{}{ { "id": "draft issue ID", "fieldValues": map[string]interface{}{ "nodes": []map[string]interface{}{ { "__typename": "ProjectV2ItemFieldIterationValue", "title": "Iteration Title 1", "iterationId": "iterationId1", }, { "__typename": "ProjectV2ItemFieldMilestoneValue", "milestone": map[string]interface{}{ "title": "Milestone Title 1", }, }, }, }, }, }, }, }, }, }, }) client := NewTestClient() owner := &Owner{ Type: "USER", Login: "monalisa", ID: "user ID", } project, err := client.ProjectItems(owner, 1, LimitMax) assert.NoError(t, err) assert.Len(t, project.Items.Nodes, 1) assert.Len(t, project.Items.Nodes[0].FieldValues.Nodes, 2) assert.Equal(t, project.Items.Nodes[0].FieldValues.Nodes[0].ProjectV2ItemFieldIterationValue.Title, "Iteration Title 1") assert.Equal(t, project.Items.Nodes[0].FieldValues.Nodes[0].ProjectV2ItemFieldIterationValue.IterationId, "iterationId1") assert.Equal(t, project.Items.Nodes[0].FieldValues.Nodes[1].ProjectV2ItemFieldMilestoneValue.Milestone.Title, "Milestone Title 1") } func TestCamelCase(t *testing.T) { assert.Equal(t, "camelCase", camelCase("camelCase")) assert.Equal(t, "camelCase", camelCase("CamelCase")) assert.Equal(t, "c", camelCase("C")) assert.Equal(t, "", camelCase("")) }