summaryrefslogtreecommitdiffstats
path: root/api4
diff options
context:
space:
mode:
authorStephen Kiers <stephen@stephenkiers.com>2018-03-09 05:48:30 -0700
committerJoram Wilander <jwawilander@gmail.com>2018-03-09 07:48:30 -0500
commit302dae5bb982aad14324a4df61a018557f3dd24e (patch)
tree8e1b8b52b3c717dd90ade42ad6dd1e3a265d9903 /api4
parent31532f7feb4055f42538e23d48d4f0c941609db1 (diff)
downloadchat-302dae5bb982aad14324a4df61a018557f3dd24e.tar.gz
chat-302dae5bb982aad14324a4df61a018557f3dd24e.tar.bz2
chat-302dae5bb982aad14324a4df61a018557f3dd24e.zip
MM-9274- Sort Users in Channel by status (#8181)
* sort by lastActivity * added status ordering to Users * sort offline before dnd * remove data not needed * added seperate call for when order=‘status’ is on GetUser request * remove PrintLn * styling fix * remove mistake * mistake 2 * better comment * explicit if statemnt * writing tests * removed manually added mocks * generated mock * ICU-668 Added unit tests * style fix * sort by lastActivity * added status ordering to Users * sort offline before dnd * remove data not needed * added seperate call for when order=‘status’ is on GetUser request * remove PrintLn * styling fix * remove mistake * mistake 2 * better comment * explicit if statemnt * writing tests * removed manually added mocks * generated mock * ICU-668 Added unit tests * style fix * reverse dnd and offline * Fixed app.SaveStatusAndBroadcast * Fixed incorrect merge * Fixing incorrect merge again
Diffstat (limited to 'api4')
-rw-r--r--api4/apitestlib.go16
-rw-r--r--api4/user.go14
-rw-r--r--api4/user_test.go143
3 files changed, 170 insertions, 3 deletions
diff --git a/api4/apitestlib.go b/api4/apitestlib.go
index 2bb80ddfb..6edd37812 100644
--- a/api4/apitestlib.go
+++ b/api4/apitestlib.go
@@ -467,6 +467,22 @@ func (me *TestHelper) LinkUserToTeam(user *model.User, team *model.Team) {
utils.EnableDebugLogForTest()
}
+func (me *TestHelper) AddUserToChannel(user *model.User, channel *model.Channel) *model.ChannelMember {
+ utils.DisableDebugLogForTest()
+
+ member, err := me.App.AddUserToChannel(user, channel)
+ if err != nil {
+ l4g.Error(err.Error())
+ l4g.Close()
+ time.Sleep(time.Second)
+ panic(err)
+ }
+
+ utils.EnableDebugLogForTest()
+
+ return member
+}
+
func (me *TestHelper) GenerateTestEmail() string {
if me.App.Config().EmailSettings.SMTPServer != "dockerhost" && os.Getenv("CI_INBUCKET_PORT") == "" {
return strings.ToLower("success+" + model.NewId() + "@simulator.amazonses.com")
diff --git a/api4/user.go b/api4/user.go
index f82a6e3d5..8f8f08c75 100644
--- a/api4/user.go
+++ b/api4/user.go
@@ -290,16 +290,21 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if sort != "" && sort != "last_activity_at" && sort != "create_at" {
+ if sort != "" && sort != "last_activity_at" && sort != "create_at" && sort != "status" {
c.SetInvalidUrlParam("sort")
return
}
// Currently only supports sorting on a team
+ // or sort="status" on inChannelId
if (sort == "last_activity_at" || sort == "create_at") && (inTeamId == "" || notInTeamId != "" || inChannelId != "" || notInChannelId != "" || withoutTeam != "") {
c.SetInvalidUrlParam("sort")
return
}
+ if sort == "status" && inChannelId == "" {
+ c.SetInvalidUrlParam("sort")
+ return
+ }
var profiles []*model.User
var err *model.AppError
@@ -355,8 +360,11 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
return
}
-
- profiles, err = c.App.GetUsersInChannelPage(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
+ if sort == "status" {
+ profiles, err = c.App.GetUsersInChannelPageByStatus(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
+ } else {
+ profiles, err = c.App.GetUsersInChannelPage(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
+ }
} else {
// No permission check required
diff --git a/api4/user_test.go b/api4/user_test.go
index 4613a8ea9..f04cd6ab2 100644
--- a/api4/user_test.go
+++ b/api4/user_test.go
@@ -2650,3 +2650,146 @@ func TestUserAccessTokenDisableConfig(t *testing.T) {
_, resp = Client.GetMe("")
CheckNoError(t, resp)
}
+
+func TestGetUsersByStatus(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ team, err := th.App.CreateTeam(&model.Team{
+ DisplayName: "dn_" + model.NewId(),
+ Name: GenerateTestTeamName(),
+ Email: th.GenerateTestEmail(),
+ Type: model.TEAM_OPEN,
+ })
+ if err != nil {
+ t.Fatalf("failed to create team: %v", err)
+ }
+
+ channel, err := th.App.CreateChannel(&model.Channel{
+ DisplayName: "dn_" + model.NewId(),
+ Name: "name_" + model.NewId(),
+ Type: model.CHANNEL_OPEN,
+ TeamId: team.Id,
+ CreatorId: model.NewId(),
+ }, false)
+ if err != nil {
+ t.Fatalf("failed to create channel: %v", err)
+ }
+
+ createUserWithStatus := func(username string, status string) *model.User {
+ id := model.NewId()
+
+ user, err := th.App.CreateUser(&model.User{
+ Email: "success+" + id + "@simulator.amazonses.com",
+ Username: "un_" + username + "_" + id,
+ Nickname: "nn_" + id,
+ Password: "Password1",
+ })
+ if err != nil {
+ t.Fatalf("failed to create user: %v", err)
+ }
+
+ th.LinkUserToTeam(user, team)
+ th.AddUserToChannel(user, channel)
+
+ th.App.SaveAndBroadcastStatus(&model.Status{
+ UserId: user.Id,
+ Status: status,
+ Manual: true,
+ })
+
+ return user
+ }
+
+ // Creating these out of order in case that affects results
+ offlineUser1 := createUserWithStatus("offline1", model.STATUS_OFFLINE)
+ offlineUser2 := createUserWithStatus("offline2", model.STATUS_OFFLINE)
+ awayUser1 := createUserWithStatus("away1", model.STATUS_AWAY)
+ awayUser2 := createUserWithStatus("away2", model.STATUS_AWAY)
+ onlineUser1 := createUserWithStatus("online1", model.STATUS_ONLINE)
+ onlineUser2 := createUserWithStatus("online2", model.STATUS_ONLINE)
+ dndUser1 := createUserWithStatus("dnd1", model.STATUS_DND)
+ dndUser2 := createUserWithStatus("dnd2", model.STATUS_DND)
+
+ client := th.CreateClient()
+ if _, resp := client.Login(onlineUser2.Username, "Password1"); resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ t.Run("sorting by status then alphabetical", func(t *testing.T) {
+ usersByStatus, resp := client.GetUsersInChannelByStatus(channel.Id, 0, 8, "")
+ if resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ expectedUsersByStatus := []*model.User{
+ onlineUser1,
+ onlineUser2,
+ awayUser1,
+ awayUser2,
+ dndUser1,
+ dndUser2,
+ offlineUser1,
+ offlineUser2,
+ }
+
+ if len(usersByStatus) != len(expectedUsersByStatus) {
+ t.Fatalf("received only %v users, expected %v", len(usersByStatus), len(expectedUsersByStatus))
+ }
+
+ for i := range usersByStatus {
+ if usersByStatus[i].Id != expectedUsersByStatus[i].Id {
+ t.Fatalf("received user %v at index %v, expected %v", usersByStatus[i].Username, i, expectedUsersByStatus[i].Username)
+ }
+ }
+ })
+
+ t.Run("paging", func(t *testing.T) {
+ usersByStatus, resp := client.GetUsersInChannelByStatus(channel.Id, 0, 3, "")
+ if resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ if len(usersByStatus) != 3 {
+ t.Fatal("received too many users")
+ }
+
+ if usersByStatus[0].Id != onlineUser1.Id && usersByStatus[1].Id != onlineUser2.Id {
+ t.Fatal("expected to receive online users first")
+ }
+
+ if usersByStatus[2].Id != awayUser1.Id {
+ t.Fatal("expected to receive away users second")
+ }
+
+ usersByStatus, resp = client.GetUsersInChannelByStatus(channel.Id, 1, 3, "")
+ if resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ if usersByStatus[0].Id != awayUser2.Id {
+ t.Fatal("expected to receive away users second")
+ }
+
+ if usersByStatus[1].Id != dndUser1.Id && usersByStatus[2].Id != dndUser2.Id {
+ t.Fatal("expected to receive dnd users third")
+ }
+
+ usersByStatus, resp = client.GetUsersInChannelByStatus(channel.Id, 1, 4, "")
+ if resp.Error != nil {
+ t.Fatal(resp.Error)
+ }
+
+ if len(usersByStatus) != 4 {
+ t.Fatal("received too many users")
+ }
+
+ if usersByStatus[0].Id != dndUser1.Id && usersByStatus[1].Id != dndUser2.Id {
+ t.Fatal("expected to receive dnd users third")
+ }
+
+ if usersByStatus[2].Id != offlineUser1.Id && usersByStatus[3].Id != offlineUser2.Id {
+ t.Fatal("expected to receive offline users last")
+ }
+ })
+}