[MM-26532] Support "active" filter on profile search (#14923)
* Support "active" filter on profile search * Add tests for active user filter
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
bec2f366a7
Коммит
11bc28b5fb
@@ -533,6 +533,7 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
groupConstrained := r.URL.Query().Get("group_constrained")
|
groupConstrained := r.URL.Query().Get("group_constrained")
|
||||||
withoutTeam := r.URL.Query().Get("without_team")
|
withoutTeam := r.URL.Query().Get("without_team")
|
||||||
inactive := r.URL.Query().Get("inactive")
|
inactive := r.URL.Query().Get("inactive")
|
||||||
|
active := r.URL.Query().Get("active")
|
||||||
role := r.URL.Query().Get("role")
|
role := r.URL.Query().Get("role")
|
||||||
sort := r.URL.Query().Get("sort")
|
sort := r.URL.Query().Get("sort")
|
||||||
|
|
||||||
@@ -560,6 +561,11 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
withoutTeamBool, _ := strconv.ParseBool(withoutTeam)
|
withoutTeamBool, _ := strconv.ParseBool(withoutTeam)
|
||||||
groupConstrainedBool, _ := strconv.ParseBool(groupConstrained)
|
groupConstrainedBool, _ := strconv.ParseBool(groupConstrained)
|
||||||
inactiveBool, _ := strconv.ParseBool(inactive)
|
inactiveBool, _ := strconv.ParseBool(inactive)
|
||||||
|
activeBool, _ := strconv.ParseBool(active)
|
||||||
|
|
||||||
|
if inactiveBool && activeBool {
|
||||||
|
c.SetInvalidUrlParam("inactive")
|
||||||
|
}
|
||||||
|
|
||||||
restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session().UserId)
|
restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session().UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -576,6 +582,7 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
GroupConstrained: groupConstrainedBool,
|
GroupConstrained: groupConstrainedBool,
|
||||||
WithoutTeam: withoutTeamBool,
|
WithoutTeam: withoutTeamBool,
|
||||||
Inactive: inactiveBool,
|
Inactive: inactiveBool,
|
||||||
|
Active: activeBool,
|
||||||
Role: role,
|
Role: role,
|
||||||
Sort: sort,
|
Sort: sort,
|
||||||
Page: c.Params.Page,
|
Page: c.Params.Page,
|
||||||
|
|||||||
@@ -2245,6 +2245,35 @@ func TestGetRecentlyActiveUsersInTeam(t *testing.T) {
|
|||||||
CheckUnauthorizedStatus(t, resp)
|
CheckUnauthorizedStatus(t, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetActiveUsersInTeam(t *testing.T) {
|
||||||
|
th := Setup(t).InitBasic()
|
||||||
|
defer th.TearDown()
|
||||||
|
teamId := th.BasicTeam.Id
|
||||||
|
|
||||||
|
th.SystemAdminClient.UpdateUserActive(th.BasicUser2.Id, false)
|
||||||
|
rusers, resp := th.Client.GetActiveUsersInTeam(teamId, 0, 60, "")
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
|
||||||
|
require.NotZero(t, len(rusers))
|
||||||
|
for _, u := range rusers {
|
||||||
|
require.Zero(t, u.DeleteAt, "should not be deleted")
|
||||||
|
require.NotEqual(t, th.BasicUser2.Id, "should not include deactivated user")
|
||||||
|
CheckUserSanitization(t, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
rusers, resp = th.Client.GetActiveUsersInTeam(teamId, 0, 1, "")
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
require.Len(t, rusers, 1, "should be 1 per page")
|
||||||
|
|
||||||
|
// Check case where we have supplied both active and inactive flags
|
||||||
|
_, err := th.Client.DoApiGet("/users?inactive=true&active=true", "")
|
||||||
|
require.NotNil(t, err)
|
||||||
|
|
||||||
|
th.Client.Logout()
|
||||||
|
_, resp = th.Client.GetActiveUsersInTeam(teamId, 0, 1, "")
|
||||||
|
CheckUnauthorizedStatus(t, resp)
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetUsersWithoutTeam(t *testing.T) {
|
func TestGetUsersWithoutTeam(t *testing.T) {
|
||||||
th := Setup(t).InitBasic()
|
th := Setup(t).InitBasic()
|
||||||
defer th.TearDown()
|
defer th.TearDown()
|
||||||
|
|||||||
@@ -939,6 +939,17 @@ func (c *Client4) GetRecentlyActiveUsersInTeam(teamId string, page int, perPage
|
|||||||
return UserListFromJson(r.Body), BuildResponse(r)
|
return UserListFromJson(r.Body), BuildResponse(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetActiveUsersInTeam returns a page of users on a team. Page counting starts at 0.
|
||||||
|
func (c *Client4) GetActiveUsersInTeam(teamId string, page int, perPage int, etag string) ([]*User, *Response) {
|
||||||
|
query := fmt.Sprintf("?active=true&in_team=%v&page=%v&per_page=%v", teamId, page, perPage)
|
||||||
|
r, err := c.DoApiGet(c.GetUsersRoute()+query, etag)
|
||||||
|
if err != nil {
|
||||||
|
return nil, BuildErrorResponse(r, err)
|
||||||
|
}
|
||||||
|
defer closeBody(r)
|
||||||
|
return UserListFromJson(r.Body), BuildResponse(r)
|
||||||
|
}
|
||||||
|
|
||||||
// GetUsersNotInTeam returns a page of users who are not in a team. Page counting starts at 0.
|
// GetUsersNotInTeam returns a page of users who are not in a team. Page counting starts at 0.
|
||||||
func (c *Client4) GetUsersNotInTeam(teamId string, page int, perPage int, etag string) ([]*User, *Response) {
|
func (c *Client4) GetUsersNotInTeam(teamId string, page int, perPage int, etag string) ([]*User, *Response) {
|
||||||
query := fmt.Sprintf("?not_in_team=%v&page=%v&per_page=%v", teamId, page, perPage)
|
query := fmt.Sprintf("?not_in_team=%v&page=%v&per_page=%v", teamId, page, perPage)
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ type UserGetOptions struct {
|
|||||||
WithoutTeam bool
|
WithoutTeam bool
|
||||||
// Filters the inactive users
|
// Filters the inactive users
|
||||||
Inactive bool
|
Inactive bool
|
||||||
|
// Filters the active users
|
||||||
|
Active bool
|
||||||
// Filters for the given role
|
// Filters for the given role
|
||||||
Role string
|
Role string
|
||||||
// Sorting option
|
// Sorting option
|
||||||
|
|||||||
@@ -422,6 +422,8 @@ func (us SqlUserStore) GetAllProfiles(options *model.UserGetOptions) ([]*model.U
|
|||||||
|
|
||||||
if options.Inactive {
|
if options.Inactive {
|
||||||
query = query.Where("u.DeleteAt != 0")
|
query = query.Where("u.DeleteAt != 0")
|
||||||
|
} else if options.Active {
|
||||||
|
query = query.Where("u.DeleteAt = 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
queryString, args, err := query.ToSql()
|
queryString, args, err := query.ToSql()
|
||||||
@@ -526,6 +528,8 @@ func (us SqlUserStore) GetProfiles(options *model.UserGetOptions) ([]*model.User
|
|||||||
|
|
||||||
if options.Inactive {
|
if options.Inactive {
|
||||||
query = query.Where("u.DeleteAt != 0")
|
query = query.Where("u.DeleteAt != 0")
|
||||||
|
} else if options.Active {
|
||||||
|
query = query.Where("u.DeleteAt = 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
queryString, args, err := query.ToSql()
|
queryString, args, err := query.ToSql()
|
||||||
@@ -711,6 +715,8 @@ func (us SqlUserStore) GetProfilesWithoutTeam(options *model.UserGetOptions) ([]
|
|||||||
|
|
||||||
if options.Inactive {
|
if options.Inactive {
|
||||||
query = query.Where("u.DeleteAt != 0")
|
query = query.Where("u.DeleteAt != 0")
|
||||||
|
} else if options.Active {
|
||||||
|
query = query.Where("u.DeleteAt = 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
queryString, args, err := query.ToSql()
|
queryString, args, err := query.ToSql()
|
||||||
|
|||||||
@@ -516,6 +516,36 @@ func testUserStoreGetAllProfiles(t *testing.T, ss store.Store) {
|
|||||||
sanitized(u7),
|
sanitized(u7),
|
||||||
}, actual)
|
}, actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("filter to active", func(t *testing.T) {
|
||||||
|
actual, err := ss.User().GetAllProfiles(&model.UserGetOptions{
|
||||||
|
Page: 0,
|
||||||
|
PerPage: 10,
|
||||||
|
Active: true,
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, []*model.User{
|
||||||
|
sanitized(u1),
|
||||||
|
sanitized(u2),
|
||||||
|
sanitized(u3),
|
||||||
|
sanitized(u4),
|
||||||
|
sanitized(u5),
|
||||||
|
}, actual)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("try to filter to active and inactive", func(t *testing.T) {
|
||||||
|
actual, err := ss.User().GetAllProfiles(&model.UserGetOptions{
|
||||||
|
Page: 0,
|
||||||
|
PerPage: 10,
|
||||||
|
Inactive: true,
|
||||||
|
Active: true,
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, []*model.User{
|
||||||
|
sanitized(u6),
|
||||||
|
sanitized(u7),
|
||||||
|
}, actual)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testUserStoreGetProfiles(t *testing.T, ss store.Store) {
|
func testUserStoreGetProfiles(t *testing.T, ss store.Store) {
|
||||||
@@ -655,6 +685,36 @@ func testUserStoreGetProfiles(t *testing.T, ss store.Store) {
|
|||||||
sanitized(u5),
|
sanitized(u5),
|
||||||
}, actual)
|
}, actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("filter to active", func(t *testing.T) {
|
||||||
|
actual, err := ss.User().GetProfiles(&model.UserGetOptions{
|
||||||
|
InTeamId: teamId,
|
||||||
|
Page: 0,
|
||||||
|
PerPage: 10,
|
||||||
|
Active: true,
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, []*model.User{
|
||||||
|
sanitized(u1),
|
||||||
|
sanitized(u2),
|
||||||
|
sanitized(u3),
|
||||||
|
sanitized(u4),
|
||||||
|
}, actual)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("try to filter to active and inactive", func(t *testing.T) {
|
||||||
|
actual, err := ss.User().GetProfiles(&model.UserGetOptions{
|
||||||
|
InTeamId: teamId,
|
||||||
|
Page: 0,
|
||||||
|
PerPage: 10,
|
||||||
|
Inactive: true,
|
||||||
|
Active: true,
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, []*model.User{
|
||||||
|
sanitized(u5),
|
||||||
|
}, actual)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testUserStoreGetProfilesInChannel(t *testing.T, ss store.Store) {
|
func testUserStoreGetProfilesInChannel(t *testing.T, ss store.Store) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user