From f857af64f2e5a9d23486069ad0d68e13a91963c9 Mon Sep 17 00:00:00 2001 From: Maria A Nunez Date: Thu, 11 Jan 2024 21:28:58 -0500 Subject: [PATCH] Fixed actived users and added mau in true up report (#24921) * Fixed actived users and added mau in true up report * Temp disable of true up calendar checks for testing * Revert "Temp disable of true up calendar checks for testing" This reverts commit 73055bdb258546b863ea6841e39e22687da8aead. * Added unit test * Linting * Typo * Forgot the pain of linting * Added dau * Create imports.go * Fix merge error * Fixed test --------- Co-authored-by: Mattermost Build --- server/channels/app/true_up.go | 22 +++++++- server/channels/app/true_up_test.go | 55 +++++++++++++++++++ server/public/model/true_up_review_profile.go | 4 +- 3 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 server/channels/app/true_up_test.go diff --git a/server/channels/app/true_up.go b/server/channels/app/true_up.go index 7bad3766c4b6..5639354d9bad 100644 --- a/server/channels/app/true_up.go +++ b/server/channels/app/true_up.go @@ -52,9 +52,23 @@ func (a *App) getTrueUpProfile() (*model.TrueUpReviewProfile, error) { } // Customer Info & Usage Analytics - activeUserCount, err := a.Srv().Store().Status().GetTotalActiveUsersCount() + + // active registered users + activatedUsers, err := a.Srv().Store().User().Count(model.UserCountOptions{}) + if err != nil { + return nil, model.NewAppError("requestTrueUpReview", "api.license.true_up_review.user_count_fail", nil, "Could not get the total activated users count", http.StatusInternalServerError).Wrap(err) + } + + // daily active users + dau, err := a.Srv().Store().User().AnalyticsActiveCount(DayMilliseconds, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false}) + if err != nil { + return nil, model.NewAppError("requestTrueUpReview", "api.license.true_up_review.user_count_fail", nil, "Could not get the total daily active users count", http.StatusInternalServerError) + } + + // monthly active users + mau, err := a.Srv().Store().User().AnalyticsActiveCount(MonthMilliseconds, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false}) if err != nil { - return nil, model.NewAppError("requestTrueUpReview", "api.license.true_up_review.user_count_fail", nil, "Could not get the total active users count", http.StatusInternalServerError) + return nil, model.NewAppError("requestTrueUpReview", "api.license.true_up_review.user_count_fail", nil, "Could not get the total monthly active users count", http.StatusInternalServerError).Wrap(err) } // Webhook, calls, boards, and playbook counts @@ -108,7 +122,9 @@ func (a *App) getTrueUpProfile() (*model.TrueUpReviewProfile, error) { LicensedSeats: *license.Features.Users, LicensePlan: license.SkuName, CustomerName: license.Customer.Name, - ActiveUsers: activeUserCount, + ActivatedUsers: activatedUsers, + DailyActiveUsers: dau, + MonthlyActiveUsers: mau, TotalIncomingWebhooks: incomingWebhookCount, TotalOutgoingWebhooks: outgoingWebhookCount, Plugins: trueUpReviewPlugins, diff --git a/server/channels/app/true_up_test.go b/server/channels/app/true_up_test.go new file mode 100644 index 000000000000..650ebe742f25 --- /dev/null +++ b/server/channels/app/true_up_test.go @@ -0,0 +1,55 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package app + +import ( + "strings" + "testing" + + "github.com/mattermost/mattermost/server/public/model" + "github.com/mattermost/mattermost/server/v8/channels/store/storetest/mocks" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func TestGetTrueUpProfile(t *testing.T) { + th := SetupWithStoreMock(t) + defer th.TearDown() + + mockStore := th.App.Srv().Store().(*mocks.Store) + mockUserStore := mocks.UserStore{} + //Activated userss set to 10 + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + //Mau set to 5 + mockUserStore.On("AnalyticsActiveCount", int64(MonthMilliseconds), model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false}).Return(int64(5), nil) + //dau set to 2 + mockUserStore.On("AnalyticsActiveCount", int64(DayMilliseconds), model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false}).Return(int64(2), nil) + mockStore.On("User").Return(&mockUserStore) + + mockWebhookStore := mocks.WebhookStore{} + mockWebhookStore.On("AnalyticsIncomingCount", mock.Anything).Return(int64(1), nil) + mockWebhookStore.On("AnalyticsOutgoingCount", mock.Anything).Return(int64(1), nil) + mockStore.On("Webhook").Return(&mockWebhookStore) + + t.Run("missing license", func(t *testing.T) { + _, err := th.App.GetTrueUpProfile() + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), "True up review requires a license")) + }) + + t.Run("happy path - returns correct mau and activated users", func(t *testing.T) { + th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuProfessional)) + + profile, err := th.App.GetTrueUpProfile() + assert.NoError(t, err, "Unexpected error") + + require.NotNil(t, profile) + assert.Equal(t, float64(5), profile["monthly_active_users"]) + assert.Equal(t, float64(2), profile["daily_active_users"]) + assert.Equal(t, float64(10), profile["total_activated_users"]) + assert.Equal(t, float64(1), profile["incoming_webhooks_count"]) + assert.Equal(t, float64(1), profile["outgoing_webhooks_count"]) + }) +} diff --git a/server/public/model/true_up_review_profile.go b/server/public/model/true_up_review_profile.go index 8e4d186b75aa..39741c3bb25d 100644 --- a/server/public/model/true_up_review_profile.go +++ b/server/public/model/true_up_review_profile.go @@ -13,7 +13,9 @@ type TrueUpReviewProfile struct { LicensedSeats int `json:"licensed_seats"` LicensePlan string `json:"license_plan"` CustomerName string `json:"customer_name"` - ActiveUsers int64 `json:"active_users"` + ActivatedUsers int64 `json:"total_activated_users"` + DailyActiveUsers int64 `json:"daily_active_users"` + MonthlyActiveUsers int64 `json:"monthly_active_users"` AuthenticationFeatures []string `json:"authentication_features"` Plugins TrueUpReviewPlugins `json:"plugins"` TotalIncomingWebhooks int64 `json:"incoming_webhooks_count"`