From 1802c575e5e219653eeedb9d91a4b4f70f8f4a08 Mon Sep 17 00:00:00 2001 From: jfrerich Date: Tue, 10 Sep 2019 11:50:27 -0500 Subject: [PATCH] =?UTF-8?q?[MM-18119]=20Add=20methods=20for=20getting=20te?= =?UTF-8?q?ams=20and=20count=20when=20query=E2=80=A6=20(#12020)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add methods to handle include_total_count api parameter when permissions for authenticated user is not sysadmin * Add translations for app errors * Add Mocks * Add tests for new methods * When running at the TeamStore testing level, the number of returned teams is different than running tests individually. Fix for now and submit help wanted do proper teardown after each test * correct value when running test at the top level * Add helper function to delete previous teams in db * Instead of checking against numbers of teams returned, check against the actual teams returned. When creating test teams, use unique DisplaName values so the return array will be sorted consistantly. When testing private and public team counts, add teams that should not be counted. Also create odd number of public/private teams for better error protections. Don't want 1 of each type --- api4/team.go | 12 +- api4/team_test.go | 34 ++++- app/team.go | 24 +++ i18n/en.json | 8 + store/sqlstore/team_store.go | 44 ++++++ store/store.go | 3 + store/storetest/mocks/AuditStore.go | 6 +- store/storetest/mocks/BotStore.go | 6 +- .../mocks/ChannelMemberHistoryStore.go | 6 +- store/storetest/mocks/ChannelStore.go | 8 +- .../storetest/mocks/ClusterDiscoveryStore.go | 6 +- store/storetest/mocks/CommandStore.go | 6 +- store/storetest/mocks/CommandWebhookStore.go | 6 +- store/storetest/mocks/ComplianceStore.go | 6 +- store/storetest/mocks/EmojiStore.go | 6 +- store/storetest/mocks/FileInfoStore.go | 6 +- store/storetest/mocks/GroupStore.go | 6 +- store/storetest/mocks/JobStore.go | 6 +- .../mocks/LayeredStoreDatabaseLayer.go | 12 +- store/storetest/mocks/LayeredStoreSupplier.go | 12 +- store/storetest/mocks/LicenseStore.go | 6 +- store/storetest/mocks/LinkMetadataStore.go | 6 +- store/storetest/mocks/OAuthStore.go | 6 +- store/storetest/mocks/PluginStore.go | 6 +- store/storetest/mocks/PostStore.go | 6 +- store/storetest/mocks/PreferenceStore.go | 6 +- store/storetest/mocks/ReactionStore.go | 6 +- store/storetest/mocks/RoleStore.go | 6 +- store/storetest/mocks/SchemeStore.go | 6 +- store/storetest/mocks/SessionStore.go | 6 +- store/storetest/mocks/SqlStore.go | 11 +- store/storetest/mocks/StatusStore.go | 6 +- store/storetest/mocks/Store.go | 6 +- store/storetest/mocks/SystemStore.go | 6 +- store/storetest/mocks/TeamStore.go | 77 +++++++++- store/storetest/mocks/TermsOfServiceStore.go | 6 +- store/storetest/mocks/TokenStore.go | 6 +- store/storetest/mocks/UserAccessTokenStore.go | 6 +- store/storetest/mocks/UserStore.go | 8 +- .../mocks/UserTermsOfServiceStore.go | 6 +- store/storetest/mocks/WebhookStore.go | 6 +- store/storetest/team_store.go | 141 ++++++++++++++++++ 42 files changed, 483 insertions(+), 85 deletions(-) diff --git a/api4/team.go b/api4/team.go index 884e071ec1..5c0df4902c 100644 --- a/api4/team.go +++ b/api4/team.go @@ -740,9 +740,17 @@ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) { teams, err = c.App.GetAllTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage) } } else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) { - teams, err = c.App.GetAllPrivateTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage) + if c.Params.IncludeTotalCount { + teamsWithCount, err = c.App.GetAllPrivateTeamsPageWithCount(c.Params.Page*c.Params.PerPage, c.Params.PerPage) + } else { + teams, err = c.App.GetAllPrivateTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage) + } } else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PUBLIC_TEAMS) { - teams, err = c.App.GetAllPublicTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage) + if c.Params.IncludeTotalCount { + teamsWithCount, err = c.App.GetAllPublicTeamsPageWithCount(c.Params.Page*c.Params.PerPage, c.Params.PerPage) + } else { + teams, err = c.App.GetAllPublicTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage) + } } if err != nil { diff --git a/api4/team_test.go b/api4/team_test.go index ff5b0d84eb..dce8f8b7d0 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -621,6 +621,10 @@ func TestGetAllTeams(t *testing.T) { team3, resp = Client.CreateTeam(team3) CheckNoError(t, resp) + team4 := &model.Team{DisplayName: "Name4", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: false} + team4, resp = Client.CreateTeam(team4) + CheckNoError(t, resp) + testCases := []struct { Name string Page int @@ -663,14 +667,14 @@ func TestGetAllTeams(t *testing.T) { Page: 0, PerPage: 10, Permissions: []string{model.PERMISSION_LIST_PRIVATE_TEAMS.Id}, - ExpectedTeams: []string{th.BasicTeam.Id, team3.Id}, + ExpectedTeams: []string{th.BasicTeam.Id, team3.Id, team4.Id}, }, { Name: "Get all teams", Page: 0, PerPage: 10, Permissions: []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.PERMISSION_LIST_PRIVATE_TEAMS.Id}, - ExpectedTeams: []string{th.BasicTeam.Id, team1.Id, team2.Id, team3.Id}, + ExpectedTeams: []string{th.BasicTeam.Id, team1.Id, team2.Id, team3.Id, team4.Id}, }, { Name: "Get no teams because permissions", @@ -684,9 +688,27 @@ func TestGetAllTeams(t *testing.T) { Page: 0, PerPage: 10, Permissions: []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.PERMISSION_LIST_PRIVATE_TEAMS.Id}, - ExpectedTeams: []string{th.BasicTeam.Id, team1.Id, team2.Id, team3.Id}, + ExpectedTeams: []string{th.BasicTeam.Id, team1.Id, team2.Id, team3.Id, team4.Id}, WithCount: true, - ExpectedCount: 4, + ExpectedCount: 5, + }, + { + Name: "Get all public teams with count", + Page: 0, + PerPage: 10, + Permissions: []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id}, + ExpectedTeams: []string{team1.Id, team2.Id}, + WithCount: true, + ExpectedCount: 2, + }, + { + Name: "Get all private teams with count", + Page: 0, + PerPage: 10, + Permissions: []string{model.PERMISSION_LIST_PRIVATE_TEAMS.Id}, + ExpectedTeams: []string{th.BasicTeam.Id, team3.Id, team4.Id}, + WithCount: true, + ExpectedCount: 3, }, } @@ -2310,7 +2332,9 @@ func TestInviteGuestsToTeam(t *testing.T) { defer func() { th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableEmailInvitations = &enableEmailInvitations }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.RestrictCreationToDomains = restrictCreationToDomains }) - th.App.UpdateConfig(func(cfg *model.Config) { cfg.GuestAccountsSettings.RestrictCreationToDomains = guestRestrictCreationToDomains }) + th.App.UpdateConfig(func(cfg *model.Config) { + cfg.GuestAccountsSettings.RestrictCreationToDomains = guestRestrictCreationToDomains + }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.GuestAccountsSettings.Enable = &enableGuestAccounts }) }() diff --git a/app/team.go b/app/team.go index 26da179d14..3bc3e8409e 100644 --- a/app/team.go +++ b/app/team.go @@ -683,6 +683,18 @@ func (a *App) GetAllPrivateTeamsPage(offset int, limit int) ([]*model.Team, *mod return a.Srv.Store.Team().GetAllPrivateTeamPageListing(offset, limit) } +func (a *App) GetAllPrivateTeamsPageWithCount(offset int, limit int) (*model.TeamsWithCount, *model.AppError) { + totalCount, err := a.Srv.Store.Team().AnalyticsPrivateTeamCount() + if err != nil { + return nil, err + } + teams, err := a.Srv.Store.Team().GetAllPrivateTeamPageListing(offset, limit) + if err != nil { + return nil, err + } + return &model.TeamsWithCount{Teams: teams, TotalCount: totalCount}, nil +} + func (a *App) GetAllPublicTeams() ([]*model.Team, *model.AppError) { return a.Srv.Store.Team().GetAllTeamListing() } @@ -691,6 +703,18 @@ func (a *App) GetAllPublicTeamsPage(offset int, limit int) ([]*model.Team, *mode return a.Srv.Store.Team().GetAllTeamPageListing(offset, limit) } +func (a *App) GetAllPublicTeamsPageWithCount(offset int, limit int) (*model.TeamsWithCount, *model.AppError) { + totalCount, err := a.Srv.Store.Team().AnalyticsPublicTeamCount() + if err != nil { + return nil, err + } + teams, err := a.Srv.Store.Team().GetAllPublicTeamPageListing(offset, limit) + if err != nil { + return nil, err + } + return &model.TeamsWithCount{Teams: teams, TotalCount: totalCount}, nil +} + func (a *App) SearchAllTeams(term string) ([]*model.Team, *model.AppError) { return a.Srv.Store.Team().SearchAll(term) } diff --git a/i18n/en.json b/i18n/en.json index d2e46f64f3..1901d6bcb6 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -6678,6 +6678,14 @@ "id": "store.sql_team.analytics_get_team_count_for_scheme.app_error", "translation": "Unable to get the channel count for the scheme." }, + { + "id": "store.sql_team.analytics_private_team_count.app_error", + "translation": "Unable to count the private teams" + }, + { + "id": "store.sql_team.analytics_public_team_count.app_error", + "translation": "Unable to count the public teams" + }, { "id": "store.sql_team.analytics_team_count.app_error", "translation": "Unable to count the teams" diff --git a/store/sqlstore/team_store.go b/store/sqlstore/team_store.go index 8b4c84ad52..ec3b3770f5 100644 --- a/store/sqlstore/team_store.go +++ b/store/sqlstore/team_store.go @@ -381,6 +381,21 @@ func (s SqlTeamStore) GetAllPrivateTeamListing() ([]*model.Team, *model.AppError return data, nil } +func (s SqlTeamStore) GetAllPublicTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) { + query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1 ORDER BY DisplayName LIMIT :Limit OFFSET :Offset" + + if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { + query = "SELECT * FROM Teams WHERE AllowOpenInvite = true ORDER BY DisplayName LIMIT :Limit OFFSET :Offset" + } + + var data []*model.Team + if _, err := s.GetReplica().Select(&data, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { + return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamListing", "store.sql_team.get_all_private_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) + } + + return data, nil +} + func (s SqlTeamStore) GetAllPrivateTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) { query := "SELECT * FROM Teams WHERE AllowOpenInvite = 0 ORDER BY DisplayName LIMIT :Limit OFFSET :Offset" @@ -433,6 +448,35 @@ func (s SqlTeamStore) PermanentDelete(teamId string) *model.AppError { return nil } +func (s SqlTeamStore) AnalyticsPublicTeamCount() (int64, *model.AppError) { + + c, err := s.GetReplica().SelectInt("SELECT COUNT(*) FROM Teams WHERE DeleteAt = 0 AND AllowOpenInvite = 1", map[string]interface{}{}) + + if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { + c, err = s.GetReplica().SelectInt("SELECT COUNT(*) FROM Teams WHERE DeleteAt = 0 AND AllowOpenInvite = true", map[string]interface{}{}) + } + + if err != nil { + return int64(0), model.NewAppError("SqlTeamStore.AnalyticsPublicTeamCount", "store.sql_team.analytics_public_team_count.app_error", nil, err.Error(), http.StatusInternalServerError) + } + + return c, nil +} + +func (s SqlTeamStore) AnalyticsPrivateTeamCount() (int64, *model.AppError) { + c, err := s.GetReplica().SelectInt("SELECT COUNT(*) FROM Teams WHERE DeleteAt = 0 AND AllowOpenInvite = 0", map[string]interface{}{}) + + if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { + c, err = s.GetReplica().SelectInt("SELECT COUNT(*) FROM Teams WHERE DeleteAt = 0 AND AllowOpenInvite = false", map[string]interface{}{}) + } + + if err != nil { + return int64(0), model.NewAppError("SqlTeamStore.AnalyticsPrivateTeamCount", "store.sql_team.analytics_private_team_count.app_error", nil, err.Error(), http.StatusInternalServerError) + } + + return c, nil +} + func (s SqlTeamStore) AnalyticsTeamCount() (int64, *model.AppError) { c, err := s.GetReplica().SelectInt("SELECT COUNT(*) FROM Teams WHERE DeleteAt = 0", map[string]interface{}{}) diff --git a/store/store.go b/store/store.go index a098317a0b..c6fe2b1d5b 100644 --- a/store/store.go +++ b/store/store.go @@ -70,12 +70,15 @@ type TeamStore interface { GetAllPage(offset int, limit int) ([]*model.Team, *model.AppError) GetAllPrivateTeamListing() ([]*model.Team, *model.AppError) GetAllPrivateTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) + GetAllPublicTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) GetAllTeamListing() ([]*model.Team, *model.AppError) GetAllTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) GetTeamsByUserId(userId string) ([]*model.Team, *model.AppError) GetByInviteId(inviteId string) (*model.Team, *model.AppError) PermanentDelete(teamId string) *model.AppError AnalyticsTeamCount() (int64, *model.AppError) + AnalyticsPublicTeamCount() (int64, *model.AppError) + AnalyticsPrivateTeamCount() (int64, *model.AppError) SaveMember(member *model.TeamMember, maxUsersPerTeam int) (*model.TeamMember, *model.AppError) UpdateMember(member *model.TeamMember) (*model.TeamMember, *model.AppError) GetMember(teamId string, userId string) (*model.TeamMember, *model.AppError) diff --git a/store/storetest/mocks/AuditStore.go b/store/storetest/mocks/AuditStore.go index dd23d9c1ae..7740d16b0a 100644 --- a/store/storetest/mocks/AuditStore.go +++ b/store/storetest/mocks/AuditStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // AuditStore is an autogenerated mock type for the AuditStore type type AuditStore struct { diff --git a/store/storetest/mocks/BotStore.go b/store/storetest/mocks/BotStore.go index d4514ddbaf..c5d6f1d265 100644 --- a/store/storetest/mocks/BotStore.go +++ b/store/storetest/mocks/BotStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // BotStore is an autogenerated mock type for the BotStore type type BotStore struct { diff --git a/store/storetest/mocks/ChannelMemberHistoryStore.go b/store/storetest/mocks/ChannelMemberHistoryStore.go index 9ceac5cbff..0c65677b7b 100644 --- a/store/storetest/mocks/ChannelMemberHistoryStore.go +++ b/store/storetest/mocks/ChannelMemberHistoryStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // ChannelMemberHistoryStore is an autogenerated mock type for the ChannelMemberHistoryStore type type ChannelMemberHistoryStore struct { diff --git a/store/storetest/mocks/ChannelStore.go b/store/storetest/mocks/ChannelStore.go index 86f258a318..8eb871ced0 100644 --- a/store/storetest/mocks/ChannelStore.go +++ b/store/storetest/mocks/ChannelStore.go @@ -4,9 +4,11 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" -import store "github.com/mattermost/mattermost-server/store" +import ( + model "github.com/mattermost/mattermost-server/model" + store "github.com/mattermost/mattermost-server/store" + mock "github.com/stretchr/testify/mock" +) // ChannelStore is an autogenerated mock type for the ChannelStore type type ChannelStore struct { diff --git a/store/storetest/mocks/ClusterDiscoveryStore.go b/store/storetest/mocks/ClusterDiscoveryStore.go index 7303faba31..1d36295689 100644 --- a/store/storetest/mocks/ClusterDiscoveryStore.go +++ b/store/storetest/mocks/ClusterDiscoveryStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // ClusterDiscoveryStore is an autogenerated mock type for the ClusterDiscoveryStore type type ClusterDiscoveryStore struct { diff --git a/store/storetest/mocks/CommandStore.go b/store/storetest/mocks/CommandStore.go index 5015c3d6c8..a60141d299 100644 --- a/store/storetest/mocks/CommandStore.go +++ b/store/storetest/mocks/CommandStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // CommandStore is an autogenerated mock type for the CommandStore type type CommandStore struct { diff --git a/store/storetest/mocks/CommandWebhookStore.go b/store/storetest/mocks/CommandWebhookStore.go index c388f2386d..b804a0ccd0 100644 --- a/store/storetest/mocks/CommandWebhookStore.go +++ b/store/storetest/mocks/CommandWebhookStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // CommandWebhookStore is an autogenerated mock type for the CommandWebhookStore type type CommandWebhookStore struct { diff --git a/store/storetest/mocks/ComplianceStore.go b/store/storetest/mocks/ComplianceStore.go index b175a9a7ba..e0b4bff3b2 100644 --- a/store/storetest/mocks/ComplianceStore.go +++ b/store/storetest/mocks/ComplianceStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // ComplianceStore is an autogenerated mock type for the ComplianceStore type type ComplianceStore struct { diff --git a/store/storetest/mocks/EmojiStore.go b/store/storetest/mocks/EmojiStore.go index 32cc6a49af..98429c68de 100644 --- a/store/storetest/mocks/EmojiStore.go +++ b/store/storetest/mocks/EmojiStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // EmojiStore is an autogenerated mock type for the EmojiStore type type EmojiStore struct { diff --git a/store/storetest/mocks/FileInfoStore.go b/store/storetest/mocks/FileInfoStore.go index 4a87217349..ef91923a22 100644 --- a/store/storetest/mocks/FileInfoStore.go +++ b/store/storetest/mocks/FileInfoStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // FileInfoStore is an autogenerated mock type for the FileInfoStore type type FileInfoStore struct { diff --git a/store/storetest/mocks/GroupStore.go b/store/storetest/mocks/GroupStore.go index 217bafd399..f630d27581 100644 --- a/store/storetest/mocks/GroupStore.go +++ b/store/storetest/mocks/GroupStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // GroupStore is an autogenerated mock type for the GroupStore type type GroupStore struct { diff --git a/store/storetest/mocks/JobStore.go b/store/storetest/mocks/JobStore.go index 2c9908dece..1a8f34a660 100644 --- a/store/storetest/mocks/JobStore.go +++ b/store/storetest/mocks/JobStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // JobStore is an autogenerated mock type for the JobStore type type JobStore struct { diff --git a/store/storetest/mocks/LayeredStoreDatabaseLayer.go b/store/storetest/mocks/LayeredStoreDatabaseLayer.go index c5d7691607..cb0ab438f5 100644 --- a/store/storetest/mocks/LayeredStoreDatabaseLayer.go +++ b/store/storetest/mocks/LayeredStoreDatabaseLayer.go @@ -4,10 +4,14 @@ package mocks -import context "context" -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" -import store "github.com/mattermost/mattermost-server/store" +import ( + context "context" + + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" + + store "github.com/mattermost/mattermost-server/store" +) // LayeredStoreDatabaseLayer is an autogenerated mock type for the LayeredStoreDatabaseLayer type type LayeredStoreDatabaseLayer struct { diff --git a/store/storetest/mocks/LayeredStoreSupplier.go b/store/storetest/mocks/LayeredStoreSupplier.go index 45682da8f9..6d4e655e22 100644 --- a/store/storetest/mocks/LayeredStoreSupplier.go +++ b/store/storetest/mocks/LayeredStoreSupplier.go @@ -4,10 +4,14 @@ package mocks -import context "context" -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" -import store "github.com/mattermost/mattermost-server/store" +import ( + context "context" + + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" + + store "github.com/mattermost/mattermost-server/store" +) // LayeredStoreSupplier is an autogenerated mock type for the LayeredStoreSupplier type type LayeredStoreSupplier struct { diff --git a/store/storetest/mocks/LicenseStore.go b/store/storetest/mocks/LicenseStore.go index b769b39404..8a376037ef 100644 --- a/store/storetest/mocks/LicenseStore.go +++ b/store/storetest/mocks/LicenseStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // LicenseStore is an autogenerated mock type for the LicenseStore type type LicenseStore struct { diff --git a/store/storetest/mocks/LinkMetadataStore.go b/store/storetest/mocks/LinkMetadataStore.go index 5de2575969..2a7a12cef6 100644 --- a/store/storetest/mocks/LinkMetadataStore.go +++ b/store/storetest/mocks/LinkMetadataStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // LinkMetadataStore is an autogenerated mock type for the LinkMetadataStore type type LinkMetadataStore struct { diff --git a/store/storetest/mocks/OAuthStore.go b/store/storetest/mocks/OAuthStore.go index ab8f97b9ce..3ed44c34b3 100644 --- a/store/storetest/mocks/OAuthStore.go +++ b/store/storetest/mocks/OAuthStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // OAuthStore is an autogenerated mock type for the OAuthStore type type OAuthStore struct { diff --git a/store/storetest/mocks/PluginStore.go b/store/storetest/mocks/PluginStore.go index d618df0ce4..54812a66a6 100644 --- a/store/storetest/mocks/PluginStore.go +++ b/store/storetest/mocks/PluginStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // PluginStore is an autogenerated mock type for the PluginStore type type PluginStore struct { diff --git a/store/storetest/mocks/PostStore.go b/store/storetest/mocks/PostStore.go index 70818dd7d7..acb8adfe7f 100644 --- a/store/storetest/mocks/PostStore.go +++ b/store/storetest/mocks/PostStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // PostStore is an autogenerated mock type for the PostStore type type PostStore struct { diff --git a/store/storetest/mocks/PreferenceStore.go b/store/storetest/mocks/PreferenceStore.go index 293979210a..71828d62b0 100644 --- a/store/storetest/mocks/PreferenceStore.go +++ b/store/storetest/mocks/PreferenceStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // PreferenceStore is an autogenerated mock type for the PreferenceStore type type PreferenceStore struct { diff --git a/store/storetest/mocks/ReactionStore.go b/store/storetest/mocks/ReactionStore.go index 80cb0486c5..41117978bb 100644 --- a/store/storetest/mocks/ReactionStore.go +++ b/store/storetest/mocks/ReactionStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // ReactionStore is an autogenerated mock type for the ReactionStore type type ReactionStore struct { diff --git a/store/storetest/mocks/RoleStore.go b/store/storetest/mocks/RoleStore.go index e19635796c..64254eda52 100644 --- a/store/storetest/mocks/RoleStore.go +++ b/store/storetest/mocks/RoleStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // RoleStore is an autogenerated mock type for the RoleStore type type RoleStore struct { diff --git a/store/storetest/mocks/SchemeStore.go b/store/storetest/mocks/SchemeStore.go index a1e9d0779f..d1c1b1fbb8 100644 --- a/store/storetest/mocks/SchemeStore.go +++ b/store/storetest/mocks/SchemeStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // SchemeStore is an autogenerated mock type for the SchemeStore type type SchemeStore struct { diff --git a/store/storetest/mocks/SessionStore.go b/store/storetest/mocks/SessionStore.go index 4c0a97ecc9..88f3c817d5 100644 --- a/store/storetest/mocks/SessionStore.go +++ b/store/storetest/mocks/SessionStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // SessionStore is an autogenerated mock type for the SessionStore type type SessionStore struct { diff --git a/store/storetest/mocks/SqlStore.go b/store/storetest/mocks/SqlStore.go index 3c7c29c3b1..b4e22062bc 100644 --- a/store/storetest/mocks/SqlStore.go +++ b/store/storetest/mocks/SqlStore.go @@ -4,11 +4,14 @@ package mocks -import gorp "github.com/mattermost/gorp" -import mock "github.com/stretchr/testify/mock" +import ( + gorp "github.com/mattermost/gorp" + mock "github.com/stretchr/testify/mock" -import squirrel "github.com/Masterminds/squirrel" -import store "github.com/mattermost/mattermost-server/store" + squirrel "github.com/Masterminds/squirrel" + + store "github.com/mattermost/mattermost-server/store" +) // SqlStore is an autogenerated mock type for the SqlStore type type SqlStore struct { diff --git a/store/storetest/mocks/StatusStore.go b/store/storetest/mocks/StatusStore.go index 48d4e9a67f..bdfb0b40af 100644 --- a/store/storetest/mocks/StatusStore.go +++ b/store/storetest/mocks/StatusStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // StatusStore is an autogenerated mock type for the StatusStore type type StatusStore struct { diff --git a/store/storetest/mocks/Store.go b/store/storetest/mocks/Store.go index 1fa222c35f..c9b1cb1081 100644 --- a/store/storetest/mocks/Store.go +++ b/store/storetest/mocks/Store.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import store "github.com/mattermost/mattermost-server/store" +import ( + store "github.com/mattermost/mattermost-server/store" + mock "github.com/stretchr/testify/mock" +) // Store is an autogenerated mock type for the Store type type Store struct { diff --git a/store/storetest/mocks/SystemStore.go b/store/storetest/mocks/SystemStore.go index f9eeea7df2..1cd8f54a3e 100644 --- a/store/storetest/mocks/SystemStore.go +++ b/store/storetest/mocks/SystemStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // SystemStore is an autogenerated mock type for the SystemStore type type SystemStore struct { diff --git a/store/storetest/mocks/TeamStore.go b/store/storetest/mocks/TeamStore.go index e490238c37..b5afcea483 100644 --- a/store/storetest/mocks/TeamStore.go +++ b/store/storetest/mocks/TeamStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // TeamStore is an autogenerated mock type for the TeamStore type type TeamStore struct { @@ -35,6 +37,52 @@ func (_m *TeamStore) AnalyticsGetTeamCountForScheme(schemeId string) (int64, *mo return r0, r1 } +// AnalyticsPrivateTeamCount provides a mock function with given fields: +func (_m *TeamStore) AnalyticsPrivateTeamCount() (int64, *model.AppError) { + ret := _m.Called() + + var r0 int64 + if rf, ok := ret.Get(0).(func() int64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int64) + } + + var r1 *model.AppError + if rf, ok := ret.Get(1).(func() *model.AppError); ok { + r1 = rf() + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*model.AppError) + } + } + + return r0, r1 +} + +// AnalyticsPublicTeamCount provides a mock function with given fields: +func (_m *TeamStore) AnalyticsPublicTeamCount() (int64, *model.AppError) { + ret := _m.Called() + + var r0 int64 + if rf, ok := ret.Get(0).(func() int64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int64) + } + + var r1 *model.AppError + if rf, ok := ret.Get(1).(func() *model.AppError); ok { + r1 = rf() + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*model.AppError) + } + } + + return r0, r1 +} + // AnalyticsTeamCount provides a mock function with given fields: func (_m *TeamStore) AnalyticsTeamCount() (int64, *model.AppError) { ret := _m.Called() @@ -252,6 +300,31 @@ func (_m *TeamStore) GetAllPrivateTeamPageListing(offset int, limit int) ([]*mod return r0, r1 } +// GetAllPublicTeamPageListing provides a mock function with given fields: offset, limit +func (_m *TeamStore) GetAllPublicTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) { + ret := _m.Called(offset, limit) + + var r0 []*model.Team + if rf, ok := ret.Get(0).(func(int, int) []*model.Team); ok { + r0 = rf(offset, limit) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.Team) + } + } + + var r1 *model.AppError + if rf, ok := ret.Get(1).(func(int, int) *model.AppError); ok { + r1 = rf(offset, limit) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*model.AppError) + } + } + + return r0, r1 +} + // GetAllTeamListing provides a mock function with given fields: func (_m *TeamStore) GetAllTeamListing() ([]*model.Team, *model.AppError) { ret := _m.Called() diff --git a/store/storetest/mocks/TermsOfServiceStore.go b/store/storetest/mocks/TermsOfServiceStore.go index fca2d3f367..d107849e98 100644 --- a/store/storetest/mocks/TermsOfServiceStore.go +++ b/store/storetest/mocks/TermsOfServiceStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // TermsOfServiceStore is an autogenerated mock type for the TermsOfServiceStore type type TermsOfServiceStore struct { diff --git a/store/storetest/mocks/TokenStore.go b/store/storetest/mocks/TokenStore.go index b295467f20..a6a22c224f 100644 --- a/store/storetest/mocks/TokenStore.go +++ b/store/storetest/mocks/TokenStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // TokenStore is an autogenerated mock type for the TokenStore type type TokenStore struct { diff --git a/store/storetest/mocks/UserAccessTokenStore.go b/store/storetest/mocks/UserAccessTokenStore.go index 5995688d6a..0a3012f767 100644 --- a/store/storetest/mocks/UserAccessTokenStore.go +++ b/store/storetest/mocks/UserAccessTokenStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // UserAccessTokenStore is an autogenerated mock type for the UserAccessTokenStore type type UserAccessTokenStore struct { diff --git a/store/storetest/mocks/UserStore.go b/store/storetest/mocks/UserStore.go index 017b36cb2c..e901c81d70 100644 --- a/store/storetest/mocks/UserStore.go +++ b/store/storetest/mocks/UserStore.go @@ -4,9 +4,11 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" -import store "github.com/mattermost/mattermost-server/store" +import ( + model "github.com/mattermost/mattermost-server/model" + store "github.com/mattermost/mattermost-server/store" + mock "github.com/stretchr/testify/mock" +) // UserStore is an autogenerated mock type for the UserStore type type UserStore struct { diff --git a/store/storetest/mocks/UserTermsOfServiceStore.go b/store/storetest/mocks/UserTermsOfServiceStore.go index 387abb4c10..3689b7d212 100644 --- a/store/storetest/mocks/UserTermsOfServiceStore.go +++ b/store/storetest/mocks/UserTermsOfServiceStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // UserTermsOfServiceStore is an autogenerated mock type for the UserTermsOfServiceStore type type UserTermsOfServiceStore struct { diff --git a/store/storetest/mocks/WebhookStore.go b/store/storetest/mocks/WebhookStore.go index f6e3a61e4c..2c126cceb0 100644 --- a/store/storetest/mocks/WebhookStore.go +++ b/store/storetest/mocks/WebhookStore.go @@ -4,8 +4,10 @@ package mocks -import mock "github.com/stretchr/testify/mock" -import model "github.com/mattermost/mattermost-server/model" +import ( + model "github.com/mattermost/mattermost-server/model" + mock "github.com/stretchr/testify/mock" +) // WebhookStore is an autogenerated mock type for the WebhookStore type type WebhookStore struct { diff --git a/store/storetest/team_store.go b/store/storetest/team_store.go index edf9fd0f55..8d161cbb66 100644 --- a/store/storetest/team_store.go +++ b/store/storetest/team_store.go @@ -15,6 +15,14 @@ import ( "github.com/mattermost/mattermost-server/store" ) +func cleanupTeamStore(t *testing.T, ss store.Store) { + allTeams, err := ss.Team().GetAll() + for _, team := range allTeams { + ss.Team().PermanentDelete(team.Id) + } + assert.Nil(t, err) +} + func TestTeamStore(t *testing.T, ss store.Store) { createDefaultRoles(t, ss) @@ -31,8 +39,11 @@ func TestTeamStore(t *testing.T, ss store.Store) { t.Run("GetAllTeamPageListing", func(t *testing.T) { testGetAllTeamPageListing(t, ss) }) t.Run("GetAllPrivateTeamListing", func(t *testing.T) { testGetAllPrivateTeamListing(t, ss) }) t.Run("GetAllPrivateTeamPageListing", func(t *testing.T) { testGetAllPrivateTeamPageListing(t, ss) }) + t.Run("GetAllPublicTeamPageListing", func(t *testing.T) { testGetAllPublicTeamPageListing(t, ss) }) t.Run("Delete", func(t *testing.T) { testDelete(t, ss) }) t.Run("TeamCount", func(t *testing.T) { testTeamCount(t, ss) }) + t.Run("TeamPublicCount", func(t *testing.T) { testPublicTeamCount(t, ss) }) + t.Run("TeamPrivateCount", func(t *testing.T) { testPrivateTeamCount(t, ss) }) t.Run("TeamMembers", func(t *testing.T) { testTeamMembers(t, ss) }) t.Run("SaveTeamMemberMaxMembers", func(t *testing.T) { testSaveTeamMemberMaxMembers(t, ss) }) t.Run("GetTeamMember", func(t *testing.T) { testGetTeamMember(t, ss) }) @@ -678,6 +689,66 @@ func testGetAllPrivateTeamPageListing(t *testing.T, ss store.Store) { } } +func testGetAllPublicTeamPageListing(t *testing.T, ss store.Store) { + cleanupTeamStore(t, ss) + + o1 := model.Team{} + o1.DisplayName = "DisplayName1" + o1.Name = "z-z-z" + model.NewId() + "b" + o1.Email = MakeEmail() + o1.Type = model.TEAM_OPEN + o1.AllowOpenInvite = true + t1, err := ss.Team().Save(&o1) + require.Nil(t, err) + + o2 := model.Team{} + o2.DisplayName = "DisplayName2" + o2.Name = "zz" + model.NewId() + "b" + o2.Email = MakeEmail() + o2.Type = model.TEAM_OPEN + o2.AllowOpenInvite = false + _, err = ss.Team().Save(&o2) + require.Nil(t, err) + + o3 := model.Team{} + o3.DisplayName = "DisplayName3" + o3.Name = "z-z-z" + model.NewId() + "b" + o3.Email = MakeEmail() + o3.Type = model.TEAM_INVITE + o3.AllowOpenInvite = true + t3, err := ss.Team().Save(&o3) + require.Nil(t, err) + + o4 := model.Team{} + o4.DisplayName = "DisplayName4" + o4.Name = "zz" + model.NewId() + "b" + o4.Email = MakeEmail() + o4.Type = model.TEAM_INVITE + o4.AllowOpenInvite = false + _, err = ss.Team().Save(&o4) + require.Nil(t, err) + + teams, err := ss.Team().GetAllPublicTeamPageListing(0, 10) + assert.Nil(t, err) + assert.Equal(t, []*model.Team{t1, t3}, teams) + + o5 := model.Team{} + o5.DisplayName = "DisplayName5" + o5.Name = "z-z-z" + model.NewId() + "b" + o5.Email = MakeEmail() + o5.Type = model.TEAM_OPEN + o5.AllowOpenInvite = true + t5, err := ss.Team().Save(&o5) + require.Nil(t, err) + + teams, err = ss.Team().GetAllPublicTeamPageListing(0, 4) + assert.Nil(t, err) + assert.Equal(t, []*model.Team{t1, t3, t5}, teams) + + teams, err = ss.Team().GetAllPublicTeamPageListing(1, 1) + assert.Nil(t, err) +} + func testDelete(t *testing.T, ss store.Store) { o1 := model.Team{} o1.DisplayName = "DisplayName" @@ -701,6 +772,76 @@ func testDelete(t *testing.T, ss store.Store) { } } +func testPublicTeamCount(t *testing.T, ss store.Store) { + cleanupTeamStore(t, ss) + + o1 := model.Team{} + o1.DisplayName = "DisplayName" + o1.Name = "z-z-z" + model.NewId() + "b" + o1.Email = MakeEmail() + o1.Type = model.TEAM_OPEN + o1.AllowOpenInvite = true + _, err := ss.Team().Save(&o1) + require.Nil(t, err) + + o2 := model.Team{} + o2.DisplayName = "DisplayName" + o2.Name = "z-z-z" + model.NewId() + "b" + o2.Email = MakeEmail() + o2.Type = model.TEAM_OPEN + o2.AllowOpenInvite = false + _, err = ss.Team().Save(&o2) + require.Nil(t, err) + + o3 := model.Team{} + o3.DisplayName = "DisplayName" + o3.Name = "z-z-z" + model.NewId() + "b" + o3.Email = MakeEmail() + o3.Type = model.TEAM_OPEN + o3.AllowOpenInvite = true + _, err = ss.Team().Save(&o3) + require.Nil(t, err) + + teamCount, err := ss.Team().AnalyticsPublicTeamCount() + require.Nil(t, err) + require.Equal(t, int64(2), teamCount, "should only be 1 team") +} + +func testPrivateTeamCount(t *testing.T, ss store.Store) { + cleanupTeamStore(t, ss) + + o1 := model.Team{} + o1.DisplayName = "DisplayName" + o1.Name = "z-z-z" + model.NewId() + "b" + o1.Email = MakeEmail() + o1.Type = model.TEAM_OPEN + o1.AllowOpenInvite = false + _, err := ss.Team().Save(&o1) + require.Nil(t, err) + + o2 := model.Team{} + o2.DisplayName = "DisplayName" + o2.Name = "z-z-z" + model.NewId() + "b" + o2.Email = MakeEmail() + o2.Type = model.TEAM_OPEN + o2.AllowOpenInvite = true + _, err = ss.Team().Save(&o2) + require.Nil(t, err) + + o3 := model.Team{} + o3.DisplayName = "DisplayName" + o3.Name = "z-z-z" + model.NewId() + "b" + o3.Email = MakeEmail() + o3.Type = model.TEAM_OPEN + o3.AllowOpenInvite = false + _, err = ss.Team().Save(&o3) + require.Nil(t, err) + + teamCount, err := ss.Team().AnalyticsPrivateTeamCount() + require.Nil(t, err) + require.Equal(t, int64(2), teamCount, "should only be 1 team") +} + func testTeamCount(t *testing.T, ss store.Store) { o1 := model.Team{} o1.DisplayName = "DisplayName"