22f8b029b9
The SQL transaction that inserted project invitations relied on the error result of one of its statements in order to determine whether an invitation should be updated. This was inappropriate since any errors returned from a transaction statement should end the transaction immediately. This change resolves that issue. Change-Id: I354e430df293054d8583fb4faa5dc1bcf9053836
184 lines
5.5 KiB
Go
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().Upsert(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))
|
|
}
|
|
})
|
|
})
|
|
}
|