[MM-13746] Add GetTeamMembersForUser and GetChannelMembersForUser apis (#10269)

* Add GetTeamMembersForUser and GetChannelMembersForUser apis

* Address comments

* Fix tests

* Fix test

* Fix comment

* Fix minimum server version

* Change to []*model.ChannelMember

* Fix panic, add more tests

* Remove print statement
This commit is contained in:
Shobhit Gupta
2019-02-23 11:41:19 -08:00
committed by Lev
parent 0e50ec6a35
commit b4d645f121
15 changed files with 373 additions and 0 deletions

View File

@@ -1923,6 +1923,21 @@ func (s SqlChannelStore) GetMembersForUser(teamId string, userId string) store.S
})
}
func (s SqlChannelStore) GetMembersForUserWithPagination(teamId, userId string, page, perPage int) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
var dbMembers channelMemberWithSchemeRolesList
offset := page * perPage
_, err := s.GetReplica().Select(&dbMembers, CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE ChannelMembers.UserId = :UserId Limit :Limit Offset :Offset", map[string]interface{}{"TeamId": teamId, "UserId": userId, "Limit": perPage, "Offset": offset})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetMembersForUserWithPagination", "store.sql_channel.get_members.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error(), http.StatusInternalServerError)
return
}
result.Data = dbMembers.ToModel()
})
}
func (s SqlChannelStore) AutocompleteInTeam(teamId string, term string, includeDeleted bool) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
deleteFilter := "AND c.DeleteAt = 0"

View File

@@ -670,6 +670,20 @@ func (s SqlTeamStore) GetTeamsForUser(userId string) store.StoreChannel {
})
}
func (s SqlTeamStore) GetTeamsForUserWithPagination(userId string, page, perPage int) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
var dbMembers teamMemberWithSchemeRolesList
offset := page * perPage
_, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.UserId = :UserId Limit :Limit Offset :Offset", map[string]interface{}{"UserId": userId, "Limit": perPage, "Offset": offset})
if err != nil {
result.Err = model.NewAppError("SqlTeamStore.GetTeamsForUserWithPagination", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
return
}
result.Data = dbMembers.ToModel()
})
}
func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
var data []*model.ChannelUnread

View File

@@ -104,6 +104,7 @@ type TeamStore interface {
GetTotalMemberCount(teamId string) StoreChannel
GetActiveMemberCount(teamId string) StoreChannel
GetTeamsForUser(userId string) StoreChannel
GetTeamsForUserWithPagination(userId string, page, perPage int) StoreChannel
GetChannelUnreadsForAllTeams(excludeTeamId, userId string) StoreChannel
GetChannelUnreadsForTeam(teamId, userId string) StoreChannel
RemoveMember(teamId string, userId string) StoreChannel
@@ -169,6 +170,7 @@ type ChannelStore interface {
IncrementMentionCount(channelId string, userId string) StoreChannel
AnalyticsTypeCount(teamId string, channelType string) StoreChannel
GetMembersForUser(teamId string, userId string) StoreChannel
GetMembersForUserWithPagination(teamId, userId string, page, perPage int) StoreChannel
AutocompleteInTeam(teamId string, term string, includeDeleted bool) StoreChannel
AutocompleteInTeamForSearch(teamId string, userId string, term string, includeDeleted bool) StoreChannel
SearchAllChannels(term string, includeDeleted bool) StoreChannel

View File

@@ -57,6 +57,7 @@ func TestChannelStore(t *testing.T, ss store.Store, s SqlSupplier) {
t.Run("GetPublicChannelsByIdsForTeam", func(t *testing.T) { testChannelStoreGetPublicChannelsByIdsForTeam(t, ss) })
t.Run("GetChannelCounts", func(t *testing.T) { testChannelStoreGetChannelCounts(t, ss) })
t.Run("GetMembersForUser", func(t *testing.T) { testChannelStoreGetMembersForUser(t, ss) })
t.Run("GetMembersForUserWithPagination", func(t *testing.T) { testChannelStoreGetMembersForUserWithPagination(t, ss) })
t.Run("UpdateLastViewedAt", func(t *testing.T) { testChannelStoreUpdateLastViewedAt(t, ss) })
t.Run("IncrementMentionCount", func(t *testing.T) { testChannelStoreIncrementMentionCount(t, ss) })
t.Run("UpdateChannelMember", func(t *testing.T) { testUpdateChannelMember(t, ss) })
@@ -1419,6 +1420,50 @@ func testChannelStoreGetMembersForUser(t *testing.T, ss store.Store) {
}
}
func testChannelStoreGetMembersForUserWithPagination(t *testing.T, ss store.Store) {
t1 := model.Team{}
t1.DisplayName = "Name"
t1.Name = model.NewId()
t1.Email = MakeEmail()
t1.Type = model.TEAM_OPEN
store.Must(ss.Team().Save(&t1))
o1 := model.Channel{}
o1.TeamId = t1.Id
o1.DisplayName = "Channel1"
o1.Name = "zz" + model.NewId() + "b"
o1.Type = model.CHANNEL_OPEN
store.Must(ss.Channel().Save(&o1, -1))
o2 := model.Channel{}
o2.TeamId = o1.TeamId
o2.DisplayName = "Channel2"
o2.Name = "zz" + model.NewId() + "b"
o2.Type = model.CHANNEL_OPEN
store.Must(ss.Channel().Save(&o2, -1))
m1 := model.ChannelMember{}
m1.ChannelId = o1.Id
m1.UserId = model.NewId()
m1.NotifyProps = model.GetDefaultChannelNotifyProps()
store.Must(ss.Channel().SaveMember(&m1))
m2 := model.ChannelMember{}
m2.ChannelId = o2.Id
m2.UserId = m1.UserId
m2.NotifyProps = model.GetDefaultChannelNotifyProps()
store.Must(ss.Channel().SaveMember(&m2))
cresult := <-ss.Channel().GetMembersForUserWithPagination(o1.TeamId, m1.UserId, 0, 1)
members := cresult.Data.(*model.ChannelMembers)
assert.Len(t, *members, 1)
cresult = <-ss.Channel().GetMembersForUserWithPagination(o1.TeamId, m1.UserId, 1, 1)
members = cresult.Data.(*model.ChannelMembers)
assert.Len(t, *members, 1)
}
func testChannelStoreUpdateLastViewedAt(t *testing.T, ss store.Store) {
o1 := model.Channel{}
o1.TeamId = model.NewId()

View File

@@ -544,6 +544,22 @@ func (_m *ChannelStore) GetMembersForUser(teamId string, userId string) store.St
return r0
}
// GetMembersForUserWithPagination provides a mock function with given fields: teamId, userId, page, perPage
func (_m *ChannelStore) GetMembersForUserWithPagination(teamId string, userId string, page int, perPage int) store.StoreChannel {
ret := _m.Called(teamId, userId, page, perPage)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, string, int, int) store.StoreChannel); ok {
r0 = rf(teamId, userId, page, perPage)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
}
}
return r0
}
// GetMoreChannels provides a mock function with given fields: teamId, userId, offset, limit
func (_m *ChannelStore) GetMoreChannels(teamId string, userId string, offset int, limit int) store.StoreChannel {
ret := _m.Called(teamId, userId, offset, limit)

View File

@@ -0,0 +1,26 @@
// Code generated by mockery v1.0.0. DO NOT EDIT.
// Regenerate this file using `make store-mocks`.
package mocks
import mock "github.com/stretchr/testify/mock"
// JSONSerializable is an autogenerated mock type for the JSONSerializable type
type JSONSerializable struct {
mock.Mock
}
// ToJson provides a mock function with given fields:
func (_m *JSONSerializable) ToJson() string {
ret := _m.Called()
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
return r0
}

View File

@@ -349,6 +349,22 @@ func (_m *TeamStore) GetTeamsForUser(userId string) store.StoreChannel {
return r0
}
// GetTeamsForUserWithPagination provides a mock function with given fields: userId, page, perPage
func (_m *TeamStore) GetTeamsForUserWithPagination(userId string, page int, perPage int) store.StoreChannel {
ret := _m.Called(userId, page, perPage)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, int, int) store.StoreChannel); ok {
r0 = rf(userId, page, perPage)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
}
}
return r0
}
// GetTotalMemberCount provides a mock function with given fields: teamId
func (_m *TeamStore) GetTotalMemberCount(teamId string) store.StoreChannel {
ret := _m.Called(teamId)

View File

@@ -47,6 +47,7 @@ func TestTeamStore(t *testing.T, ss store.Store) {
t.Run("AnalyticsGetTeamCountForScheme", func(t *testing.T) { testTeamStoreAnalyticsGetTeamCountForScheme(t, ss) })
t.Run("GetAllForExportAfter", func(t *testing.T) { testTeamStoreGetAllForExportAfter(t, ss) })
t.Run("GetTeamMembersForExport", func(t *testing.T) { testTeamStoreGetTeamMembersForExport(t, ss) })
t.Run("GetTeamsForUserWithPagination", func(t *testing.T) { testTeamMembersWithPagination(t, ss) })
}
func testTeamStoreSave(t *testing.T, ss store.Store) {
@@ -668,6 +669,62 @@ func testTeamMembers(t *testing.T, ss store.Store) {
}
}
func testTeamMembersWithPagination(t *testing.T, ss store.Store) {
teamId1 := model.NewId()
teamId2 := model.NewId()
m1 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
m2 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
m3 := &model.TeamMember{TeamId: teamId2, UserId: model.NewId()}
r1 := <-ss.Team().SaveMember(m1, -1)
require.Nil(t, r1.Err)
store.Must(ss.Team().SaveMember(m2, -1))
store.Must(ss.Team().SaveMember(m3, -1))
r1 = <-ss.Team().GetTeamsForUserWithPagination(m1.UserId, 0, 1)
require.Nil(t, r1.Err)
ms := r1.Data.([]*model.TeamMember)
require.Len(t, ms, 1)
require.Equal(t, m1.TeamId, ms[0].TeamId)
r1 = <-ss.Team().RemoveMember(teamId1, m1.UserId)
require.Nil(t, r1.Err)
r1 = <-ss.Team().GetMembers(teamId1, 0, 100)
require.Nil(t, r1.Err)
ms = r1.Data.([]*model.TeamMember)
require.Len(t, ms, 1)
require.Equal(t, m2.UserId, ms[0].UserId)
store.Must(ss.Team().SaveMember(m1, -1))
r1 = <-ss.Team().RemoveAllMembersByTeam(teamId1)
require.Nil(t, r1.Err)
uid := model.NewId()
m4 := &model.TeamMember{TeamId: teamId1, UserId: uid}
m5 := &model.TeamMember{TeamId: teamId2, UserId: uid}
store.Must(ss.Team().SaveMember(m4, -1))
store.Must(ss.Team().SaveMember(m5, -1))
r1 = <-ss.Team().GetTeamsForUserWithPagination(uid, 0, 1)
require.Nil(t, r1.Err)
ms = r1.Data.([]*model.TeamMember)
require.Len(t, ms, 1)
r1 = <-ss.Team().RemoveAllMembersByUser(uid)
require.Nil(t, r1.Err)
r1 = <-ss.Team().GetTeamsForUserWithPagination(uid, 1, 1)
require.Nil(t, r1.Err)
ms = r1.Data.([]*model.TeamMember)
require.Len(t, ms, 0)
}
func testSaveTeamMemberMaxMembers(t *testing.T, ss store.Store) {
maxUsersPerTeam := 5