diff --git a/app/analytics.go b/app/analytics.go index 0b44e2e55f..9e423be8ae 100644 --- a/app/analytics.go +++ b/app/analytics.go @@ -91,14 +91,14 @@ func (a *App) GetAnalytics(name string, teamId string) (model.AnalyticsRows, *mo dailyActiveChan := make(chan store.StoreResult, 1) go func() { - dailyActive, err := a.Srv.Store.User().AnalyticsActiveCount(DAY_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false}) + dailyActive, err := a.Srv.Store.User().AnalyticsActiveCount(DAY_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false}) dailyActiveChan <- store.StoreResult{Data: dailyActive, Err: err} close(dailyActiveChan) }() monthlyActiveChan := make(chan store.StoreResult, 1) go func() { - monthlyActive, err := a.Srv.Store.User().AnalyticsActiveCount(MONTH_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false}) + monthlyActive, err := a.Srv.Store.User().AnalyticsActiveCount(MONTH_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false}) monthlyActiveChan <- store.StoreResult{Data: monthlyActive, Err: err} close(monthlyActiveChan) }() diff --git a/app/command_loadtest.go b/app/command_loadtest.go index 6b44628ac6..d93b5ad7b0 100644 --- a/app/command_loadtest.go +++ b/app/command_loadtest.go @@ -118,6 +118,14 @@ func (me *LoadTestProvider) DoCommand(a *App, args *model.CommandArgs, message s return me.UsersCommand(a, args, message) } + if strings.HasPrefix(message, "activate_user") { + return me.ActivateUserCommand(a, args, message) + } + + if strings.HasPrefix(message, "deactivate_user") { + return me.DeActivateUserCommand(a, args, message) + } + if strings.HasPrefix(message, "channels") { return me.ChannelsCommand(a, args, message) } @@ -229,6 +237,22 @@ func (me *LoadTestProvider) SetupCommand(a *App, args *model.CommandArgs, messag return &model.CommandResponse{Text: "Created environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } +func (me *LoadTestProvider) ActivateUserCommand(a *App, args *model.CommandArgs, message string) *model.CommandResponse { + user_id := strings.TrimSpace(strings.TrimPrefix(message, "activate_user")) + if err := a.UpdateUserActive(user_id, true); err != nil { + return &model.CommandResponse{Text: "Failed to activate user", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} + } + return &model.CommandResponse{Text: "Activated user", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} +} + +func (me *LoadTestProvider) DeActivateUserCommand(a *App, args *model.CommandArgs, message string) *model.CommandResponse { + user_id := strings.TrimSpace(strings.TrimPrefix(message, "deactivate_user")) + if err := a.UpdateUserActive(user_id, false); err != nil { + return &model.CommandResponse{Text: "Failed to deactivate user", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} + } + return &model.CommandResponse{Text: "DeActivated user", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} +} + func (me *LoadTestProvider) UsersCommand(a *App, args *model.CommandArgs, message string) *model.CommandResponse { cmd := strings.TrimSpace(strings.TrimPrefix(message, "users")) diff --git a/app/diagnostics.go b/app/diagnostics.go index 56340f8da1..8be9a3581f 100644 --- a/app/diagnostics.go +++ b/app/diagnostics.go @@ -126,14 +126,14 @@ func (a *App) trackActivity() { activeUsersDailyCountChan := make(chan store.StoreResult, 1) go func() { - count, err := a.Srv.Store.User().AnalyticsActiveCount(DAY_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false}) + count, err := a.Srv.Store.User().AnalyticsActiveCount(DAY_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false}) activeUsersDailyCountChan <- store.StoreResult{Data: count, Err: err} close(activeUsersDailyCountChan) }() activeUsersMonthlyCountChan := make(chan store.StoreResult, 1) go func() { - count, err := a.Srv.Store.User().AnalyticsActiveCount(MONTH_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false}) + count, err := a.Srv.Store.User().AnalyticsActiveCount(MONTH_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false}) activeUsersMonthlyCountChan <- store.StoreResult{Data: count, Err: err} close(activeUsersMonthlyCountChan) }() diff --git a/store/sqlstore/user_store.go b/store/sqlstore/user_store.go index c159d9da3b..9a60223f87 100644 --- a/store/sqlstore/user_store.go +++ b/store/sqlstore/user_store.go @@ -1101,16 +1101,23 @@ func (us SqlUserStore) Count(options model.UserCountOptions) (int64, *model.AppE func (us SqlUserStore) AnalyticsActiveCount(timePeriod int64, options model.UserCountOptions) (int64, *model.AppError) { time := model.GetMillis() - timePeriod + query := us.getQueryBuilder().Select("COUNT(*)").From("Status AS s").Where("LastActivityAt > :Time", map[string]interface{}{"Time": time}) - query := "SELECT COUNT(*) FROM Status s" - - if options.IncludeBotAccounts { - query += " WHERE LastActivityAt > :Time" - } else { - query += " LEFT JOIN Bots ON s.UserId = Bots.UserId WHERE Bots.UserId IS NULL AND LastActivityAt > :Time" + if !options.IncludeBotAccounts { + query = query.LeftJoin("Bots ON s.UserId = Bots.UserId").Where("Bots.UserId IS NULL") } - v, err := us.GetReplica().SelectInt(query, map[string]interface{}{"Time": time}) + if !options.IncludeDeleted { + query = query.LeftJoin("Users ON s.UserId = Users.Id").Where("Users.DeleteAt = 0") + } + + queryStr, args, err := query.ToSql() + + if err != nil { + return 0, model.NewAppError("SqlUserStore.Get", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError) + } + + v, err := us.GetReplica().SelectInt(queryStr, args...) if err != nil { return 0, model.NewAppError("SqlUserStore.AnalyticsDailyActiveUsers", "store.sql_user.analytics_daily_active_users.app_error", nil, err.Error(), http.StatusInternalServerError) } diff --git a/store/storetest/user_store.go b/store/storetest/user_store.go index b8a5ab3cc2..58a32883f5 100644 --- a/store/storetest/user_store.go +++ b/store/storetest/user_store.go @@ -3402,22 +3402,43 @@ func testUserStoreAnalyticsActiveCount(t *testing.T, ss store.Store, s SqlSuppli // Create 5 users statuses u0, u1, u2, u3, u4. // u4 is also a bot - u0Id := model.NewId() - u1Id := model.NewId() - u2Id := model.NewId() - u3Id := model.NewId() - + u0, err := ss.User().Save(&model.User{ + Email: MakeEmail(), + Username: "u0" + model.NewId(), + }) + require.Nil(t, err) + u1, err := ss.User().Save(&model.User{ + Email: MakeEmail(), + Username: "u1" + model.NewId(), + }) + require.Nil(t, err) + u2, err := ss.User().Save(&model.User{ + Email: MakeEmail(), + Username: "u2" + model.NewId(), + }) + require.Nil(t, err) + u3, err := ss.User().Save(&model.User{ + Email: MakeEmail(), + Username: "u3" + model.NewId(), + }) + require.Nil(t, err) u4, err := ss.User().Save(&model.User{ Email: MakeEmail(), Username: "u4" + model.NewId(), }) require.Nil(t, err) - defer func() { require.Nil(t, ss.User().PermanentDelete(u4.Id)) }() + defer func() { + require.Nil(t, ss.User().PermanentDelete(u0.Id)) + require.Nil(t, ss.User().PermanentDelete(u1.Id)) + require.Nil(t, ss.User().PermanentDelete(u2.Id)) + require.Nil(t, ss.User().PermanentDelete(u3.Id)) + require.Nil(t, ss.User().PermanentDelete(u4.Id)) + }() _, err = ss.Bot().Save(&model.Bot{ UserId: u4.Id, Username: u4.Username, - OwnerId: u1Id, + OwnerId: u1.Id, }) require.Nil(t, err) @@ -3428,31 +3449,37 @@ func testUserStoreAnalyticsActiveCount(t *testing.T, ss store.Store, s SqlSuppli // u0 last activity status is two months ago. // u1 last activity status is two days ago. // u2, u3, u4 last activity is within last day - require.Nil(t, ss.Status().SaveOrUpdate(&model.Status{UserId: u0Id, Status: model.STATUS_OFFLINE, LastActivityAt: millisTwoMonthsAgo})) - require.Nil(t, ss.Status().SaveOrUpdate(&model.Status{UserId: u1Id, Status: model.STATUS_OFFLINE, LastActivityAt: millisTwoDaysAgo})) - require.Nil(t, ss.Status().SaveOrUpdate(&model.Status{UserId: u2Id, Status: model.STATUS_OFFLINE, LastActivityAt: millis})) - require.Nil(t, ss.Status().SaveOrUpdate(&model.Status{UserId: u3Id, Status: model.STATUS_OFFLINE, LastActivityAt: millis})) + require.Nil(t, ss.Status().SaveOrUpdate(&model.Status{UserId: u0.Id, Status: model.STATUS_OFFLINE, LastActivityAt: millisTwoMonthsAgo})) + require.Nil(t, ss.Status().SaveOrUpdate(&model.Status{UserId: u1.Id, Status: model.STATUS_OFFLINE, LastActivityAt: millisTwoDaysAgo})) + require.Nil(t, ss.Status().SaveOrUpdate(&model.Status{UserId: u2.Id, Status: model.STATUS_OFFLINE, LastActivityAt: millis})) + require.Nil(t, ss.Status().SaveOrUpdate(&model.Status{UserId: u3.Id, Status: model.STATUS_OFFLINE, LastActivityAt: millis})) require.Nil(t, ss.Status().SaveOrUpdate(&model.Status{UserId: u4.Id, Status: model.STATUS_OFFLINE, LastActivityAt: millis})) // Daily counts (without bots) - count, err := ss.User().AnalyticsActiveCount(DAY_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false}) + count, err := ss.User().AnalyticsActiveCount(DAY_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: true}) require.Nil(t, err) assert.Equal(t, int64(2), count) // Daily counts (with bots) - count, err = ss.User().AnalyticsActiveCount(DAY_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: true}) + count, err = ss.User().AnalyticsActiveCount(DAY_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: true, IncludeDeleted: true}) require.Nil(t, err) assert.Equal(t, int64(3), count) // Monthly counts (without bots) - count, err = ss.User().AnalyticsActiveCount(MONTH_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false}) + count, err = ss.User().AnalyticsActiveCount(MONTH_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: true}) require.Nil(t, err) assert.Equal(t, int64(3), count) // Monthly counts - (with bots) - count, err = ss.User().AnalyticsActiveCount(MONTH_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: true}) + count, err = ss.User().AnalyticsActiveCount(MONTH_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: true, IncludeDeleted: true}) require.Nil(t, err) assert.Equal(t, int64(4), count) + + // Monthly counts - (with bots, excluding deleted) + count, err = ss.User().AnalyticsActiveCount(MONTH_MILLISECONDS, model.UserCountOptions{IncludeBotAccounts: true, IncludeDeleted: false}) + require.Nil(t, err) + assert.Equal(t, int64(4), count) + } func testUserStoreAnalyticsGetInactiveUsersCount(t *testing.T, ss store.Store) {