diff options
author | Joram Wilander <jwawilander@gmail.com> | 2016-11-04 12:27:19 -0400 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-11-04 12:27:19 -0400 |
commit | 00787974d0a87b1a54f15cf75d2dab398546b87e (patch) | |
tree | 6f41b56b10183b6543309b790cd13b1fbf7559af | |
parent | 263f29068386cdd3b5393e00ce97f776532c723f (diff) | |
download | chat-00787974d0a87b1a54f15cf75d2dab398546b87e.tar.gz chat-00787974d0a87b1a54f15cf75d2dab398546b87e.tar.bz2 chat-00787974d0a87b1a54f15cf75d2dab398546b87e.zip |
PLT-4481 Fix member count for team user lists and channel invite list (#4422)
* Fix member count for team user lists and channel invite list
* Fix client unit test
-rw-r--r-- | api/team.go | 21 | ||||
-rw-r--r-- | api/team_test.go | 28 | ||||
-rw-r--r-- | model/team_stats.go | 5 | ||||
-rw-r--r-- | store/sql_team_store.go | 35 | ||||
-rw-r--r-- | store/sql_team_store_test.go | 32 | ||||
-rw-r--r-- | store/store.go | 3 | ||||
-rw-r--r-- | webapp/components/admin_console/team_users.jsx | 6 | ||||
-rw-r--r-- | webapp/components/channel_invite_modal.jsx | 6 | ||||
-rw-r--r-- | webapp/components/member_list_team.jsx | 4 | ||||
-rw-r--r-- | webapp/stores/user_store.jsx | 21 | ||||
-rw-r--r-- | webapp/tests/client_team.test.jsx | 2 |
11 files changed, 130 insertions, 33 deletions
diff --git a/api/team.go b/api/team.go index 5a8c605ef..b1a1ae3cd 100644 --- a/api/team.go +++ b/api/team.go @@ -902,16 +902,27 @@ func getTeamStats(c *Context, w http.ResponseWriter, r *http.Request) { } } - if result := <-Srv.Store.Team().GetMemberCount(c.TeamId); result.Err != nil { + tchan := Srv.Store.Team().GetTotalMemberCount(c.TeamId) + achan := Srv.Store.Team().GetActiveMemberCount(c.TeamId) + + stats := &model.TeamStats{} + stats.TeamId = c.TeamId + + if result := <-tchan; result.Err != nil { c.Err = result.Err return } else { - stats := &model.TeamStats{} - stats.MemberCount = result.Data.(int64) - stats.TeamId = c.TeamId - w.Write([]byte(stats.ToJson())) + stats.TotalMemberCount = result.Data.(int64) + } + + if result := <-achan; result.Err != nil { + c.Err = result.Err return + } else { + stats.ActiveMemberCount = result.Data.(int64) } + + w.Write([]byte(stats.ToJson())) } func importTeam(c *Context, w http.ResponseWriter, r *http.Request) { diff --git a/api/team_test.go b/api/team_test.go index bac0228ad..ec3c40e51 100644 --- a/api/team_test.go +++ b/api/team_test.go @@ -706,7 +706,25 @@ func TestGetTeamStats(t *testing.T) { if result, err := th.SystemAdminClient.GetTeamStats(th.BasicTeam.Id); err != nil { t.Fatal(err) } else { - if result.Data.(*model.TeamStats).MemberCount != 2 { + if result.Data.(*model.TeamStats).TotalMemberCount != 2 { + t.Fatal("wrong count") + } + + if result.Data.(*model.TeamStats).ActiveMemberCount != 2 { + t.Fatal("wrong count") + } + } + + th.SystemAdminClient.Must(th.SystemAdminClient.UpdateActive(th.BasicUser2.Id, false)) + + if result, err := th.SystemAdminClient.GetTeamStats(th.BasicTeam.Id); err != nil { + t.Fatal(err) + } else { + if result.Data.(*model.TeamStats).TotalMemberCount != 2 { + t.Fatal("wrong count") + } + + if result.Data.(*model.TeamStats).ActiveMemberCount != 1 { t.Fatal("wrong count") } } @@ -714,7 +732,11 @@ func TestGetTeamStats(t *testing.T) { if result, err := th.SystemAdminClient.GetTeamStats("junk"); err != nil { t.Fatal(err) } else { - if result.Data.(*model.TeamStats).MemberCount != 0 { + if result.Data.(*model.TeamStats).TotalMemberCount != 0 { + t.Fatal("wrong count") + } + + if result.Data.(*model.TeamStats).ActiveMemberCount != 0 { t.Fatal("wrong count") } } @@ -722,7 +744,7 @@ func TestGetTeamStats(t *testing.T) { if result, err := th.SystemAdminClient.GetTeamStats(th.BasicTeam.Id); err != nil { t.Fatal(err) } else { - if result.Data.(*model.TeamStats).MemberCount != 2 { + if result.Data.(*model.TeamStats).TotalMemberCount != 2 { t.Fatal("wrong count") } } diff --git a/model/team_stats.go b/model/team_stats.go index 8634c3d1b..9042e76d6 100644 --- a/model/team_stats.go +++ b/model/team_stats.go @@ -9,8 +9,9 @@ import ( ) type TeamStats struct { - TeamId string `json:"team_id"` - MemberCount int64 `json:"member_count"` + TeamId string `json:"team_id"` + TotalMemberCount int64 `json:"total_member_count"` + ActiveMemberCount int64 `json:"active_member_count"` } func (o *TeamStats) ToJson() string { diff --git a/store/sql_team_store.go b/store/sql_team_store.go index cc425ccf6..00f1f5c61 100644 --- a/store/sql_team_store.go +++ b/store/sql_team_store.go @@ -467,7 +467,7 @@ func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int) StoreChan return storeChannel } -func (s SqlTeamStore) GetMemberCount(teamId string) StoreChannel { +func (s SqlTeamStore) GetTotalMemberCount(teamId string) StoreChannel { storeChannel := make(StoreChannel, 1) go func() { @@ -482,10 +482,39 @@ func (s SqlTeamStore) GetMemberCount(teamId string) StoreChannel { WHERE TeamMembers.UserId = Users.Id AND TeamMembers.TeamId = :TeamId - AND TeamMembers.DeleteAt = 0 + AND TeamMembers.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId}) + if err != nil { + result.Err = model.NewLocAppError("SqlTeamStore.GetTotalMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error()) + } else { + result.Data = count + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (s SqlTeamStore) GetActiveMemberCount(teamId string) StoreChannel { + storeChannel := make(StoreChannel, 1) + + go func() { + result := StoreResult{} + + count, err := s.GetReplica().SelectInt(` + SELECT + count(*) + FROM + TeamMembers, + Users + WHERE + TeamMembers.UserId = Users.Id + AND TeamMembers.TeamId = :TeamId + AND TeamMembers.DeleteAt = 0 AND Users.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId}) if err != nil { - result.Err = model.NewLocAppError("SqlTeamStore.GetMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error()) + result.Err = model.NewLocAppError("SqlTeamStore.GetActiveMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error()) } else { result.Data = count } diff --git a/store/sql_team_store_test.go b/store/sql_team_store_test.go index 46215d9be..0e472a961 100644 --- a/store/sql_team_store_test.go +++ b/store/sql_team_store_test.go @@ -482,11 +482,27 @@ func TestTeamStoreMemberCount(t *testing.T) { u1.Email = model.NewId() Must(store.User().Save(u1)) + u2 := &model.User{} + u2.Email = model.NewId() + u2.DeleteAt = 1 + Must(store.User().Save(u2)) + teamId1 := model.NewId() m1 := &model.TeamMember{TeamId: teamId1, UserId: u1.Id} Must(store.Team().SaveMember(m1)) - if result := <-store.Team().GetMemberCount(teamId1); result.Err != nil { + m2 := &model.TeamMember{TeamId: teamId1, UserId: u2.Id} + Must(store.Team().SaveMember(m2)) + + if result := <-store.Team().GetTotalMemberCount(teamId1); result.Err != nil { + t.Fatal(result.Err) + } else { + if result.Data.(int64) != 2 { + t.Fatal("wrong count") + } + } + + if result := <-store.Team().GetActiveMemberCount(teamId1); result.Err != nil { t.Fatal(result.Err) } else { if result.Data.(int64) != 1 { @@ -494,10 +510,18 @@ func TestTeamStoreMemberCount(t *testing.T) { } } - m2 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()} - Must(store.Team().SaveMember(m2)) + m3 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()} + Must(store.Team().SaveMember(m3)) + + if result := <-store.Team().GetTotalMemberCount(teamId1); result.Err != nil { + t.Fatal(result.Err) + } else { + if result.Data.(int64) != 2 { + t.Fatal("wrong count") + } + } - if result := <-store.Team().GetMemberCount(teamId1); result.Err != nil { + if result := <-store.Team().GetActiveMemberCount(teamId1); result.Err != nil { t.Fatal(result.Err) } else { if result.Data.(int64) != 1 { diff --git a/store/store.go b/store/store.go index 85a1ad398..b3d87da38 100644 --- a/store/store.go +++ b/store/store.go @@ -70,7 +70,8 @@ type TeamStore interface { GetMember(teamId string, userId string) StoreChannel GetMembers(teamId string, offset int, limit int) StoreChannel GetMembersByIds(teamId string, userIds []string) StoreChannel - GetMemberCount(teamId string) StoreChannel + GetTotalMemberCount(teamId string) StoreChannel + GetActiveMemberCount(teamId string) StoreChannel GetTeamsForUser(userId string) StoreChannel RemoveMember(teamId string, userId string) StoreChannel RemoveAllMembersByTeam(teamId string) StoreChannel diff --git a/webapp/components/admin_console/team_users.jsx b/webapp/components/admin_console/team_users.jsx index 3efb242ed..fce0f18ea 100644 --- a/webapp/components/admin_console/team_users.jsx +++ b/webapp/components/admin_console/team_users.jsx @@ -49,7 +49,7 @@ export default class UserList extends React.Component { team: AdminStore.getTeam(this.props.params.team), users: [], teamMembers: TeamStore.getMembersInTeam(this.props.params.team), - total: stats.member_count, + total: stats.total_member_count, serverError: null, showPasswordModal: false, loading: true, @@ -75,7 +75,7 @@ export default class UserList extends React.Component { team: AdminStore.getTeam(nextProps.params.team), users: [], teamMembers: TeamStore.getMembersInTeam(nextProps.params.team), - total: stats.member_count + total: stats.total_member_count }); this.getTeamProfiles(nextProps.params.team); @@ -102,7 +102,7 @@ export default class UserList extends React.Component { onStatsChange() { const stats = TeamStore.getStats(this.props.params.team); - this.setState({total: stats.member_count}); + this.setState({total: stats.total_member_count}); } onUsersChange() { diff --git a/webapp/components/channel_invite_modal.jsx b/webapp/components/channel_invite_modal.jsx index 29607136c..89185435a 100644 --- a/webapp/components/channel_invite_modal.jsx +++ b/webapp/components/channel_invite_modal.jsx @@ -38,7 +38,7 @@ export default class ChannelInviteModal extends React.Component { this.state = { users: null, - total: teamStats.member_count - channelStats.member_count, + total: teamStats.active_member_count - channelStats.member_count, show: true, search: false, statusChange: false @@ -72,8 +72,8 @@ export default class ChannelInviteModal extends React.Component { const teamStats = TeamStore.getCurrentStats(); this.setState({ - users: UserStore.getProfileListNotInChannel(this.props.channel.id), - total: teamStats.member_count - channelStats.member_count + users: UserStore.getProfileListNotInChannel(this.props.channel.id, true), + total: teamStats.active_member_count - channelStats.member_count }); } diff --git a/webapp/components/member_list_team.jsx b/webapp/components/member_list_team.jsx index b32ab117d..8b23b650b 100644 --- a/webapp/components/member_list_team.jsx +++ b/webapp/components/member_list_team.jsx @@ -30,7 +30,7 @@ export default class MemberListTeam extends React.Component { this.state = { users: UserStore.getProfileListInTeam(), teamMembers: Object.assign([], TeamStore.getMembersInTeam()), - total: stats.member_count, + total: stats.total_member_count, search: false, loading: true }; @@ -67,7 +67,7 @@ export default class MemberListTeam extends React.Component { onStatsChange() { const stats = TeamStore.getCurrentStats(); - this.setState({total: stats.member_count}); + this.setState({total: stats.total_member_count}); } nextPage(page) { diff --git a/webapp/stores/user_store.jsx b/webapp/stores/user_store.jsx index bb3415a7d..71b98d2e5 100644 --- a/webapp/stores/user_store.jsx +++ b/webapp/stores/user_store.jsx @@ -320,6 +320,10 @@ class UserStoreClass extends EventEmitter { for (let i = 0; i < userIds.length; i++) { const profile = this.getProfile(userIds[i]); + if (!profile) { + continue; + } + if (skipCurrent && profile.id === currentId) { continue; } @@ -328,9 +332,7 @@ class UserStoreClass extends EventEmitter { continue; } - if (profile) { - profiles.push(profile); - } + profiles.push(profile); } return profiles; @@ -473,15 +475,22 @@ class UserStoreClass extends EventEmitter { userIds.splice(index, 1); } - getProfileListNotInChannel(channelId = ChannelStore.getCurrentId()) { + getProfileListNotInChannel(channelId = ChannelStore.getCurrentId(), skipInactive = false) { const userIds = this.profiles_not_in_channel[channelId] || []; const profiles = []; for (let i = 0; i < userIds.length; i++) { const profile = this.getProfile(userIds[i]); - if (profile) { - profiles.push(profile); + + if (!profile) { + continue; } + + if (skipInactive && profile.delete_at > 0) { + continue; + } + + profiles.push(profile); } return profiles; diff --git a/webapp/tests/client_team.test.jsx b/webapp/tests/client_team.test.jsx index 642307986..ab2e625bf 100644 --- a/webapp/tests/client_team.test.jsx +++ b/webapp/tests/client_team.test.jsx @@ -169,7 +169,7 @@ describe('Client.Team', function() { TestHelper.basicClient().getTeamStats( TestHelper.basicTeam().id, function(data) { - assert.equal(data.member_count > 0, true); + assert.equal(data.total_member_count > 0, true); done(); }, function(err) { |