satellite project members pagination api (#907)

* satellite project members pagination api

* rename GetByProjectIDPaged to GetByProjectID

* add comment to max limit
This commit is contained in:
Yaroslav Vorobiov 2018-12-19 15:03:12 +02:00 committed by GitHub
parent bbe1dbb92c
commit 76018231c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 67 deletions

View File

@ -14,10 +14,8 @@ import (
type ProjectMembers interface {
// GetByMemberID is a method for querying project member from the database by memberID.
GetByMemberID(ctx context.Context, memberID uuid.UUID) (*ProjectMember, error)
// GetByProjectID is a method for querying project members from the database by projectID.
GetByProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error)
// GetByProjectIDPaged is a method for querying project members from the database by projectID, offset and limit.
GetByProjectIDPaged(ctx context.Context, projectID uuid.UUID, limit, offset int64) ([]ProjectMember, error)
// GetByProjectID is a method for querying project members from the database by projectID, offset and limit.
GetByProjectID(ctx context.Context, projectID uuid.UUID, limit int, offset int64) ([]ProjectMember, error)
// Insert is a method for inserting project member into the database.
Insert(ctx context.Context, memberID, projectID uuid.UUID) (*ProjectMember, error)
// Delete is a method for deleting project member by memberID and projectID from the database.

View File

@ -29,22 +29,12 @@ func (pm *projectMembers) GetByMemberID(ctx context.Context, memberID uuid.UUID)
return projectMemberFromDBX(projectMemberDbx)
}
// GetByProjectID is a method for querying project members from the database by projectID.
func (pm *projectMembers) GetByProjectID(ctx context.Context, projectID uuid.UUID) ([]satellite.ProjectMember, error) {
projectMembersDbx, err := pm.db.All_ProjectMember_By_ProjectId(ctx, dbx.ProjectMember_ProjectId(projectID[:]))
if err != nil {
return nil, err
}
return projectMembersFromDbxSlice(projectMembersDbx)
}
// GetByProjectIDPaged is a method for querying project members from the database by projectID, offset and limit.
func (pm *projectMembers) GetByProjectIDPaged(ctx context.Context, projectID uuid.UUID, limit, offset int64) ([]satellite.ProjectMember, error) {
// GetByProjectID is a method for querying project members from the database by projectID, offset and limit.
func (pm *projectMembers) GetByProjectID(ctx context.Context, projectID uuid.UUID, limit int, offset int64) ([]satellite.ProjectMember, error) {
projectMembersDbx, err := pm.db.Limited_ProjectMember_By_ProjectId(
ctx,
dbx.ProjectMember_ProjectId(projectID[:]),
int(limit),
limit,
offset)
if err != nil {

View File

@ -76,19 +76,19 @@ func TestProjectMembersRepository(t *testing.T) {
})
t.Run("Get paged", func(t *testing.T) {
members, err := projectMembers.GetByProjectIDPaged(ctx, createdProjects[0].ID, 1, 0)
members, err := projectMembers.GetByProjectID(ctx, createdProjects[0].ID, 1, 0)
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, members)
assert.Equal(t, 1, len(members))
members, err = projectMembers.GetByProjectIDPaged(ctx, createdProjects[0].ID, 2, 0)
members, err = projectMembers.GetByProjectID(ctx, createdProjects[0].ID, 2, 0)
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, members)
assert.Equal(t, 2, len(members))
members, err = projectMembers.GetByProjectIDPaged(ctx, createdProjects[0].ID, 1, 1)
members, err = projectMembers.GetByProjectID(ctx, createdProjects[0].ID, 1, 1)
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, members)
@ -112,45 +112,6 @@ func TestProjectMembersRepository(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, originalMember2.ID, selectedMember2.MemberID)
})
t.Run("Get member by projectID success", func(t *testing.T) {
originalProject1 := createdProjects[0]
projectMembers1, err := projectMembers.GetByProjectID(ctx, originalProject1.ID)
assert.NotNil(t, projectMembers1)
assert.Equal(t, 2, len(projectMembers1))
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, projectMembers1[0].MemberID, createdUsers[0].ID)
assert.Equal(t, projectMembers1[1].MemberID, createdUsers[1].ID)
originalProject2 := createdProjects[1]
projectMembers2, err := projectMembers.GetByProjectID(ctx, originalProject2.ID)
assert.NotNil(t, projectMembers2)
assert.Equal(t, 1, len(projectMembers2))
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, projectMembers2[0].MemberID, createdUsers[2].ID)
})
t.Run("Delete success", func(t *testing.T) {
members, err := projectMembers.GetByProjectID(ctx, createdProjects[0].ID)
assert.NotNil(t, members)
assert.Equal(t, 2, len(members))
assert.Nil(t, err)
assert.NoError(t, err)
err = projectMembers.Delete(ctx, members[1].MemberID, members[1].ProjectID)
assert.Nil(t, err)
assert.NoError(t, err)
members, err = projectMembers.GetByProjectID(ctx, createdProjects[0].ID)
assert.NotNil(t, members)
assert.Equal(t, 1, len(members))
assert.Nil(t, err)
assert.NoError(t, err)
})
}
func prepareUsersAndProjects(ctx context.Context, t *testing.T, users satellite.Users, projects satellite.Projects) ([]*satellite.User, []*satellite.Project) {

View File

@ -19,6 +19,9 @@ const (
// Used in input model
fieldIsTermsAccepted = "isTermsAccepted"
fieldMembers = "members"
limit = "limit"
offset = "offset"
)
// graphqlProject creates *graphql.Object type representation of satellite.ProjectInfo
@ -63,10 +66,21 @@ func graphqlProject(service *satellite.Service, types Types) *graphql.Object {
},
fieldMembers: &graphql.Field{
Type: graphql.NewList(types.ProjectMember()),
Args: graphql.FieldConfigArgument{
offset: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.Int),
},
limit: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.Int),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
project, _ := p.Source.(*satellite.Project)
members, err := service.GetProjectMembers(p.Context, project.ID)
offs, _ := p.Args[offset].(int64)
lim, _ := p.Args[limit].(int)
members, err := service.GetProjectMembers(p.Context, project.ID, lim, offs)
if err != nil {
return nil, err
}

View File

@ -20,8 +20,8 @@ import (
"storj.io/storj/pkg/utils"
)
// TODO: Use maxLimit in future.
//const maxLimit = 50
// maxLimit specifies the limit for all paged queries
const maxLimit = 50
// Service is handling accounts related logic
type Service struct {
@ -347,17 +347,21 @@ func (s *Service) DeleteProjectMember(ctx context.Context, projectID, userID uui
}
// GetProjectMembers returns ProjectMembers for given Project
// TODO: add limit and offset parameters
func (s *Service) GetProjectMembers(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error) {
func (s *Service) GetProjectMembers(ctx context.Context, projectID uuid.UUID, limit int, offset int64) ([]ProjectMember, error) {
_, err := GetAuth(ctx)
if err != nil {
return nil, err
}
// TODO: check if limit < maxLimit const
if limit < 0 || offset < 0 {
return nil, errs.New("invalid pagination argument")
}
// TODO: replace GetByProjectID with GetByProjectIDPaged and remove GetByProjectID as redundant
return s.store.ProjectMembers().GetByProjectID(ctx, projectID)
if limit > maxLimit {
limit = maxLimit
}
return s.store.ProjectMembers().GetByProjectID(ctx, projectID, limit, offset)
}
// Authorize validates token from context and returns authorized Authorization