summaryrefslogtreecommitdiffstats
path: root/store
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 /store
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 'store')
-rw-r--r--store/sqlstore/user_store.go49
-rw-r--r--store/store.go1
-rw-r--r--store/storetest/mocks/UserStore.go16
-rw-r--r--store/storetest/user_store.go77
4 files changed, 142 insertions, 1 deletions
diff --git a/store/sqlstore/user_store.go b/store/sqlstore/user_store.go
index 04e0c994c..5e84af930 100644
--- a/store/sqlstore/user_store.go
+++ b/store/sqlstore/user_store.go
@@ -412,7 +412,18 @@ func (us SqlUserStore) GetProfilesInChannel(channelId string, offset int, limit
return store.Do(func(result *store.StoreResult) {
var users []*model.User
- query := "SELECT Users.* FROM Users, ChannelMembers WHERE ChannelMembers.ChannelId = :ChannelId AND Users.Id = ChannelMembers.UserId ORDER BY Users.Username ASC LIMIT :Limit OFFSET :Offset"
+ query := `
+ SELECT
+ Users.*
+ FROM
+ Users, ChannelMembers
+ WHERE
+ ChannelMembers.ChannelId = :ChannelId
+ AND Users.Id = ChannelMembers.UserId
+ ORDER BY
+ Users.Username ASC
+ LIMIT :Limit OFFSET :Offset
+ `
if _, err := us.GetReplica().Select(&users, query, map[string]interface{}{"ChannelId": channelId, "Offset": offset, "Limit": limit}); err != nil {
result.Err = model.NewAppError("SqlUserStore.GetProfilesInChannel", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
@@ -427,6 +438,42 @@ func (us SqlUserStore) GetProfilesInChannel(channelId string, offset int, limit
})
}
+func (us SqlUserStore) GetProfilesInChannelByStatus(channelId string, offset int, limit int) store.StoreChannel {
+ return store.Do(func(result *store.StoreResult) {
+ var users []*model.User
+
+ query := `
+ SELECT
+ Users.*
+ FROM Users
+ INNER JOIN ChannelMembers ON Users.Id = ChannelMembers.UserId
+ LEFT JOIN Status ON Users.Id = Status.UserId
+ WHERE
+ ChannelMembers.ChannelId = :ChannelId
+ ORDER BY
+ CASE Status
+ WHEN 'online' THEN 1
+ WHEN 'away' THEN 2
+ WHEN 'dnd' THEN 3
+ ELSE 4
+ END,
+ Users.Username ASC
+ LIMIT :Limit OFFSET :Offset
+ `
+
+ if _, err := us.GetReplica().Select(&users, query, map[string]interface{}{"ChannelId": channelId, "Offset": offset, "Limit": limit}); err != nil {
+ result.Err = model.NewAppError("SqlUserStore.GetProfilesInChannelByStatus", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
+ } else {
+
+ for _, u := range users {
+ u.Sanitize(map[string]bool{})
+ }
+
+ result.Data = users
+ }
+ })
+}
+
func (us SqlUserStore) GetAllProfilesInChannel(channelId string, allowFromCache bool) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
if allowFromCache {
diff --git a/store/store.go b/store/store.go
index 0394277b7..671da02bd 100644
--- a/store/store.go
+++ b/store/store.go
@@ -216,6 +216,7 @@ type UserStore interface {
InvalidateProfilesInChannelCacheByUser(userId string)
InvalidateProfilesInChannelCache(channelId string)
GetProfilesInChannel(channelId string, offset int, limit int) StoreChannel
+ GetProfilesInChannelByStatus(channelId string, offset int, limit int) StoreChannel
GetAllProfilesInChannel(channelId string, allowFromCache bool) StoreChannel
GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int) StoreChannel
GetProfilesWithoutTeam(offset int, limit int) StoreChannel
diff --git a/store/storetest/mocks/UserStore.go b/store/storetest/mocks/UserStore.go
index 2f921ae6e..369a29e7a 100644
--- a/store/storetest/mocks/UserStore.go
+++ b/store/storetest/mocks/UserStore.go
@@ -354,6 +354,22 @@ func (_m *UserStore) GetProfilesInChannel(channelId string, offset int, limit in
return r0
}
+// GetProfilesInChannelByStatus provides a mock function with given fields: channelId, offset, limit
+func (_m *UserStore) GetProfilesInChannelByStatus(channelId string, offset int, limit int) store.StoreChannel {
+ ret := _m.Called(channelId, offset, limit)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(string, int, int) store.StoreChannel); ok {
+ r0 = rf(channelId, offset, limit)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// GetProfilesNotInChannel provides a mock function with given fields: teamId, channelId, offset, limit
func (_m *UserStore) GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int) store.StoreChannel {
ret := _m.Called(teamId, channelId, offset, limit)
diff --git a/store/storetest/user_store.go b/store/storetest/user_store.go
index 47f04d1bb..2fd7d4190 100644
--- a/store/storetest/user_store.go
+++ b/store/storetest/user_store.go
@@ -25,6 +25,7 @@ func TestUserStore(t *testing.T, ss store.Store) {
t.Run("GetAllProfiles", func(t *testing.T) { testUserStoreGetAllProfiles(t, ss) })
t.Run("GetProfiles", func(t *testing.T) { testUserStoreGetProfiles(t, ss) })
t.Run("GetProfilesInChannel", func(t *testing.T) { testUserStoreGetProfilesInChannel(t, ss) })
+ t.Run("GetProfilesInChannelByStatus", func(t *testing.T) { testUserStoreGetProfilesInChannelByStatus(t, ss) })
t.Run("GetProfilesWithoutTeam", func(t *testing.T) { testUserStoreGetProfilesWithoutTeam(t, ss) })
t.Run("GetAllProfilesInChannel", func(t *testing.T) { testUserStoreGetAllProfilesInChannel(t, ss) })
t.Run("GetProfilesNotInChannel", func(t *testing.T) { testUserStoreGetProfilesNotInChannel(t, ss) })
@@ -464,6 +465,82 @@ func testUserStoreGetProfilesInChannel(t *testing.T, ss store.Store) {
}
}
+func testUserStoreGetProfilesInChannelByStatus(t *testing.T, ss store.Store) {
+ teamId := model.NewId()
+
+ u1 := &model.User{}
+ u1.Email = model.NewId()
+ store.Must(ss.User().Save(u1))
+ store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}, -1))
+
+ u2 := &model.User{}
+ u2.Email = model.NewId()
+ store.Must(ss.User().Save(u2))
+ store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id}, -1))
+
+ c1 := model.Channel{}
+ c1.TeamId = teamId
+ c1.DisplayName = "Profiles in channel"
+ c1.Name = "profiles-" + model.NewId()
+ c1.Type = model.CHANNEL_OPEN
+
+ c2 := model.Channel{}
+ c2.TeamId = teamId
+ c2.DisplayName = "Profiles in private"
+ c2.Name = "profiles-" + model.NewId()
+ c2.Type = model.CHANNEL_PRIVATE
+
+ store.Must(ss.Channel().Save(&c1, -1))
+ store.Must(ss.Channel().Save(&c2, -1))
+
+ m1 := model.ChannelMember{}
+ m1.ChannelId = c1.Id
+ m1.UserId = u1.Id
+ m1.NotifyProps = model.GetDefaultChannelNotifyProps()
+
+ m2 := model.ChannelMember{}
+ m2.ChannelId = c1.Id
+ m2.UserId = u2.Id
+ m2.NotifyProps = model.GetDefaultChannelNotifyProps()
+
+ m3 := model.ChannelMember{}
+ m3.ChannelId = c2.Id
+ m3.UserId = u1.Id
+ m3.NotifyProps = model.GetDefaultChannelNotifyProps()
+
+ store.Must(ss.Channel().SaveMember(&m1))
+ store.Must(ss.Channel().SaveMember(&m2))
+ store.Must(ss.Channel().SaveMember(&m3))
+
+ if r1 := <-ss.User().GetProfilesInChannelByStatus(c1.Id, 0, 100); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ users := r1.Data.([]*model.User)
+ if len(users) != 2 {
+ t.Fatal("invalid returned users")
+ }
+
+ found := false
+ for _, u := range users {
+ if u.Id == u1.Id {
+ found = true
+ }
+ }
+
+ if !found {
+ t.Fatal("missing user")
+ }
+ }
+
+ if r2 := <-ss.User().GetProfilesInChannelByStatus(c2.Id, 0, 1); r2.Err != nil {
+ t.Fatal(r2.Err)
+ } else {
+ if len(r2.Data.([]*model.User)) != 1 {
+ t.Fatal("should have returned only 1 user")
+ }
+ }
+}
+
func testUserStoreGetProfilesWithoutTeam(t *testing.T, ss store.Store) {
teamId := model.NewId()