mirror of
https://github.com/coder/coder.git
synced 2026-06-03 04:58:23 +00:00
81188b9ac9
You can now filter by/out service accounts using `service_account:true/false` or using the filter dropdown.
611 lines
18 KiB
Go
611 lines
18 KiB
Go
package coderdtest
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/coder/coder/v2/coderd/database"
|
|
"github.com/coder/coder/v2/coderd/database/db2sdk"
|
|
"github.com/coder/coder/v2/coderd/database/dbauthz"
|
|
"github.com/coder/coder/v2/coderd/database/dbtime"
|
|
"github.com/coder/coder/v2/coderd/rbac"
|
|
"github.com/coder/coder/v2/coderd/userpassword"
|
|
"github.com/coder/coder/v2/coderd/util/slice"
|
|
"github.com/coder/coder/v2/codersdk"
|
|
"github.com/coder/coder/v2/testutil"
|
|
)
|
|
|
|
// UsersPagination creates a set of users for testing pagination. It can be
|
|
// used to test paginating both users and group members.
|
|
func UsersPagination(
|
|
ctx context.Context,
|
|
t *testing.T,
|
|
client *codersdk.Client,
|
|
setup func(users []codersdk.User),
|
|
fetch func(req codersdk.UsersRequest) ([]codersdk.ReducedUser, int),
|
|
) {
|
|
t.Helper()
|
|
|
|
firstUser, err := client.User(ctx, codersdk.Me)
|
|
require.NoError(t, err, "fetch me")
|
|
|
|
count := 10
|
|
users := make([]codersdk.User, count)
|
|
orgID := firstUser.OrganizationIDs[0]
|
|
users[0] = firstUser
|
|
for i := range count - 1 {
|
|
_, user := CreateAnotherUserMutators(t, client, orgID, nil, func(r *codersdk.CreateUserRequestWithOrgs) {
|
|
if i < 5 {
|
|
r.Name = fmt.Sprintf("before%d", i)
|
|
} else {
|
|
r.Name = fmt.Sprintf("after%d", i)
|
|
}
|
|
})
|
|
users[i+1] = user
|
|
}
|
|
|
|
slices.SortFunc(users, func(a, b codersdk.User) int {
|
|
return slice.Ascending(strings.ToLower(a.Username), strings.ToLower(b.Username))
|
|
})
|
|
|
|
if setup != nil {
|
|
setup(users)
|
|
}
|
|
|
|
gotUsers, gotCount := fetch(codersdk.UsersRequest{})
|
|
require.Len(t, gotUsers, count)
|
|
require.Equal(t, gotCount, count)
|
|
|
|
gotUsers, gotCount = fetch(codersdk.UsersRequest{
|
|
Pagination: codersdk.Pagination{
|
|
Limit: 1,
|
|
},
|
|
})
|
|
require.Len(t, gotUsers, 1)
|
|
require.Equal(t, gotCount, count)
|
|
|
|
gotUsers, gotCount = fetch(codersdk.UsersRequest{
|
|
Pagination: codersdk.Pagination{
|
|
Offset: 1,
|
|
},
|
|
})
|
|
require.Len(t, gotUsers, count-1)
|
|
require.Equal(t, gotCount, count)
|
|
|
|
gotUsers, gotCount = fetch(codersdk.UsersRequest{
|
|
Pagination: codersdk.Pagination{
|
|
Limit: 1,
|
|
Offset: 1,
|
|
},
|
|
})
|
|
require.Len(t, gotUsers, 1)
|
|
require.Equal(t, gotCount, count)
|
|
|
|
// If offset is higher than the count postgres returns an empty array
|
|
// and not an ErrNoRows error.
|
|
gotUsers, gotCount = fetch(codersdk.UsersRequest{
|
|
Pagination: codersdk.Pagination{
|
|
Offset: count + 1,
|
|
},
|
|
})
|
|
require.Len(t, gotUsers, 0)
|
|
require.Equal(t, gotCount, 0)
|
|
|
|
// Check that AfterID works.
|
|
gotUsers, gotCount = fetch(codersdk.UsersRequest{
|
|
Pagination: codersdk.Pagination{
|
|
AfterID: users[5].ID,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
require.Len(t, gotUsers, 4)
|
|
require.Equal(t, gotCount, 4)
|
|
|
|
// Check we can paginate a filtered response.
|
|
gotUsers, gotCount = fetch(codersdk.UsersRequest{
|
|
SearchQuery: "name:after",
|
|
Pagination: codersdk.Pagination{
|
|
Limit: 1,
|
|
Offset: 1,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
require.Len(t, gotUsers, 1)
|
|
require.Equal(t, gotCount, 4)
|
|
require.Contains(t, gotUsers[0].Name, "after")
|
|
}
|
|
|
|
// UsersFilter creates a set of users to run various filters against for
|
|
// testing. It can be used to test filtering both users and group members.
|
|
func UsersFilter(
|
|
setupCtx context.Context,
|
|
t *testing.T,
|
|
client *codersdk.Client,
|
|
db database.Store,
|
|
setup func(users []codersdk.User),
|
|
fetch func(ctx context.Context, req codersdk.UsersRequest) []codersdk.ReducedUser,
|
|
) {
|
|
t.Helper()
|
|
|
|
firstUser, err := client.User(setupCtx, codersdk.Me)
|
|
require.NoError(t, err, "fetch me")
|
|
|
|
// Noon on Jan 18 is the "now" for this test for last_seen timestamps.
|
|
// All these values are equal
|
|
// 2023-01-18T12:00:00Z (UTC)
|
|
// 2023-01-18T07:00:00-05:00 (America/New_York)
|
|
// 2023-01-18T13:00:00+01:00 (Europe/Madrid)
|
|
// 2023-01-16T00:00:00+12:00 (Asia/Anadyr)
|
|
lastSeenNow := time.Date(2023, 1, 18, 12, 0, 0, 0, time.UTC)
|
|
users := make([]codersdk.User, 0)
|
|
users = append(users, firstUser)
|
|
orgID := firstUser.OrganizationIDs[0]
|
|
for i := range 15 {
|
|
roles := []rbac.RoleIdentifier{}
|
|
if i%2 == 0 {
|
|
roles = append(roles, rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin())
|
|
}
|
|
if i%3 == 0 {
|
|
roles = append(roles, rbac.RoleAuditor())
|
|
}
|
|
userClient, userData := CreateAnotherUserMutators(t, client, orgID, roles, func(r *codersdk.CreateUserRequestWithOrgs) {
|
|
switch {
|
|
case i%7 == 0:
|
|
r.Username += fmt.Sprintf("-gh%d", i)
|
|
r.UserLoginType = codersdk.LoginTypeGithub
|
|
r.Password = ""
|
|
case i%6 == 0:
|
|
r.UserLoginType = codersdk.LoginTypeOIDC
|
|
r.Password = ""
|
|
default:
|
|
r.UserLoginType = codersdk.LoginTypePassword
|
|
}
|
|
})
|
|
|
|
// Set the last seen for each user to a unique day
|
|
// nolint:gocritic // Setting up unit test data.
|
|
_, err := db.UpdateUserLastSeenAt(dbauthz.AsSystemRestricted(setupCtx), database.UpdateUserLastSeenAtParams{
|
|
ID: userData.ID,
|
|
LastSeenAt: lastSeenNow.Add(-1 * time.Hour * 24 * time.Duration(i)),
|
|
UpdatedAt: time.Now(),
|
|
})
|
|
require.NoError(t, err, "set a last seen")
|
|
|
|
// Set a github user ID for github login types.
|
|
if i%7 == 0 {
|
|
// nolint:gocritic // Setting up unit test data.
|
|
err = db.UpdateUserGithubComUserID(dbauthz.AsSystemRestricted(setupCtx), database.UpdateUserGithubComUserIDParams{
|
|
ID: userData.ID,
|
|
GithubComUserID: sql.NullInt64{
|
|
Int64: int64(i),
|
|
Valid: true,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
user, err := userClient.User(setupCtx, codersdk.Me)
|
|
require.NoError(t, err, "fetch me")
|
|
|
|
if i%4 == 0 {
|
|
user, err = client.UpdateUserStatus(setupCtx, user.ID.String(), codersdk.UserStatusSuspended)
|
|
require.NoError(t, err, "suspend user")
|
|
}
|
|
|
|
if i%5 == 0 {
|
|
user, err = client.UpdateUserProfile(setupCtx, user.ID.String(), codersdk.UpdateUserProfileRequest{
|
|
Username: strings.ToUpper(user.Username),
|
|
})
|
|
require.NoError(t, err, "update username to uppercase")
|
|
}
|
|
|
|
users = append(users, user)
|
|
}
|
|
|
|
// Add some service accounts.
|
|
for range 3 {
|
|
_, user := CreateAnotherUserMutators(t, client, orgID, nil, func(r *codersdk.CreateUserRequestWithOrgs) {
|
|
r.ServiceAccount = true
|
|
})
|
|
users = append(users, user)
|
|
}
|
|
|
|
hashedPassword, err := userpassword.Hash("SomeStrongPassword!")
|
|
require.NoError(t, err)
|
|
|
|
// Add users with different creation dates for testing date filters
|
|
for i := range 3 {
|
|
// nolint:gocritic // Setting up unit test data.
|
|
user1, err := db.InsertUser(dbauthz.AsSystemRestricted(setupCtx), database.InsertUserParams{
|
|
ID: uuid.New(),
|
|
Email: fmt.Sprintf("before%d@coder.com", i),
|
|
Username: fmt.Sprintf("before%d", i),
|
|
Name: fmt.Sprintf("Test User %d", i),
|
|
HashedPassword: []byte(hashedPassword),
|
|
LoginType: database.LoginTypeNone,
|
|
Status: string(codersdk.UserStatusActive),
|
|
RBACRoles: []string{codersdk.RoleMember},
|
|
CreatedAt: dbtime.Time(time.Date(2022, 12, 15+i, 12, 0, 0, 0, time.UTC)),
|
|
UpdatedAt: dbtime.Time(time.Date(2022, 12, 15+i, 12, 0, 0, 0, time.UTC)),
|
|
IsServiceAccount: false,
|
|
})
|
|
require.NoError(t, err)
|
|
// nolint:gocritic // Setting up unit test data.
|
|
_, err = db.InsertOrganizationMember(dbauthz.AsSystemRestricted(setupCtx), database.InsertOrganizationMemberParams{
|
|
OrganizationID: orgID,
|
|
UserID: user1.ID,
|
|
CreatedAt: dbtime.Now(),
|
|
UpdatedAt: dbtime.Now(),
|
|
Roles: []string{},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// The expected timestamps must be parsed from strings to compare equal during `ElementsMatch`
|
|
sdkUser1 := db2sdk.User(user1, []uuid.UUID{orgID})
|
|
sdkUser1.CreatedAt, err = time.Parse(time.RFC3339, sdkUser1.CreatedAt.Format(time.RFC3339))
|
|
require.NoError(t, err)
|
|
sdkUser1.UpdatedAt, err = time.Parse(time.RFC3339, sdkUser1.UpdatedAt.Format(time.RFC3339))
|
|
require.NoError(t, err)
|
|
sdkUser1.LastSeenAt, err = time.Parse(time.RFC3339, sdkUser1.LastSeenAt.Format(time.RFC3339))
|
|
require.NoError(t, err)
|
|
users = append(users, sdkUser1)
|
|
|
|
// nolint:gocritic // Setting up unit test data.
|
|
user2, err := db.InsertUser(dbauthz.AsSystemRestricted(setupCtx), database.InsertUserParams{
|
|
ID: uuid.New(),
|
|
Email: fmt.Sprintf("during%d@coder.com", i),
|
|
Username: fmt.Sprintf("during%d", i),
|
|
Name: "",
|
|
HashedPassword: []byte(hashedPassword),
|
|
LoginType: database.LoginTypeNone,
|
|
Status: string(codersdk.UserStatusActive),
|
|
RBACRoles: []string{codersdk.RoleOwner},
|
|
CreatedAt: dbtime.Time(time.Date(2023, 1, 15+i, 12, 0, 0, 0, time.UTC)),
|
|
UpdatedAt: dbtime.Time(time.Date(2023, 1, 15+i, 12, 0, 0, 0, time.UTC)),
|
|
IsServiceAccount: false,
|
|
})
|
|
require.NoError(t, err)
|
|
// nolint:gocritic // Setting up unit test data.
|
|
_, err = db.InsertOrganizationMember(dbauthz.AsSystemRestricted(setupCtx), database.InsertOrganizationMemberParams{
|
|
OrganizationID: orgID,
|
|
UserID: user2.ID,
|
|
CreatedAt: dbtime.Now(),
|
|
UpdatedAt: dbtime.Now(),
|
|
Roles: []string{},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
sdkUser2 := db2sdk.User(user2, []uuid.UUID{orgID})
|
|
sdkUser2.CreatedAt, err = time.Parse(time.RFC3339, sdkUser2.CreatedAt.Format(time.RFC3339))
|
|
require.NoError(t, err)
|
|
sdkUser2.UpdatedAt, err = time.Parse(time.RFC3339, sdkUser2.UpdatedAt.Format(time.RFC3339))
|
|
require.NoError(t, err)
|
|
sdkUser2.LastSeenAt, err = time.Parse(time.RFC3339, sdkUser2.LastSeenAt.Format(time.RFC3339))
|
|
require.NoError(t, err)
|
|
users = append(users, sdkUser2)
|
|
|
|
// nolint:gocritic // Setting up unit test data.
|
|
user3, err := db.InsertUser(dbauthz.AsSystemRestricted(setupCtx), database.InsertUserParams{
|
|
ID: uuid.New(),
|
|
Email: fmt.Sprintf("after%d@coder.com", i),
|
|
Username: fmt.Sprintf("after%d", i),
|
|
Name: "",
|
|
HashedPassword: []byte(hashedPassword),
|
|
LoginType: database.LoginTypeNone,
|
|
Status: string(codersdk.UserStatusActive),
|
|
RBACRoles: []string{codersdk.RoleOwner},
|
|
CreatedAt: dbtime.Time(time.Date(2023, 2, 15+i, 12, 0, 0, 0, time.UTC)),
|
|
UpdatedAt: dbtime.Time(time.Date(2023, 2, 15+i, 12, 0, 0, 0, time.UTC)),
|
|
IsServiceAccount: false,
|
|
})
|
|
require.NoError(t, err)
|
|
// nolint:gocritic // Setting up unit test data.
|
|
_, err = db.InsertOrganizationMember(dbauthz.AsSystemRestricted(setupCtx), database.InsertOrganizationMemberParams{
|
|
OrganizationID: orgID,
|
|
UserID: user3.ID,
|
|
CreatedAt: dbtime.Now(),
|
|
UpdatedAt: dbtime.Now(),
|
|
Roles: []string{},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
sdkUser3 := db2sdk.User(user3, []uuid.UUID{orgID})
|
|
sdkUser3.CreatedAt, err = time.Parse(time.RFC3339, sdkUser3.CreatedAt.Format(time.RFC3339))
|
|
require.NoError(t, err)
|
|
sdkUser3.UpdatedAt, err = time.Parse(time.RFC3339, sdkUser3.UpdatedAt.Format(time.RFC3339))
|
|
require.NoError(t, err)
|
|
sdkUser3.LastSeenAt, err = time.Parse(time.RFC3339, sdkUser3.LastSeenAt.Format(time.RFC3339))
|
|
require.NoError(t, err)
|
|
users = append(users, sdkUser3)
|
|
}
|
|
|
|
if setup != nil {
|
|
setup(users)
|
|
}
|
|
|
|
// --- Setup done ---
|
|
testCases := []struct {
|
|
Name string
|
|
Filter codersdk.UsersRequest
|
|
// If FilterF is true, we include it in the expected results
|
|
FilterF func(f codersdk.UsersRequest, user codersdk.User) bool
|
|
}{
|
|
{
|
|
Name: "All",
|
|
Filter: codersdk.UsersRequest{
|
|
Status: codersdk.UserStatusSuspended + "," + codersdk.UserStatusActive,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, _ codersdk.User) bool {
|
|
return true
|
|
},
|
|
},
|
|
{
|
|
Name: "Active",
|
|
Filter: codersdk.UsersRequest{
|
|
Status: codersdk.UserStatusActive,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.Status == codersdk.UserStatusActive
|
|
},
|
|
},
|
|
{
|
|
Name: "GithubComUserID",
|
|
Filter: codersdk.UsersRequest{
|
|
SearchQuery: "github_com_user_id:7",
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return strings.HasSuffix(u.Username, "-gh7")
|
|
},
|
|
},
|
|
{
|
|
Name: "ActiveUppercase",
|
|
Filter: codersdk.UsersRequest{
|
|
Status: "ACTIVE",
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.Status == codersdk.UserStatusActive
|
|
},
|
|
},
|
|
{
|
|
Name: "Suspended",
|
|
Filter: codersdk.UsersRequest{
|
|
Status: codersdk.UserStatusSuspended,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.Status == codersdk.UserStatusSuspended
|
|
},
|
|
},
|
|
{
|
|
Name: "NameContains",
|
|
Filter: codersdk.UsersRequest{
|
|
Search: "a",
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return (strings.ContainsAny(u.Username, "aA") || strings.ContainsAny(u.Email, "aA"))
|
|
},
|
|
},
|
|
{
|
|
Name: "NameAndSearch",
|
|
Filter: codersdk.UsersRequest{
|
|
SearchQuery: "name:Test search:before1",
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.Username == "before1"
|
|
},
|
|
},
|
|
{
|
|
Name: "NameNoMatch",
|
|
Filter: codersdk.UsersRequest{
|
|
Search: "nonexistent",
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, _ codersdk.User) bool {
|
|
return false
|
|
},
|
|
},
|
|
{
|
|
Name: "Admins",
|
|
Filter: codersdk.UsersRequest{
|
|
Role: codersdk.RoleOwner,
|
|
Status: codersdk.UserStatusSuspended + "," + codersdk.UserStatusActive,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
for _, r := range u.Roles {
|
|
if r.Name == codersdk.RoleOwner {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
},
|
|
},
|
|
{
|
|
Name: "AdminsUppercase",
|
|
Filter: codersdk.UsersRequest{
|
|
Role: "OWNER",
|
|
Status: codersdk.UserStatusSuspended + "," + codersdk.UserStatusActive,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
for _, r := range u.Roles {
|
|
if r.Name == codersdk.RoleOwner {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
},
|
|
},
|
|
{
|
|
Name: "Members",
|
|
Filter: codersdk.UsersRequest{
|
|
Role: codersdk.RoleMember,
|
|
Status: codersdk.UserStatusSuspended + "," + codersdk.UserStatusActive,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, _ codersdk.User) bool {
|
|
return true
|
|
},
|
|
},
|
|
{
|
|
Name: "SearchQuery",
|
|
Filter: codersdk.UsersRequest{
|
|
SearchQuery: "i role:owner status:active",
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
for _, r := range u.Roles {
|
|
if r.Name == codersdk.RoleOwner {
|
|
return (strings.ContainsAny(u.Username, "iI") || strings.ContainsAny(u.Email, "iI")) &&
|
|
u.Status == codersdk.UserStatusActive
|
|
}
|
|
}
|
|
return false
|
|
},
|
|
},
|
|
{
|
|
Name: "SearchQueryInsensitive",
|
|
Filter: codersdk.UsersRequest{
|
|
SearchQuery: "i Role:Owner STATUS:Active",
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
for _, r := range u.Roles {
|
|
if r.Name == codersdk.RoleOwner {
|
|
return (strings.ContainsAny(u.Username, "iI") || strings.ContainsAny(u.Email, "iI")) &&
|
|
u.Status == codersdk.UserStatusActive
|
|
}
|
|
}
|
|
return false
|
|
},
|
|
},
|
|
{
|
|
Name: "LastSeenBeforeNow",
|
|
Filter: codersdk.UsersRequest{
|
|
SearchQuery: `last_seen_before:"2023-01-16T00:00:00+12:00"`,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.LastSeenAt.Before(lastSeenNow)
|
|
},
|
|
},
|
|
{
|
|
Name: "LastSeenLastWeek",
|
|
Filter: codersdk.UsersRequest{
|
|
SearchQuery: `last_seen_before:"2023-01-14T23:59:59Z" last_seen_after:"2023-01-08T00:00:00Z"`,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
start := time.Date(2023, 1, 8, 0, 0, 0, 0, time.UTC)
|
|
end := time.Date(2023, 1, 14, 23, 59, 59, 0, time.UTC)
|
|
return u.LastSeenAt.Before(end) && u.LastSeenAt.After(start)
|
|
},
|
|
},
|
|
{
|
|
Name: "CreatedAtBefore",
|
|
Filter: codersdk.UsersRequest{
|
|
SearchQuery: `created_before:"2023-01-31T23:59:59Z"`,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
end := time.Date(2023, 1, 31, 23, 59, 59, 0, time.UTC)
|
|
return u.CreatedAt.Before(end)
|
|
},
|
|
},
|
|
{
|
|
Name: "CreatedAtAfter",
|
|
Filter: codersdk.UsersRequest{
|
|
SearchQuery: `created_after:"2023-01-01T00:00:00Z"`,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
start := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
return u.CreatedAt.After(start)
|
|
},
|
|
},
|
|
{
|
|
Name: "CreatedAtRange",
|
|
Filter: codersdk.UsersRequest{
|
|
SearchQuery: `created_after:"2023-01-01T00:00:00Z" created_before:"2023-01-31T23:59:59Z"`,
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
start := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
end := time.Date(2023, 1, 31, 23, 59, 59, 0, time.UTC)
|
|
return u.CreatedAt.After(start) && u.CreatedAt.Before(end)
|
|
},
|
|
},
|
|
{
|
|
Name: "LoginTypeNone",
|
|
Filter: codersdk.UsersRequest{
|
|
LoginType: []codersdk.LoginType{codersdk.LoginTypeNone},
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.LoginType == codersdk.LoginTypeNone
|
|
},
|
|
},
|
|
{
|
|
Name: "LoginTypeOIDC",
|
|
Filter: codersdk.UsersRequest{
|
|
LoginType: []codersdk.LoginType{codersdk.LoginTypeOIDC},
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.LoginType == codersdk.LoginTypeOIDC
|
|
},
|
|
},
|
|
{
|
|
Name: "LoginTypeMultiple",
|
|
Filter: codersdk.UsersRequest{
|
|
LoginType: []codersdk.LoginType{codersdk.LoginTypeNone, codersdk.LoginTypeGithub},
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.LoginType == codersdk.LoginTypeNone || u.LoginType == codersdk.LoginTypeGithub
|
|
},
|
|
},
|
|
{
|
|
Name: "DormantUserWithLoginTypeNone",
|
|
Filter: codersdk.UsersRequest{
|
|
Status: codersdk.UserStatusSuspended,
|
|
LoginType: []codersdk.LoginType{codersdk.LoginTypeNone},
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.Status == codersdk.UserStatusSuspended && u.LoginType == codersdk.LoginTypeNone
|
|
},
|
|
},
|
|
{
|
|
Name: "IsServiceAccount",
|
|
Filter: codersdk.UsersRequest{
|
|
Search: "service_account:true",
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return u.IsServiceAccount
|
|
},
|
|
},
|
|
{
|
|
Name: "IsNotServiceAccount",
|
|
Filter: codersdk.UsersRequest{
|
|
Search: "service_account:false",
|
|
},
|
|
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
|
|
return !u.IsServiceAccount
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, c := range testCases {
|
|
t.Run(c.Name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testCtx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
|
defer cancel()
|
|
|
|
got := fetch(testCtx, c.Filter)
|
|
exp := make([]codersdk.ReducedUser, 0)
|
|
for _, made := range users {
|
|
match := c.FilterF(c.Filter, made)
|
|
if match {
|
|
exp = append(exp, made.ReducedUser)
|
|
}
|
|
}
|
|
|
|
require.ElementsMatch(t, exp, got, "expected users returned")
|
|
})
|
|
}
|
|
}
|