storj/satellite/satellitedb/projectmembers_test.go
Jeremy Wharton 2ab6e00966 satellite/satellitedb: add method to return project members and invites
A method has been implemented that allows for paged searching through
project members and project member invitations. In the future, this
will be used to display invitations in the Team page of the satellite
frontend.

References #5855

Change-Id: I0937c425f60f1318e55202bf30b44a33ff695414
2023-06-12 17:28:50 -05:00

184 lines
5.5 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package satellitedb_test
import (
"fmt"
"testing"
"time"
"github.com/stretchr/testify/require"
"storj.io/common/testcontext"
"storj.io/common/testrand"
"storj.io/common/uuid"
"storj.io/storj/satellite"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/satellitedb/satellitedbtest"
)
func TestGetPagedWithInvitationsByProjectID(t *testing.T) {
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
membersDB := db.Console().ProjectMembers()
projectID := testrand.UUID()
_, err := db.Console().Projects().Insert(ctx, &console.Project{ID: projectID})
require.NoError(t, err)
memberUser, err := db.Console().Users().Insert(ctx, &console.User{
FullName: "Alice",
Email: "alice@mail.test",
ID: testrand.UUID(),
PasswordHash: testrand.Bytes(8),
})
require.NoError(t, err)
_, err = db.Console().ProjectMembers().Insert(ctx, memberUser.ID, projectID)
require.NoError(t, err)
_, err = db.Console().ProjectInvitations().Insert(ctx, &console.ProjectInvitation{
ProjectID: projectID,
Email: "bob@mail.test",
})
require.NoError(t, err)
t.Run("paging", func(t *testing.T) {
ctx := testcontext.New(t)
for _, tt := range []struct {
limit uint
page uint
expectedCount int
}{
{limit: 2, page: 1, expectedCount: 2},
{limit: 1, page: 1, expectedCount: 1},
{limit: 1, page: 2, expectedCount: 1},
} {
cursor := console.ProjectMembersCursor{Limit: tt.limit, Page: tt.page}
page, err := membersDB.GetPagedWithInvitationsByProjectID(ctx, projectID, cursor)
require.NoError(t, err)
require.Equal(t, tt.expectedCount, len(page.ProjectInvitations)+len(page.ProjectMembers),
fmt.Sprintf("error occurred with limit %d, page %d", tt.limit, tt.page))
}
_, err = membersDB.GetPagedWithInvitationsByProjectID(ctx, projectID, console.ProjectMembersCursor{Limit: 1, Page: 3})
require.Error(t, err)
})
t.Run("search", func(t *testing.T) {
ctx := testcontext.New(t)
for _, tt := range []struct {
search string
expectMembers bool
expectInvites bool
}{
{search: "aLiCe", expectMembers: true},
{search: "@ test", expectMembers: true, expectInvites: true},
{search: "bad"},
} {
errMsg := "unexpected result for search '" + tt.search + "'"
cursor := console.ProjectMembersCursor{Search: tt.search, Limit: 2, Page: 1}
page, err := membersDB.GetPagedWithInvitationsByProjectID(ctx, projectID, cursor)
require.NoError(t, err, errMsg)
if tt.expectMembers {
require.NotEmpty(t, page.ProjectMembers, errMsg)
} else {
require.Empty(t, page.ProjectMembers, errMsg)
}
if tt.expectInvites {
require.NotEmpty(t, page.ProjectInvitations, errMsg)
} else {
require.Empty(t, page.ProjectInvitations, errMsg)
}
}
})
t.Run("ordering", func(t *testing.T) {
ctx := testcontext.New(t)
projectID := testrand.UUID()
_, err := db.Console().Projects().Insert(ctx, &console.Project{ID: projectID})
require.NoError(t, err)
var memberIDs []uuid.UUID
for i := 0; i < 3; i++ {
id := uuid.UUID{}
id[len(id)-1] = byte(i + 1)
memberIDs = append(memberIDs, id)
user := console.User{
FullName: fmt.Sprintf("%d", i),
Email: fmt.Sprintf("%d@mail.test", (i+2)%3),
ID: id,
PasswordHash: testrand.Bytes(8),
}
_, err := db.Console().Users().Insert(ctx, &user)
require.NoError(t, err)
_, err = db.Console().ProjectMembers().Insert(ctx, user.ID, projectID)
require.NoError(t, err)
result, err := db.Testing().RawDB().ExecContext(ctx,
"UPDATE project_members SET created_at = $1 WHERE member_id = $2",
time.Time{}.Add(time.Duration((i+1)%3)*time.Hour), id,
)
require.NoError(t, err)
count, err := result.RowsAffected()
require.NoError(t, err)
require.EqualValues(t, 1, count)
}
for _, tt := range []struct {
order console.ProjectMemberOrder
memberIDs []uuid.UUID
}{
{
order: console.Name,
memberIDs: []uuid.UUID{memberIDs[0], memberIDs[1], memberIDs[2]},
}, {
order: console.Email,
memberIDs: []uuid.UUID{memberIDs[1], memberIDs[2], memberIDs[0]},
}, {
order: console.Created,
memberIDs: []uuid.UUID{memberIDs[2], memberIDs[0], memberIDs[1]},
},
} {
errMsg := func(cursor console.ProjectMembersCursor) string {
return fmt.Sprintf("unexpected result when ordering by %s, %s",
[]string{"name", "email", "creation date"}[cursor.Order-1],
[]string{"ascending", "descending"}[cursor.OrderDirection-1])
}
getIDsFromDB := func(cursor console.ProjectMembersCursor) (ids []uuid.UUID) {
page, err := membersDB.GetPagedWithInvitationsByProjectID(ctx, projectID, cursor)
require.NoError(t, err, errMsg(cursor))
for _, member := range page.ProjectMembers {
ids = append(ids, member.MemberID)
}
return ids
}
cursor := console.ProjectMembersCursor{
Limit: uint(len(tt.memberIDs)),
Page: 1, Order: tt.order,
OrderDirection: console.Ascending,
}
require.Equal(t, tt.memberIDs, getIDsFromDB(cursor), errMsg(cursor))
cursor.OrderDirection = console.Descending
var reverseMemberIDs []uuid.UUID
for i := len(tt.memberIDs) - 1; i >= 0; i-- {
reverseMemberIDs = append(reverseMemberIDs, tt.memberIDs[i])
}
require.Equal(t, reverseMemberIDs, getIDsFromDB(cursor), errMsg(cursor))
}
})
})
}