satellite/console: Add graphql query for owned projects
Change-Id: If47183d46cb7552ecdddbb3e536c36d958fad6d0
This commit is contained in:
parent
c139cbd76b
commit
8263f18321
@ -19,6 +19,10 @@ const (
|
||||
ProjectInputType = "projectInput"
|
||||
// ProjectUsageType is a graphql type name for project usage.
|
||||
ProjectUsageType = "projectUsage"
|
||||
// ProjectsCursorInputType is a graphql input type name for projects cursor.
|
||||
ProjectsCursorInputType = "projectsCursor"
|
||||
// ProjectsPageType is a graphql type name for projects page.
|
||||
ProjectsPageType = "projectsPage"
|
||||
// BucketUsageCursorInputType is a graphql input
|
||||
// type name for bucket usage cursor.
|
||||
BucketUsageCursorInputType = "bucketUsageCursor"
|
||||
@ -62,6 +66,10 @@ const (
|
||||
FieldCurrentPage = "currentPage"
|
||||
// FieldTotalCount is a field name for bucket usage count total.
|
||||
FieldTotalCount = "totalCount"
|
||||
// FieldMemberCount is a field name for number of project members.
|
||||
FieldMemberCount = "memberCount"
|
||||
// FieldProjects is a field name for projects.
|
||||
FieldProjects = "projects"
|
||||
// FieldProjectMembers is a field name for project members.
|
||||
FieldProjectMembers = "projectMembers"
|
||||
// CursorArg is an argument name for cursor.
|
||||
@ -104,6 +112,9 @@ func graphqlProject(service *console.Service, types *TypeCreator) *graphql.Objec
|
||||
FieldCreatedAt: &graphql.Field{
|
||||
Type: graphql.DateTime,
|
||||
},
|
||||
FieldMemberCount: &graphql.Field{
|
||||
Type: graphql.Int,
|
||||
},
|
||||
FieldMembers: &graphql.Field{
|
||||
Type: types.projectMemberPage,
|
||||
Args: graphql.FieldConfigArgument{
|
||||
@ -255,6 +266,21 @@ func graphqlProjectInput() *graphql.InputObject {
|
||||
})
|
||||
}
|
||||
|
||||
// graphqlBucketUsageCursor creates bucket usage cursor graphql input type.
|
||||
func graphqlProjectsCursor() *graphql.InputObject {
|
||||
return graphql.NewInputObject(graphql.InputObjectConfig{
|
||||
Name: ProjectsCursorInputType,
|
||||
Fields: graphql.InputObjectConfigFieldMap{
|
||||
LimitArg: &graphql.InputObjectFieldConfig{
|
||||
Type: graphql.NewNonNull(graphql.Int),
|
||||
},
|
||||
PageArg: &graphql.InputObjectFieldConfig{
|
||||
Type: graphql.NewNonNull(graphql.Int),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// graphqlBucketUsageCursor creates bucket usage cursor graphql input type.
|
||||
func graphqlBucketUsageCursor() *graphql.InputObject {
|
||||
return graphql.NewInputObject(graphql.InputObjectConfig{
|
||||
@ -300,6 +326,33 @@ func graphqlBucketUsage() *graphql.Object {
|
||||
})
|
||||
}
|
||||
|
||||
// graphqlProjectsPage creates a projects page graphql object.
|
||||
func graphqlProjectsPage(types *TypeCreator) *graphql.Object {
|
||||
return graphql.NewObject(graphql.ObjectConfig{
|
||||
Name: ProjectsPageType,
|
||||
Fields: graphql.Fields{
|
||||
FieldProjects: &graphql.Field{
|
||||
Type: graphql.NewList(types.project),
|
||||
},
|
||||
LimitArg: &graphql.Field{
|
||||
Type: graphql.Int,
|
||||
},
|
||||
OffsetArg: &graphql.Field{
|
||||
Type: graphql.Int,
|
||||
},
|
||||
FieldPageCount: &graphql.Field{
|
||||
Type: graphql.Int,
|
||||
},
|
||||
FieldCurrentPage: &graphql.Field{
|
||||
Type: graphql.Int,
|
||||
},
|
||||
FieldTotalCount: &graphql.Field{
|
||||
Type: graphql.Int,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// graphqlBucketUsagePage creates bucket usage page graphql object.
|
||||
func graphqlBucketUsagePage(types *TypeCreator) *graphql.Object {
|
||||
return graphql.NewObject(graphql.ObjectConfig{
|
||||
@ -362,7 +415,14 @@ func fromMapProjectInfo(args map[string]interface{}) (project console.ProjectInf
|
||||
return
|
||||
}
|
||||
|
||||
// fromMapBucketUsageCursor creates console.BucketUsageCursor from input args.
|
||||
// fromMapProjectsCursor creates console.ProjectsCursor from input args.
|
||||
func fromMapProjectsCursor(args map[string]interface{}) (cursor console.ProjectsCursor) {
|
||||
cursor.Limit = args[LimitArg].(int)
|
||||
cursor.Page = args[PageArg].(int)
|
||||
return
|
||||
}
|
||||
|
||||
// fromMapBucketUsageCursor creates accounting.BucketUsageCursor from input args.
|
||||
func fromMapBucketUsageCursor(args map[string]interface{}) (cursor accounting.BucketUsageCursor) {
|
||||
limit, _ := args[LimitArg].(int)
|
||||
page, _ := args[PageArg].(int)
|
||||
|
@ -17,6 +17,8 @@ const (
|
||||
Query = "query"
|
||||
// ProjectQuery is a query name for project.
|
||||
ProjectQuery = "project"
|
||||
// OwnedProjectsQuery is a query name for projects owned by an account.
|
||||
OwnedProjectsQuery = "ownedProjects"
|
||||
// MyProjectsQuery is a query name for projects related to account.
|
||||
MyProjectsQuery = "myProjects"
|
||||
// ActiveRewardQuery is a query name for current active reward offer.
|
||||
@ -53,6 +55,19 @@ func rootQuery(service *console.Service, mailService *mailservice.Service, types
|
||||
return project, nil
|
||||
},
|
||||
},
|
||||
OwnedProjectsQuery: &graphql.Field{
|
||||
Type: types.projectsPage,
|
||||
Args: graphql.FieldConfigArgument{
|
||||
CursorArg: &graphql.ArgumentConfig{
|
||||
Type: graphql.NewNonNull(types.projectsCursor),
|
||||
},
|
||||
},
|
||||
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
||||
cursor := fromMapProjectsCursor(p.Args[CursorArg].(map[string]interface{}))
|
||||
page, err := service.GetUsersOwnedProjectsPage(p.Context, cursor)
|
||||
return page, err
|
||||
},
|
||||
},
|
||||
MyProjectsQuery: &graphql.Field{
|
||||
Type: graphql.NewList(types.project),
|
||||
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
||||
|
@ -409,6 +409,59 @@ func TestGraphqlQuery(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
assert.True(t, foundProj1)
|
||||
assert.True(t, foundProj2)
|
||||
})
|
||||
t.Run("OwnedProjects query", func(t *testing.T) {
|
||||
query := fmt.Sprintf(
|
||||
"query {ownedProjects( cursor: { limit: %d, page: %d } ) {projects{id, name, ownerId, description, createdAt, memberCount}, limit, offset, pageCount, currentPage, totalCount } }",
|
||||
5,
|
||||
1,
|
||||
)
|
||||
|
||||
result := testQuery(t, query)
|
||||
|
||||
data := result.(map[string]interface{})
|
||||
projectsPage := data[consoleql.OwnedProjectsQuery].(map[string]interface{})
|
||||
|
||||
projectsList := projectsPage[consoleql.FieldProjects].([]interface{})
|
||||
assert.Len(t, projectsList, 2)
|
||||
|
||||
assert.EqualValues(t, 1, projectsPage[consoleql.FieldCurrentPage])
|
||||
assert.EqualValues(t, 0, projectsPage[consoleql.OffsetArg])
|
||||
assert.EqualValues(t, 5, projectsPage[consoleql.LimitArg])
|
||||
assert.EqualValues(t, 1, projectsPage[consoleql.FieldPageCount])
|
||||
assert.EqualValues(t, 2, projectsPage[consoleql.FieldTotalCount])
|
||||
|
||||
testProject := func(t *testing.T, actual map[string]interface{}, expected *console.Project, expectedNumMembers int) {
|
||||
assert.Equal(t, expected.Name, actual[consoleql.FieldName])
|
||||
assert.Equal(t, expected.Description, actual[consoleql.FieldDescription])
|
||||
|
||||
createdAt := time.Time{}
|
||||
err := createdAt.UnmarshalText([]byte(actual[consoleql.FieldCreatedAt].(string)))
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, expected.CreatedAt.Equal(createdAt))
|
||||
|
||||
assert.EqualValues(t, expectedNumMembers, actual[consoleql.FieldMemberCount])
|
||||
}
|
||||
|
||||
var foundProj1, foundProj2 bool
|
||||
|
||||
for _, entry := range projectsList {
|
||||
project := entry.(map[string]interface{})
|
||||
|
||||
id := project[consoleql.FieldID].(string)
|
||||
switch id {
|
||||
case createdProject.ID.String():
|
||||
foundProj1 = true
|
||||
testProject(t, project, createdProject, 3)
|
||||
case project2.ID.String():
|
||||
foundProj2 = true
|
||||
testProject(t, project, project2, 1)
|
||||
}
|
||||
}
|
||||
|
||||
assert.True(t, foundProj1)
|
||||
assert.True(t, foundProj2)
|
||||
})
|
||||
|
@ -21,6 +21,7 @@ type TypeCreator struct {
|
||||
creditUsage *graphql.Object
|
||||
project *graphql.Object
|
||||
projectUsage *graphql.Object
|
||||
projectsPage *graphql.Object
|
||||
bucketUsage *graphql.Object
|
||||
bucketUsagePage *graphql.Object
|
||||
projectMember *graphql.Object
|
||||
@ -31,6 +32,7 @@ type TypeCreator struct {
|
||||
|
||||
userInput *graphql.InputObject
|
||||
projectInput *graphql.InputObject
|
||||
projectsCursor *graphql.InputObject
|
||||
bucketUsageCursor *graphql.InputObject
|
||||
projectMembersCursor *graphql.InputObject
|
||||
apiKeysCursor *graphql.InputObject
|
||||
@ -125,6 +127,16 @@ func (c *TypeCreator) Create(log *zap.Logger, service *console.Service, mailServ
|
||||
return err
|
||||
}
|
||||
|
||||
c.projectsCursor = graphqlProjectsCursor()
|
||||
if err := c.projectsCursor.Error(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.projectsPage = graphqlProjectsPage(c)
|
||||
if err := c.projectsPage.Error(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// root objects
|
||||
c.query = rootQuery(service, mailService, c)
|
||||
if err := c.query.Error(); err != nil {
|
||||
|
@ -988,6 +988,22 @@ func (s *Service) GetUsersProjects(ctx context.Context) (ps []Project, err error
|
||||
return
|
||||
}
|
||||
|
||||
// GetUsersOwnedProjectsPage is a method for querying paged projects.
|
||||
func (s *Service) GetUsersOwnedProjectsPage(ctx context.Context, cursor ProjectsCursor) (_ ProjectsPage, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
auth, err := s.getAuthAndAuditLog(ctx, "get user's owned projects page")
|
||||
if err != nil {
|
||||
return ProjectsPage{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
projects, err := s.store.Projects().ListByOwnerID(ctx, auth.User.ID, cursor)
|
||||
if err != nil {
|
||||
return ProjectsPage{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
// GetCurrentRewardByType is a method for querying current active reward offer based on its type.
|
||||
func (s *Service) GetCurrentRewardByType(ctx context.Context, offerType rewards.OfferType) (offer *rewards.Offer, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
Loading…
Reference in New Issue
Block a user