diff --git a/server/Makefile b/server/Makefile index 9421e882e48..64297466a07 100644 --- a/server/Makefile +++ b/server/Makefile @@ -306,6 +306,15 @@ else $(GOBIN)/golangci-lint run ./... ./public/... endif +modernize: ## Run modernize linter on codebase +## https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize is not support in golangci-lint. +## We need to invoke it directly. +ifeq ($(BUILD_ENTERPRISE_READY),true) + go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@v0.19.1 -test ./... ./public/... $(BUILD_ENTERPRISE_DIR)/... +else + go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@v0.19.1 -test ./... ./public/... +endif + i18n-extract: ## Extract strings for translation from the source code cd ../tools/mmgotool && $(GO) install . $(GOBIN)/mmgotool i18n extract --portal-dir="" @@ -405,7 +414,7 @@ ifeq ($(BUILD_ENTERPRISE_READY),true) endif endif -check-style: plugin-checker vet golangci-lint ## Runs style/lint checks +check-style: plugin-checker vet modernize golangci-lint ## Runs style/lint checks gotestsum: $(GO) install gotest.tools/gotestsum@v1.11.0 diff --git a/server/channels/api4/apitestlib.go b/server/channels/api4/apitestlib.go index ff9fad93799..6e275982ec8 100644 --- a/server/channels/api4/apitestlib.go +++ b/server/channels/api4/apitestlib.go @@ -13,6 +13,7 @@ import ( "net/http" "os" "path/filepath" + "slices" "strings" "sync" "testing" @@ -587,7 +588,7 @@ func (th *TestHelper) DeleteBots() *TestHelper { } func (th *TestHelper) waitForConnectivity(tb testing.TB) { - for i := 0; i < 1000; i++ { + for range 1000 { conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%v", th.App.Srv().ListenAddr.Port)) if err == nil { conn.Close() @@ -1439,10 +1440,8 @@ func (th *TestHelper) AddPermissionToRole(permission string, roleName string) { panic(err1) } - for _, existingPermission := range role.Permissions { - if existingPermission == permission { - return - } + if slices.Contains(role.Permissions, permission) { + return } role.Permissions = append(role.Permissions, permission) diff --git a/server/channels/api4/channel.go b/server/channels/api4/channel.go index 1443b153605..939d64ed11e 100644 --- a/server/channels/api4/channel.go +++ b/server/channels/api4/channel.go @@ -2130,7 +2130,7 @@ func channelMembersMinusGroupMembers(c *Context, w http.ResponseWriter, r *http. } groupIDs := []string{} - for _, gid := range strings.Split(c.Params.GroupIDs, ",") { + for gid := range strings.SplitSeq(c.Params.GroupIDs, ",") { if !model.IsValidId(gid) { c.SetInvalidParam("group_ids") return diff --git a/server/channels/api4/channel_test.go b/server/channels/api4/channel_test.go index c9b0c856e6d..61ce244c31b 100644 --- a/server/channels/api4/channel_test.go +++ b/server/channels/api4/channel_test.go @@ -2005,7 +2005,7 @@ func TestGetChannelsForUser(t *testing.T) { assert.Equal(t, 2, numTownSquare) // Creating some more channels to be exactly 100 to test page size boundaries. - for i := 0; i < 91; i++ { + for range 91 { ch1 = th.CreateChannelWithClientAndTeam(client, model.ChannelTypeOpen, myTeam.Id) _, appErr := th.App.AddUserToChannel(th.Context, th.BasicUser, ch1, false) require.Nil(t, appErr) diff --git a/server/channels/api4/emoji_test.go b/server/channels/api4/emoji_test.go index cb9c56d6280..9c56cc2c9a0 100644 --- a/server/channels/api4/emoji_test.go +++ b/server/channels/api4/emoji_test.go @@ -377,7 +377,7 @@ func TestGetEmojisByNames(t *testing.T) { t.Run("should return an error when too many emojis are requested", func(t *testing.T) { names := make([]string, GetEmojisByNamesMax+1) - for i := 0; i < len(names); i++ { + for i := range names { names[i] = model.NewId() } diff --git a/server/channels/api4/export_test.go b/server/channels/api4/export_test.go index 35b9284c536..3467a226e5f 100644 --- a/server/channels/api4/export_test.go +++ b/server/channels/api4/export_test.go @@ -221,8 +221,7 @@ func BenchmarkDownloadExport(b *testing.B) { err = os.Truncate(filepath.Join(exportDir, exportName), 1024*1024*1024) require.NoError(b, err) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for i := 0; b.Loop(); i++ { outFilePath := filepath.Join(dataDir, fmt.Sprintf("export%d.zip", i)) outFile, err := os.Create(outFilePath) require.NoError(b, err) diff --git a/server/channels/api4/file_test.go b/server/channels/api4/file_test.go index 920c4dab1b6..071ada52619 100644 --- a/server/channels/api4/file_test.go +++ b/server/channels/api4/file_test.go @@ -1533,7 +1533,7 @@ func TestSearchFilesAcrossTeams(t *testing.T) { var teams [2]*model.Team var channels [2]*model.Channel - for i := 0; i < 2; i++ { + for i := range 2 { teams[i] = th.CreateTeam() channels[i] = th.CreateChannelWithClientAndTeam(th.Client, model.ChannelTypeOpen, teams[i].Id) diff --git a/server/channels/api4/group_test.go b/server/channels/api4/group_test.go index 8ce584d3eed..a8438eeab01 100644 --- a/server/channels/api4/group_test.go +++ b/server/channels/api4/group_test.go @@ -1154,7 +1154,7 @@ func TestGetGroupTeams(t *testing.T) { AutoAdd: model.NewPointer(true), } - for i := 0; i < 10; i++ { + for range 10 { team := th.CreateTeam() _, response, _ := th.SystemAdminClient.LinkGroupSyncable(context.Background(), g.Id, team.Id, model.GroupSyncableTypeTeam, patch) assert.Equal(t, http.StatusCreated, response.StatusCode) @@ -1209,7 +1209,7 @@ func TestGetGroupChannels(t *testing.T) { AutoAdd: model.NewPointer(true), } - for i := 0; i < 10; i++ { + for range 10 { channel := th.CreatePublicChannel() _, response, _ := th.SystemAdminClient.LinkGroupSyncable(context.Background(), g.Id, channel.Id, model.GroupSyncableTypeChannel, patch) assert.Equal(t, http.StatusCreated, response.StatusCode) @@ -2472,7 +2472,7 @@ func TestGetGroupsGroupConstrainedParentTeam(t *testing.T) { th.App.Srv().SetLicense(model.NewTestLicense("ldap")) var groups []*model.Group - for i := 0; i < 4; i++ { + for i := range 4 { id := model.NewId() group, err := th.App.CreateGroup(&model.Group{ DisplayName: fmt.Sprintf("dn-foo_%d", i), @@ -2570,7 +2570,7 @@ func TestAddMembersToGroup(t *testing.T) { // Create test users with random usernames to prevent collisions users := make([]*model.User, 3) - for i := 0; i < 3; i++ { + for i := range 3 { randomId := model.NewId() user, appErr := th.App.CreateUser(th.Context, &model.User{ Email: th.GenerateTestEmail(), diff --git a/server/channels/api4/license_test.go b/server/channels/api4/license_test.go index 1ae13a06aad..e47f8f4e0cf 100644 --- a/server/channels/api4/license_test.go +++ b/server/channels/api4/license_test.go @@ -588,7 +588,7 @@ func TestGetLicenseLoadMetric(t *testing.T) { require.NoError(t, initialErr) // Add 50 active users (50/1000 * 1000 = 50) - for i := 0; i < 49; i++ { // 49 + 1 basic user = 50 active users + for range 49 { // 49 + 1 basic user = 50 active users user := th.CreateUser() // Make user active @@ -631,7 +631,7 @@ func TestGetLicenseLoadMetric(t *testing.T) { require.NoError(t, initialErr) // Add 19 active users (19/20 * 1000 = 950) - for i := 0; i < 18; i++ { // 18 + 1 basic user = 19 active users + for range 18 { // 18 + 1 basic user = 19 active users user := th.CreateUser() // Make user active @@ -674,7 +674,7 @@ func TestGetLicenseLoadMetric(t *testing.T) { require.NoError(t, initialErr) // Add 30 active users (30/20 * 1000 = 1500) - for i := 0; i < 29; i++ { // 29 + 1 basic user = 30 active users + for range 29 { // 29 + 1 basic user = 30 active users user := th.CreateUser() // Make user active diff --git a/server/channels/api4/post.go b/server/channels/api4/post.go index baee491cbff..401ed29768b 100644 --- a/server/channels/api4/post.go +++ b/server/channels/api4/post.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "strconv" "time" @@ -1233,12 +1234,10 @@ func moveThread(c *Context, w http.ResponseWriter, r *http.Request) { return } - userHasEmailDomain := len(c.App.Config().WranglerSettings.AllowedEmailDomain) == 0 - for _, domain := range c.App.Config().WranglerSettings.AllowedEmailDomain { - if user.EmailDomain() == domain { - userHasEmailDomain = true - break - } + userHasEmailDomain := true + // Only check the user's email domain if a list of allowed domains is configured + if len(c.App.Config().WranglerSettings.AllowedEmailDomain) > 0 { + userHasEmailDomain = slices.Contains(c.App.Config().WranglerSettings.AllowedEmailDomain, user.EmailDomain()) } if !userHasEmailDomain && !user.IsSystemAdmin() { diff --git a/server/channels/api4/post_test.go b/server/channels/api4/post_test.go index 29eb787d532..efb7ce15085 100644 --- a/server/channels/api4/post_test.go +++ b/server/channels/api4/post_test.go @@ -9,6 +9,7 @@ import ( "encoding/json" "errors" "fmt" + "maps" "net/http" "net/http/httptest" "net/url" @@ -1095,6 +1096,57 @@ func TestMoveThread(t *testing.T) { require.Equal(t, 2, len(posts.Posts)) require.Equal(t, newPost.Message, posts.Posts[posts.Order[0]].Message) }) + + t.Run("check permissions limited by AllowedEmailDomain", func(t *testing.T) { + th.App.UpdateConfig(func(c *model.Config) { + c.WranglerSettings.AllowedEmailDomain = []string{"foo.com", "bar.com"} + }) + t.Cleanup(func() { + th.App.UpdateConfig(func(c *model.Config) { + c.WranglerSettings.AllowedEmailDomain = make([]string, 0) + }) + }) + + // Create a public channel + publicChannel := createPublicChannel(th.BasicTeam.Id, "test-public-channel-allowed-email-domain", "Test Public Channel") + + // Create a new post to move + post := &model.Post{ + ChannelId: th.BasicChannel.Id, + Message: "test post", + } + newPost, resp, err := client.CreatePost(ctx, post) + require.NoError(t, err) + CheckCreatedStatus(t, resp) + require.NotNil(t, newPost) + + // Move the post to the public channel as a user without the configured domain + moveThreadParams := &model.MoveThreadParams{ + ChannelId: publicChannel.Id, + } + resp, err = client.MoveThread(ctx, newPost.Id, moveThreadParams) + require.Error(t, err) + CheckForbiddenStatus(t, resp) + + // Change the email domain to match the configured setting + th.BasicUser.Email = "basicuser@foo.com" + _, resp, err = client.UpdateUser(ctx, th.BasicUser) + require.NoError(t, err) + CheckOKStatus(t, resp) + + resp, err = client.MoveThread(ctx, newPost.Id, moveThreadParams) + require.NoError(t, err) + CheckOKStatus(t, resp) + + // Check that the post was moved to the public channel + posts, resp, err := client.GetPostsForChannel(ctx, publicChannel.Id, 0, 100, "", true, false) + require.NoError(t, err) + require.NotNil(t, resp) + require.NotNil(t, posts) + // There should be 2 posts, the system join message for the user who moved it joining the channel, and the post we moved + require.Equal(t, 2, len(posts.Posts)) + require.Equal(t, newPost.Message, posts.Posts[posts.Order[0]].Message) + }) } func TestCreatePostPublic(t *testing.T) { @@ -1369,7 +1421,7 @@ func TestUpdatePost(t *testing.T) { fileIds := make([]string, 3) data, err2 := testutils.ReadTestFile("test.png") require.NoError(t, err2) - for i := 0; i < len(fileIds); i++ { + for i := range fileIds { fileResp, _, err := client.UploadFile(context.Background(), data, channel.Id, "test.png") require.NoError(t, err) fileIds[i] = fileResp.FileInfos[0].Id @@ -1748,7 +1800,7 @@ func TestPatchPost(t *testing.T) { fileIDs := make([]string, 3) data, err2 := testutils.ReadTestFile("test.png") require.NoError(t, err2) - for i := 0; i < len(fileIDs); i++ { + for i := range fileIDs { fileResp, _, err := client.UploadFile(context.Background(), data, channel.Id, "test.png") require.NoError(t, err) fileIDs[i] = fileResp.FileInfos[0].Id @@ -4152,7 +4204,7 @@ func TestGetFileInfosForPost(t *testing.T) { fileIds := make([]string, 3) data, err := testutils.ReadTestFile("test.png") require.NoError(t, err) - for i := 0; i < 3; i++ { + for i := range 3 { fileResp, _, _ := client.UploadFile(context.Background(), data, th.BasicChannel.Id, "test.png") fileIds[i] = fileResp.FileInfos[0].Id } @@ -4765,9 +4817,7 @@ func TestCreatePostNotificationsWithCRT(t *testing.T) { patch := &model.UserPatch{} patch.NotifyProps = model.CopyStringMap(th.BasicUser.NotifyProps) - for k, v := range tc.notifyProps { - patch.NotifyProps[k] = v - } + maps.Copy(patch.NotifyProps, tc.notifyProps) // update user's notify props _, _, err := th.Client.PatchUser(context.Background(), th.BasicUser.Id, patch) diff --git a/server/channels/api4/preference_test.go b/server/channels/api4/preference_test.go index 4fe523d5343..9befd04b5d3 100644 --- a/server/channels/api4/preference_test.go +++ b/server/channels/api4/preference_test.go @@ -638,7 +638,7 @@ func TestDeletePreferences(t *testing.T) { // save 10 preferences var preferences model.Preferences - for i := 0; i < 10; i++ { + for range 10 { preference := model.Preference{ UserId: th.BasicUser.Id, Category: model.PreferenceCategoryDirectChannelShow, diff --git a/server/channels/api4/role_test.go b/server/channels/api4/role_test.go index 95c2e26c711..3eb83a7d959 100644 --- a/server/channels/api4/role_test.go +++ b/server/channels/api4/role_test.go @@ -208,7 +208,7 @@ func TestGetRolesByNames(t *testing.T) { th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { // too many roles should error with bad request roles := []string{} - for i := 0; i < GetRolesByNamesMax+10; i++ { + for i := range GetRolesByNamesMax + 10 { roles = append(roles, fmt.Sprintf("role1.Name%v", i)) } diff --git a/server/channels/api4/shared_channel_test.go b/server/channels/api4/shared_channel_test.go index 2cfb8498d3f..4c8d949568e 100644 --- a/server/channels/api4/shared_channel_test.go +++ b/server/channels/api4/shared_channel_test.go @@ -44,7 +44,7 @@ func TestGetAllSharedChannels(t *testing.T) { savedIds := make([]string, 0, pages*pageSize) // make some shared channels - for i := 0; i < pages*pageSize; i++ { + for i := range pages * pageSize { channel := th.CreateChannelWithClientAndTeam(th.Client, model.ChannelTypeOpen, th.BasicTeam.Id) sc := &model.SharedChannel{ ChannelId: channel.Id, @@ -63,7 +63,7 @@ func TestGetAllSharedChannels(t *testing.T) { t.Run("get shared channels paginated", func(t *testing.T) { channelIds := make([]string, 0, 21) - for i := 0; i < pages; i++ { + for i := range pages { channels, _, err := th.Client.GetAllSharedChannels(context.Background(), th.BasicTeam.Id, i, pageSize) require.NoError(t, err) channelIds = append(channelIds, getIds(channels)...) diff --git a/server/channels/api4/system_test.go b/server/channels/api4/system_test.go index 7bf56c0fa8a..46622a36373 100644 --- a/server/channels/api4/system_test.go +++ b/server/channels/api4/system_test.go @@ -424,7 +424,7 @@ func TestGetLogs(t *testing.T) { th := Setup(t) defer th.TearDown() - for i := 0; i < 20; i++ { + for i := range 20 { th.TestLogger.Info(strconv.Itoa(i)) } @@ -473,7 +473,7 @@ func TestDownloadLogs(t *testing.T) { th := Setup(t) defer th.TearDown() - for i := 0; i < 20; i++ { + for i := range 20 { th.TestLogger.Info(strconv.Itoa(i)) } err := th.TestLogger.Flush() @@ -487,7 +487,7 @@ func TestDownloadLogs(t *testing.T) { require.Contains(t, resp.Header.Get("Content-Disposition"), "attachment;filename=\"mattermost.log\"") bodyString := string(resData) - for i := 0; i < 20; i++ { + for i := range 20 { assert.Contains(t, bodyString, fmt.Sprintf(`"msg":"%d"`, i)) } }) diff --git a/server/channels/api4/team.go b/server/channels/api4/team.go index 5bbd7bbda10..3d09857d471 100644 --- a/server/channels/api4/team.go +++ b/server/channels/api4/team.go @@ -1876,7 +1876,7 @@ func teamMembersMinusGroupMembers(c *Context, w http.ResponseWriter, r *http.Req } groupIDs := []string{} - for _, gid := range strings.Split(c.Params.GroupIDs, ",") { + for gid := range strings.SplitSeq(c.Params.GroupIDs, ",") { if !model.IsValidId(gid) { c.SetInvalidParam("group_ids") return diff --git a/server/channels/api4/team_test.go b/server/channels/api4/team_test.go index ddf599a6dd1..1bd8a584644 100644 --- a/server/channels/api4/team_test.go +++ b/server/channels/api4/team_test.go @@ -1947,7 +1947,7 @@ func TestSearchAllTeamsPaged(t *testing.T) { commonRandom := model.NewId() teams := [3]*model.Team{} - for i := 0; i < 3; i++ { + for i := range 3 { uid := model.NewId() newTeam, err := th.App.CreateTeam(th.Context, &model.Team{ DisplayName: fmt.Sprintf("%s %d %s", commonRandom, i, uid), @@ -2995,7 +2995,7 @@ func TestAddTeamMembers(t *testing.T) { CheckNotFoundStatus(t, resp) // Test with many users. - for i := 0; i < 260; i++ { + for range 260 { testUserList = append(testUserList, GenerateTestID()) } _, resp, err = client.AddTeamMembers(context.Background(), team.Id, testUserList) @@ -3889,7 +3889,7 @@ func TestInviteUsersToTeam(t *testing.T) { require.Nilf(t, appErr, "%v, Should update the team", appErr) emailList := make([]string, 22) - for i := 0; i < 22; i++ { + for i := range 22 { emailList[i] = "test-" + strconv.Itoa(i) + "@common.com" } resp, err := client.InviteUsersToTeam(context.Background(), th.BasicTeam.Id, emailList) @@ -4030,7 +4030,7 @@ func TestInviteGuestsToTeam(t *testing.T) { require.Nilf(t, err, "%v, Should update the team", err) emailList := make([]string, 22) - for i := 0; i < 22; i++ { + for i := range 22 { emailList[i] = "test-" + strconv.Itoa(i) + "@guest.com" } invite := &model.GuestsInvite{ diff --git a/server/channels/api4/upload_test.go b/server/channels/api4/upload_test.go index 8f2f8537d41..3912526a3c5 100644 --- a/server/channels/api4/upload_test.go +++ b/server/channels/api4/upload_test.go @@ -215,7 +215,7 @@ func TestGetUploadsForUser(t *testing.T) { t.Run("success", func(t *testing.T) { uploads := make([]*model.UploadSession, 4) - for i := 0; i < len(uploads); i++ { + for i := range uploads { us := &model.UploadSession{ Id: model.NewId(), Type: model.UploadTypeAttachment, diff --git a/server/channels/api4/usage_test.go b/server/channels/api4/usage_test.go index c2ecc5b904f..e45798017c3 100644 --- a/server/channels/api4/usage_test.go +++ b/server/channels/api4/usage_test.go @@ -33,7 +33,7 @@ func TestGetPostsUsage(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() - for i := 0; i < 14; i++ { + for range 14 { th.CreatePost() } diff --git a/server/channels/api4/user.go b/server/channels/api4/user.go index d0089c7f9c6..2f704138be3 100644 --- a/server/channels/api4/user.go +++ b/server/channels/api4/user.go @@ -1478,7 +1478,7 @@ func updateUserRoles(c *Context, w http.ResponseWriter, r *http.Request) { } // require license feature to assign "new system roles" - for _, roleName := range strings.Fields(newRoles) { + for roleName := range strings.FieldsSeq(newRoles) { for _, id := range model.NewSystemRoleIDs { if roleName == id { if license := c.App.Channels().License(); license == nil || !*license.Features.CustomPermissionsSchemes { diff --git a/server/channels/api4/user_test.go b/server/channels/api4/user_test.go index 7d4375facf8..64087c91ff1 100644 --- a/server/channels/api4/user_test.go +++ b/server/channels/api4/user_test.go @@ -3853,7 +3853,7 @@ func TestResetPassword(t *testing.T) { require.Error(t, err) CheckBadRequestStatus(t, resp) code := "" - for i := 0; i < model.TokenSize; i++ { + for range model.TokenSize { code += "a" } resp, err = th.Client.ResetPassword(context.Background(), code, "newpwd") @@ -7189,7 +7189,7 @@ func TestGetThreadsForUser(t *testing.T) { client := th.Client var rootIds []*model.Post - for i := 0; i < 30; i++ { + for range 30 { rpost, resp, err := client.CreatePost(context.Background(), &model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) require.NoError(t, err) CheckCreatedStatus(t, resp) @@ -7220,7 +7220,7 @@ func TestGetThreadsForUser(t *testing.T) { client := th.Client var rootIds []*model.Post - for i := 0; i < 30; i++ { + for i := range 30 { rpost, _ := postAndCheck(t, client, &model.Post{ChannelId: th.BasicChannel.Id, Message: fmt.Sprintf("testMsg-%d", i)}) rootIds = append(rootIds, rpost) postAndCheck(t, client, &model.Post{ChannelId: th.BasicChannel.Id, Message: fmt.Sprintf("testReply-%d", i), RootId: rpost.Id}) @@ -7269,7 +7269,7 @@ func TestGetThreadsForUser(t *testing.T) { sysadminClient := th.SystemAdminClient var rootIds []*model.Post - for i := 0; i < 10; i++ { + for i := range 10 { rpost, resp, err := client.CreatePost(context.Background(), &model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) require.NoError(t, err) CheckCreatedStatus(t, resp) @@ -7308,7 +7308,7 @@ func TestGetThreadsForUser(t *testing.T) { sysadminClient := th.SystemAdminClient var rootIds []*model.Post - for i := 0; i < 10; i++ { + for i := range 10 { rpost, resp, err := client.CreatePost(context.Background(), &model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) require.NoError(t, err) CheckCreatedStatus(t, resp) @@ -9284,7 +9284,7 @@ func TestResetPasswordFailedAttempts(t *testing.T) { th.App.Channels().Ldap = mockLdap - for i := 0; i < 5; i++ { + for i := range 5 { mockedLdapUser := ldapUser mockedLdapUser.FailedAttempts = i mockLdap.Mock.On("DoLogin", mock.AnythingOfType("*request.Context"), mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(mockedLdapUser, &model.AppError{Id: "ent.ldap.do_login.invalid_password.app_error"}) diff --git a/server/channels/api4/websocket_test.go b/server/channels/api4/websocket_test.go index 23d7676e4bd..c3dcea46d60 100644 --- a/server/channels/api4/websocket_test.go +++ b/server/channels/api4/websocket_test.go @@ -107,7 +107,7 @@ func TestCreateDirectChannelWithSocket(t *testing.T) { users := make([]*model.User, 0) users = append(users, user2) - for i := 0; i < 10; i++ { + for range 10 { users = append(users, th.CreateUser()) } @@ -225,7 +225,7 @@ func TestWebSocketReconnectRace(t *testing.T) { WebSocketClient.Close() - for i := 0; i < n; i++ { + for range n { go func() { defer wg.Done() ws, err := th.CreateReliableWebSocketClient(connID, seq+1) diff --git a/server/channels/app/admin.go b/server/channels/app/admin.go index 2c043695fd2..d956a40e23c 100644 --- a/server/channels/app/admin.go +++ b/server/channels/app/admin.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "io" + "maps" "net/http" "time" @@ -96,9 +97,7 @@ func (s *Server) QueryLogs(rctx request.CTX, page, perPage int, logFilter *model logData[filteredNodeName] = clusterLogs[filteredNodeName] } } else { - for nodeName, logs := range clusterLogs { - logData[nodeName] = logs - } + maps.Copy(logData, clusterLogs) } } diff --git a/server/channels/app/authentication_test.go b/server/channels/app/authentication_test.go index 05b506af418..a0fb6fe5dad 100644 --- a/server/channels/app/authentication_test.go +++ b/server/channels/app/authentication_test.go @@ -130,7 +130,7 @@ func TestCheckPasswordAndAllCriteria(t *testing.T) { var completeWG sync.WaitGroup completeWG.Add(concurrentAttempts) - for i := 0; i < concurrentAttempts; i++ { + for i := range concurrentAttempts { go func(i int) { defer completeWG.Done() // Simulate concurrent failed login checks by same user @@ -141,7 +141,7 @@ func TestCheckPasswordAndAllCriteria(t *testing.T) { completeWG.Wait() expectedErrsCount := 0 - for i := 0; i < concurrentAttempts; i++ { + for i := range concurrentAttempts { if appErrs[i].Id == tc.expectedErrID { expectedErrsCount++ continue @@ -230,7 +230,7 @@ func TestCheckLdapUserPasswordAndAllCriteria(t *testing.T) { // Simulate failed login attempts if necessary if tc.expectedErrID == "api.user.check_user_login_attempts.too_many_ldap.app_error" { - for i := 0; i < maxFailedLoginAttempts-1; i++ { + for range maxFailedLoginAttempts - 1 { _, appErr = th.App.checkLdapUserPasswordAndAllCriteria(th.Context, ldapUser, "wrongpassword", "") require.NotNil(t, appErr) require.Equal(t, "ent.ldap.do_login.invalid_password.app_error", appErr.Id) @@ -331,7 +331,7 @@ func TestCheckLdapUserPasswordConcurrency(t *testing.T) { var completeWG sync.WaitGroup completeWG.Add(concurrentAttempts) - for i := 0; i < concurrentAttempts; i++ { + for i := range concurrentAttempts { go func(i int) { defer completeWG.Done() @@ -347,7 +347,7 @@ func TestCheckLdapUserPasswordConcurrency(t *testing.T) { completeWG.Wait() expectedErrsCount := 0 - for i := 0; i < concurrentAttempts; i++ { + for i := range concurrentAttempts { if appErrs[i].Id == tc.expectedErrID { expectedErrsCount++ continue diff --git a/server/channels/app/authorization.go b/server/channels/app/authorization.go index 70669fd2bec..a401cfa2b85 100644 --- a/server/channels/app/authorization.go +++ b/server/channels/app/authorization.go @@ -7,6 +7,7 @@ import ( "database/sql" "errors" "net/http" + "slices" "strings" "github.com/mattermost/mattermost/server/public/model" @@ -68,10 +69,8 @@ func (a *App) SessionHasPermissionToTeams(c request.CTX, session model.Session, return true } - for _, teamID := range teamIDs { - if teamID == "" { - return false - } + if slices.Contains(teamIDs, "") { + return false } // Check session permission, if it allows access, no need to check teams. @@ -366,10 +365,8 @@ func (a *App) RolesGrantPermission(roleNames []string, permissionId string) bool } permissions := role.Permissions - for _, permission := range permissions { - if permission == permissionId { - return true - } + if slices.Contains(permissions, permissionId) { + return true } } diff --git a/server/channels/app/bot_test.go b/server/channels/app/bot_test.go index 9dd4cf81561..a9fbfac3a6d 100644 --- a/server/channels/app/bot_test.go +++ b/server/channels/app/bot_test.go @@ -671,7 +671,7 @@ func TestDisableUserBots(t *testing.T) { } }() - for i := 0; i < 46; i++ { + for i := range 46 { bot, err := th.App.CreateBot(th.Context, &model.Bot{ Username: fmt.Sprintf("username%v", i), Description: "a bot", @@ -777,7 +777,7 @@ func TestNotifySysadminsBotOwnerDisabled(t *testing.T) { // create bots owned by user (equal to numBotsToPrint) var bot *model.Bot - for i := 0; i < numBotsToPrint; i++ { + for i := range numBotsToPrint { bot, err = th.App.CreateBot(th.Context, &model.Bot{ Username: fmt.Sprintf("bot%v", i), Description: "a bot", diff --git a/server/channels/app/channel.go b/server/channels/app/channel.go index 7004cc34453..aa2ed9d54e1 100644 --- a/server/channels/app/channel.go +++ b/server/channels/app/channel.go @@ -1270,7 +1270,7 @@ func (a *App) UpdateChannelMemberRoles(c request.CTX, channelID string, userID s member.SchemeUser = false member.SchemeAdmin = false - for _, roleName := range strings.Fields(newRoles) { + for roleName := range strings.FieldsSeq(newRoles) { var role *model.Role role, err = a.GetRoleByName(context.Background(), roleName) if err != nil { @@ -2307,7 +2307,6 @@ func (a *App) GetChannelMembersForUserWithPagination(c request.CTX, userID strin members := make([]*model.ChannelMember, 0, len(m)) for _, member := range m { - member := member members = append(members, &member.ChannelMember) } return members, nil @@ -3744,7 +3743,7 @@ func (a *App) GetGroupMessageMembersCommonTeams(c request.CTX, channelID string) }) userIDs := make([]string, len(users)) - for i := 0; i < len(users); i++ { + for i := range users { userIDs[i] = users[i].Id } diff --git a/server/channels/app/channel_test.go b/server/channels/app/channel_test.go index e1348721433..69a888da2f2 100644 --- a/server/channels/app/channel_test.go +++ b/server/channels/app/channel_test.go @@ -1484,7 +1484,7 @@ func TestGetPublicChannelsForTeam(t *testing.T) { require.NotNil(t, offTopic) expectedChannels = append(expectedChannels, offTopic) - for i := 0; i < 8; i++ { + for i := range 8 { channel := model.Channel{ DisplayName: fmt.Sprintf("Public %v", i), Name: fmt.Sprintf("public_%v", i), @@ -1521,7 +1521,7 @@ func TestGetPrivateChannelsForTeam(t *testing.T) { defer th.TearDown() var expectedChannels []*model.Channel - for i := 0; i < 8; i++ { + for i := range 8 { channel := model.Channel{ DisplayName: fmt.Sprintf("Private %v", i), Name: fmt.Sprintf("private_%v", i), @@ -2441,7 +2441,7 @@ func TestPatchChannelModerationsForChannel(t *testing.T) { wg := sync.WaitGroup{} wg.Add(20) - for i := 0; i < 10; i++ { + for range 10 { go func() { _, appErr := th.App.PatchChannelModerationsForChannel(th.Context, channel.DeepCopy(), addCreatePosts) require.Nil(t, appErr) @@ -2450,7 +2450,7 @@ func TestPatchChannelModerationsForChannel(t *testing.T) { wg.Done() }() } - for i := 0; i < 10; i++ { + for range 10 { go func() { _, appErr := th.App.PatchChannelModerationsForChannel(th.Context, channel.DeepCopy(), addCreatePosts) require.Nil(t, appErr) @@ -2506,7 +2506,7 @@ func TestClearChannelMembersCache(t *testing.T) { mockStore := th.App.Srv().Store().(*mocks.Store) mockChannelStore := mocks.ChannelStore{} cms := model.ChannelMembers{} - for i := 0; i < 200; i++ { + for range 200 { cms = append(cms, model.ChannelMember{ ChannelId: "1", }) @@ -2539,7 +2539,7 @@ func TestGetMemberCountsByGroup(t *testing.T) { mockStore := th.App.Srv().Store().(*mocks.Store) mockChannelStore := mocks.ChannelStore{} cmc := []*model.ChannelMemberCountByGroup{} - for i := 0; i < 5; i++ { + for i := range 5 { cmc = append(cmc, &model.ChannelMemberCountByGroup{ GroupId: model.NewId(), ChannelMemberCount: int64(i), @@ -3197,7 +3197,7 @@ func TestPatchChannelMembersNotifyProps(t *testing.T) { t.Run("should return an error when trying to update too many users at once", func(t *testing.T) { identifiers := make([]*model.ChannelMemberIdentifier, 201) - for i := 0; i < len(identifiers); i++ { + for i := range identifiers { identifiers[i] = &model.ChannelMemberIdentifier{UserId: "fakeuser", ChannelId: "fakechannel"} } diff --git a/server/channels/app/command.go b/server/channels/app/command.go index d855005c449..ee0699dc28e 100644 --- a/server/channels/app/command.go +++ b/server/channels/app/command.go @@ -7,6 +7,7 @@ import ( "context" "errors" "io" + "maps" "net/http" "net/url" "regexp" @@ -461,14 +462,10 @@ func (a *App) tryExecuteCustomCommand(c request.CTX, args *model.CommandArgs, tr p.Set("trigger_id", args.TriggerId) userMentionMap := a.MentionsToTeamMembers(c, message, team.Id) - for key, values := range userMentionMap.ToURLValues() { - p[key] = values - } + maps.Copy(p, userMentionMap.ToURLValues()) channelMentionMap := a.MentionsToPublicChannels(c, message, team.Id) - for key, values := range channelMentionMap.ToURLValues() { - p[key] = values - } + maps.Copy(p, channelMentionMap.ToURLValues()) hook, appErr := a.CreateCommandWebhook(cmd.Id, args) if appErr != nil { diff --git a/server/channels/app/email_test.go b/server/channels/app/email_test.go index 3d21c7052c2..e1148dcca3d 100644 --- a/server/channels/app/email_test.go +++ b/server/channels/app/email_test.go @@ -29,7 +29,7 @@ func TestSendInviteEmailRateLimits(t *testing.T) { memberInvite := &model.MemberInvite{} memberInvite.Emails = make([]string, 22) - for i := 0; i < 22; i++ { + for i := range 22 { memberInvite.Emails[i] = "test-" + strconv.Itoa(i) + "@common.com" } err = th.App.InviteNewUsersToTeam(th.Context, memberInvite.Emails, th.BasicTeam.Id, th.BasicUser.Id) diff --git a/server/channels/app/emoji_bench_test.go b/server/channels/app/emoji_bench_test.go index 4763acdfc67..1f5065b5d57 100644 --- a/server/channels/app/emoji_bench_test.go +++ b/server/channels/app/emoji_bench_test.go @@ -16,7 +16,6 @@ import ( func BenchmarkUploadEmojiImage(b *testing.B) { th := Setup(b) b.Cleanup(func() { - b.StopTimer() th.TearDown() }) @@ -26,8 +25,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { filename := "image.gif" b.Run("small", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestGif(b, 10, 10))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) @@ -37,8 +35,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { }) b.Run("max size", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestGif(b, MaxEmojiWidth, MaxEmojiHeight))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) @@ -48,8 +45,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { }) b.Run("too wide", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestGif(b, MaxEmojiOriginalWidth, MaxEmojiHeight))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) @@ -59,8 +55,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { }) b.Run("too tall", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestGif(b, MaxEmojiWidth, MaxEmojiOriginalWidth))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) @@ -70,8 +65,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { }) b.Run("too tall and too wide", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestGif(b, MaxEmojiOriginalWidth, MaxEmojiOriginalWidth))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) @@ -86,8 +80,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { b.Run("small", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestPng(b, 10, 10))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) @@ -98,8 +91,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { b.Run("max size", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestPng(b, MaxEmojiWidth, MaxEmojiHeight))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) @@ -109,8 +101,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { }) b.Run("too wide", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestPng(b, MaxEmojiOriginalWidth, MaxEmojiHeight))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) @@ -120,8 +111,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { }) b.Run("too tall", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestPng(b, MaxEmojiWidth, MaxEmojiOriginalWidth))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) @@ -131,8 +121,7 @@ func BenchmarkUploadEmojiImage(b *testing.B) { }) b.Run("too tall and too wide", func(b *testing.B) { file := strings.NewReader(string(utils.CreateTestPng(b, MaxEmojiOriginalWidth, MaxEmojiOriginalWidth))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { id := model.NewId() appErr := th.App.uploadEmojiImage(rctx, id, filename, file) require.Nil(b, appErr) diff --git a/server/channels/app/export_test.go b/server/channels/app/export_test.go index ccc71db7e58..3323d62c10c 100644 --- a/server/channels/app/export_test.go +++ b/server/channels/app/export_test.go @@ -1069,7 +1069,7 @@ func TestBuildPostReplies(t *testing.T) { createPostWithAttachments := func(th *TestHelper, n int, rootID string) *model.Post { var fileIDs []string - for i := 0; i < n; i++ { + for i := range n { info, err := th.App.Srv().Store().FileInfo().Save(th.Context, &model.FileInfo{ CreatorId: th.BasicUser.Id, Name: fmt.Sprintf("file%d", i), diff --git a/server/channels/app/extract_plugin_tar_test.go b/server/channels/app/extract_plugin_tar_test.go index aa31ed4efb2..a4e76c8f860 100644 --- a/server/channels/app/extract_plugin_tar_test.go +++ b/server/channels/app/extract_plugin_tar_test.go @@ -74,7 +74,7 @@ func TestExtractTarGz(t *testing.T) { t.Run("huge tar", func(t *testing.T) { files := make([]*tar.Header, 0, 10000) - for i := 0; i < 10000; i++ { + for i := range 10000 { files = append(files, &tar.Header{ Name: fmt.Sprintf("%d.txt", i), Typeflag: tar.TypeReg, diff --git a/server/channels/app/file_bench_test.go b/server/channels/app/file_bench_test.go index 8a7448961c8..aa18032cb51 100644 --- a/server/channels/app/file_bench_test.go +++ b/server/channels/app/file_bench_test.go @@ -175,7 +175,7 @@ func BenchmarkUploadFile(b *testing.B) { for _, file := range files { for _, fb := range fileBenchmarks { b.Run(file.title+"-"+fb.title, func(b *testing.B) { - for i := 0; i < b.N; i++ { + for i := 0; b.Loop(); i++ { fb.f(b, i, file.data, file.ext) } }) diff --git a/server/channels/app/helper_test.go b/server/channels/app/helper_test.go index 9f54dfc1430..93d37928ce1 100644 --- a/server/channels/app/helper_test.go +++ b/server/channels/app/helper_test.go @@ -11,6 +11,7 @@ import ( "io" "os" "path/filepath" + "slices" "strings" "sync" "testing" @@ -820,10 +821,8 @@ func (th *TestHelper) AddPermissionToRole(permission string, roleName string) { panic(err1) } - for _, existingPermission := range role.Permissions { - if existingPermission == permission { - return - } + if slices.Contains(role.Permissions, permission) { + return } role.Permissions = append(role.Permissions, permission) diff --git a/server/channels/app/imaging/decode_bench_test.go b/server/channels/app/imaging/decode_bench_test.go index ca88d81d88f..e2bc0a49485 100644 --- a/server/channels/app/imaging/decode_bench_test.go +++ b/server/channels/app/imaging/decode_bench_test.go @@ -28,16 +28,16 @@ func BenchmarkDecoderDecode(b *testing.B) { imgDir, ok := fileutils.FindDir("tests") require.True(b, ok) - b.ResetTimer() - var wg sync.WaitGroup - for i := 0; i < b.N; i++ { + for b.Loop() { + // Setup b.StopTimer() wg.Add(1) imgFile, err := os.Open(imgDir + "/fill_test_opaque.png") require.NoError(b, err) defer imgFile.Close() b.StartTimer() + go func() { defer wg.Done() img, _, err := d.Decode(imgFile) @@ -64,10 +64,8 @@ func BenchmarkDecoderDecodeMemBounded(b *testing.B) { imgDir, ok := fileutils.FindDir("tests") require.True(b, ok) - b.ResetTimer() - var wg sync.WaitGroup - for i := 0; i < b.N; i++ { + for b.Loop() { b.StopTimer() wg.Add(1) imgFile, err := os.Open(imgDir + "/fill_test_opaque.png") diff --git a/server/channels/app/imaging/preview_test.go b/server/channels/app/imaging/preview_test.go index f3aced826e6..63534275960 100644 --- a/server/channels/app/imaging/preview_test.go +++ b/server/channels/app/imaging/preview_test.go @@ -81,8 +81,8 @@ func TestGenerateThumbnail(t *testing.T) { func createTestImage(t *testing.T, width, height int) image.Image { t.Helper() img := image.NewNRGBA(image.Rect(0, 0, width, height)) - for y := 0; y < height; y++ { - for x := 0; x < width; x++ { + for y := range height { + for x := range width { img.Set(x, y, color.NRGBA{uint8(x % 256), uint8(y % 256), 0, 255}) } } diff --git a/server/channels/app/imaging/utils_bench_test.go b/server/channels/app/imaging/utils_bench_test.go index a69aabe175b..207a8d943c1 100644 --- a/server/channels/app/imaging/utils_bench_test.go +++ b/server/channels/app/imaging/utils_bench_test.go @@ -79,10 +79,11 @@ var tcs = []struct { func BenchmarkFillImageTransparency(b *testing.B) { for _, tc := range tcs { b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { b.StopTimer() img := tc.imgGen() b.StartTimer() + FillImageTransparency(img, image.White) } }) @@ -92,10 +93,11 @@ func BenchmarkFillImageTransparency(b *testing.B) { func BenchmarkFillImageTransparencyOld(b *testing.B) { for _, tc := range tcs { b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { b.StopTimer() img := tc.imgGen() b.StartTimer() + fillImageTransparencyOld(img, image.White) } }) diff --git a/server/channels/app/import.go b/server/channels/app/import.go index 9b0ca925fd3..3a29103dde2 100644 --- a/server/channels/app/import.go +++ b/server/channels/app/import.go @@ -301,7 +301,7 @@ func (a *App) bulkImport(c request.CTX, jsonlReader io.Reader, attachmentsReader // Set up the workers and channel for this type. lastLineType = line.Type linesChan = make(chan imports.LineImportWorkerData, workers) - for i := 0; i < workers; i++ { + for range workers { wg.Add(1) go a.bulkImportWorker(c, dryRun, extractContent, &wg, linesChan, errorsChan) } @@ -401,7 +401,7 @@ func (a *App) ListImports() ([]string, *model.AppError) { } results := make([]string, 0, len(imports)) - for i := 0; i < len(imports); i++ { + for i := range imports { filename := filepath.Base(imports[i]) if !strings.HasSuffix(filename, model.IncompleteUploadSuffix) { results = append(results, filename) diff --git a/server/channels/app/import_functions.go b/server/channels/app/import_functions.go index 19fad5e847b..38ab8d2ed5a 100644 --- a/server/channels/app/import_functions.go +++ b/server/channels/app/import_functions.go @@ -1037,7 +1037,7 @@ func (a *App) importUserTeams(rctx request.CTX, user *model.User, data *[]import } else { rawRoles := *tdata.Roles explicitRoles := []string{} - for _, role := range strings.Fields(rawRoles) { + for role := range strings.FieldsSeq(rawRoles) { if role == model.TeamGuestRoleId { isGuestByTeamID[team.Id] = true isUserByTeamId[team.Id] = false @@ -1194,7 +1194,7 @@ func (a *App) importUserChannels(rctx request.CTX, user *model.User, team *model if cdata.Roles != nil { rawRoles := *cdata.Roles explicitRoles := []string{} - for _, role := range strings.Fields(rawRoles) { + for role := range strings.FieldsSeq(rawRoles) { if role == model.ChannelGuestRoleId { isGuestByChannelId[channel.Id] = true isUserByChannelId[channel.Id] = false @@ -1365,7 +1365,6 @@ func (a *App) importReplies(rctx request.CTX, data []imports.ReplyImportData, po var err *model.AppError usernames := []string{} for _, replyData := range data { - replyData := replyData if err = imports.ValidateReplyImportData(&replyData, post.CreateAt, a.MaxPostSize()); err != nil { return err } @@ -1394,7 +1393,6 @@ func (a *App) importReplies(rctx request.CTX, data []imports.ReplyImportData, po ) for _, replyData := range data { - replyData := replyData user := users[strings.ToLower(*replyData.User)] // Check if this post already exists. @@ -1987,7 +1985,6 @@ func (a *App) importMultiplePostLines(rctx request.CTX, lines []imports.LineImpo } for _, postWithData := range postsWithData { - postWithData := postWithData if postWithData.postData.FlaggedBy != nil { var preferences model.Preferences @@ -2011,7 +2008,6 @@ func (a *App) importMultiplePostLines(rctx request.CTX, lines []imports.LineImpo if postWithData.postData.Reactions != nil { for _, reaction := range *postWithData.postData.Reactions { - reaction := reaction if err := a.importReaction(&reaction, postWithData.post); err != nil { return postWithData.lineNumber, err } @@ -2036,7 +2032,6 @@ func (a *App) uploadAttachments(rctx request.CTX, attachments *[]imports.Attachm } fileIDs := make(map[string]bool) for _, attachment := range *attachments { - attachment := attachment fileInfo, err := a.importAttachment(rctx, &attachment, post, teamID, extractContent) if err != nil { if attachment.Path != nil { @@ -2521,7 +2516,6 @@ func (a *App) importMultipleDirectPostLines(rctx request.CTX, lines []imports.Li if postWithData.directPostData.Reactions != nil { for _, reaction := range *postWithData.directPostData.Reactions { - reaction := reaction if err := a.importReaction(&reaction, postWithData.post); err != nil { return postWithData.lineNumber, err } diff --git a/server/channels/app/import_functions_test.go b/server/channels/app/import_functions_test.go index 60c06e53653..d3c0a0b25a2 100644 --- a/server/channels/app/import_functions_test.go +++ b/server/channels/app/import_functions_test.go @@ -1924,7 +1924,7 @@ func TestImportUserTeams(t *testing.T) { user := th.CreateUser() // Two times import must end with the same results - for x := 0; x < 2; x++ { + for range 2 { appErr := th.App.importUserTeams(th.Context, user, tc.data) if tc.expectedError { require.NotNil(t, appErr) @@ -2079,7 +2079,7 @@ func TestImportUserChannels(t *testing.T) { require.NoError(t, err) // Two times import must end with the same results - for x := 0; x < 2; x++ { + for range 2 { appErr := th.App.importUserChannels(th.Context, user, th.BasicTeam, tc.data) if tc.expectedError { require.NotNil(t, appErr) @@ -5856,10 +5856,9 @@ func BenchmarkCompareFilesContent(b *testing.B) { b.Run("plain", func(b *testing.B) { b.Run("local", func(b *testing.B) { b.ReportAllocs() - b.ResetTimer() - b.StopTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { + b.StopTimer() _, err := fileA.Seek(0, io.SeekStart) require.NoError(b, err) _, err = fileB.Seek(0, io.SeekStart) @@ -5867,13 +5866,14 @@ func BenchmarkCompareFilesContent(b *testing.B) { b.StartTimer() ok, err := compareFilesContent(fileA, fileB, 0) - b.StopTimer() require.NoError(b, err) require.True(b, ok) } }) b.Run("s3", func(b *testing.B) { + b.ReportAllocs() + th := SetupConfig(b, func(cfg *model.Config) { cfg.FileSettings = model.FileSettings{ DriverName: model.NewPointer(model.ImageDriverS3), @@ -5925,16 +5925,13 @@ func BenchmarkCompareFilesContent(b *testing.B) { require.NoError(b, err) }() - b.ResetTimer() - for _, fileSizeLabel := range fileSizeLabels { fileSize := fileSizesMap[fileSizeLabel] for _, bufSizeLabel := range bufSizeLabels { bufSize := bufSizesMap[bufSizeLabel] b.Run("bufSize-fileSize"+fileSizeLabel+"-bufSize"+bufSizeLabel, func(b *testing.B) { - b.ReportAllocs() - b.StopTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { + b.StopTimer() _, err := rdA.Seek(0, io.SeekStart) require.NoError(b, err) _, err = rdB.Seek(0, io.SeekStart) @@ -5948,7 +5945,6 @@ func BenchmarkCompareFilesContent(b *testing.B) { R: rdB, N: fileSize, }, bufSize) - b.StopTimer() require.NoError(b, err) require.True(b, ok) } @@ -5959,6 +5955,8 @@ func BenchmarkCompareFilesContent(b *testing.B) { }) b.Run("zip", func(b *testing.B) { + b.ReportAllocs() + zipFilePath := filepath.Join(tmpDir, "compareFiles.zip") zipFile, err := os.Create(zipFilePath) require.NoError(b, err) @@ -5997,14 +5995,11 @@ func BenchmarkCompareFilesContent(b *testing.B) { zipFileSize := info.Size() b.Run("local", func(b *testing.B) { - b.ResetTimer() - for _, label := range bufSizeLabels { bufSize := bufSizesMap[label] b.Run("bufSize-"+label, func(b *testing.B) { - b.ReportAllocs() - b.StopTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { + b.StopTimer() _, err := zipFile.Seek(0, io.SeekStart) require.NoError(b, err) zipRd, err := zip.NewReader(zipFile, zipFileSize) @@ -6018,7 +6013,6 @@ func BenchmarkCompareFilesContent(b *testing.B) { b.StartTimer() ok, err := compareFilesContent(zipFileA, zipFileB, bufSize) - b.StopTimer() require.NoError(b, err) require.True(b, ok) } @@ -6059,16 +6053,13 @@ func BenchmarkCompareFilesContent(b *testing.B) { require.NoError(b, err) }() - b.ResetTimer() - for _, fileSizeLabel := range fileSizeLabels { fileSize := fileSizesMap[fileSizeLabel] for _, bufSizeLabel := range bufSizeLabels { bufSize := bufSizesMap[bufSizeLabel] b.Run("bufSize-fileSize"+fileSizeLabel+"-bufSize"+bufSizeLabel, func(b *testing.B) { - b.ReportAllocs() - b.StopTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { + b.StopTimer() _, err := zipFileRd.Seek(0, io.SeekStart) require.NoError(b, err) zipRd, err := zip.NewReader(zipFileRd.(io.ReaderAt), zipFileSize) @@ -6088,7 +6079,6 @@ func BenchmarkCompareFilesContent(b *testing.B) { R: zipFileB, N: fileSize, }, bufSize) - b.StopTimer() require.NoError(b, err) require.True(b, ok) } diff --git a/server/channels/app/import_test.go b/server/channels/app/import_test.go index 8e9cd24b1fd..d1ce6a7d2c8 100644 --- a/server/channels/app/import_test.go +++ b/server/channels/app/import_test.go @@ -629,12 +629,10 @@ func BenchmarkBulkImport(b *testing.B) { require.NoError(b, err) defer jsonFile.Close() - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { err, _ := th.App.BulkImportWithPath(th.Context, jsonFile, nil, false, true, runtime.NumCPU(), dir) require.Nil(b, err) } - b.StopTimer() } func TestImportBulkImportWithAttachments(t *testing.T) { diff --git a/server/channels/app/import_utils_test.go b/server/channels/app/import_utils_test.go index 93350d68e18..be8b0a02775 100644 --- a/server/channels/app/import_utils_test.go +++ b/server/channels/app/import_utils_test.go @@ -35,7 +35,7 @@ func TestGeneratePassword(t *testing.T) { }) t.Run("Should not fail on concurrent calls", func(t *testing.T) { - for i := 0; i < 10; i++ { + for range 10 { go func() { _, err := generatePassword(10) require.NoError(t, err) diff --git a/server/channels/app/imports/import_validators.go b/server/channels/app/imports/import_validators.go index f9bbc6dd31d..fd1249754bd 100644 --- a/server/channels/app/imports/import_validators.go +++ b/server/channels/app/imports/import_validators.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "path/filepath" + "slices" "strings" "unicode/utf8" @@ -371,10 +372,8 @@ func validateAuthService(authService *string) *model.AppError { if authService == nil { return nil } - for _, valid := range validAuthServices { - if *authService == valid { - return nil - } + if slices.Contains(validAuthServices, *authService) { + return nil } return model.NewAppError("BulkImport", "app.import.validate_user_teams_import_data.invalid_auth_service.error", map[string]any{"AuthService": *authService}, "", http.StatusBadRequest) @@ -490,7 +489,6 @@ func ValidateReplyImportData(data *ReplyImportData, parentCreateAt int64, maxPos if data.Reactions != nil { for _, reaction := range *data.Reactions { - reaction := reaction if err := ValidateReactionImportData(&reaction, *data.CreateAt); err != nil { return err } @@ -535,7 +533,6 @@ func ValidatePostImportData(data *PostImportData, maxPostSize int) *model.AppErr if data.Reactions != nil { for _, reaction := range *data.Reactions { - reaction := reaction if err := ValidateReactionImportData(&reaction, *data.CreateAt); err != nil { return err } @@ -544,7 +541,6 @@ func ValidatePostImportData(data *PostImportData, maxPostSize int) *model.AppErr if data.Replies != nil { for _, reply := range *data.Replies { - reply := reply if err := ValidateReplyImportData(&reply, *data.CreateAt, maxPostSize); err != nil { return err } @@ -609,11 +605,8 @@ func ValidateDirectChannelImportData(data *DirectChannelImportData) *model.AppEr } } if data.Members != nil { - for _, member := range *data.Members { - if favoriter == member { - found = true - break - } + if slices.Contains(*data.Members, favoriter) { + found = true } } if !found { @@ -656,13 +649,7 @@ func ValidateDirectPostImportData(data *DirectPostImportData, maxPostSize int) * if data.FlaggedBy != nil { for _, flagger := range *data.FlaggedBy { - found := false - for _, member := range *data.ChannelMembers { - if flagger == member { - found = true - break - } - } + found := slices.Contains(*data.ChannelMembers, flagger) if !found { return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.unknown_flagger.error", map[string]any{"Username": flagger}, "", http.StatusBadRequest) } @@ -671,7 +658,6 @@ func ValidateDirectPostImportData(data *DirectPostImportData, maxPostSize int) * if data.Reactions != nil { for _, reaction := range *data.Reactions { - reaction := reaction if err := ValidateReactionImportData(&reaction, *data.CreateAt); err != nil { return err } @@ -680,7 +666,6 @@ func ValidateDirectPostImportData(data *DirectPostImportData, maxPostSize int) * if data.Replies != nil { for _, reply := range *data.Replies { - reply := reply if err := ValidateReplyImportData(&reply, *data.CreateAt, maxPostSize); err != nil { return err } diff --git a/server/channels/app/login.go b/server/channels/app/login.go index d7cd45504bf..cbf04b4af6a 100644 --- a/server/channels/app/login.go +++ b/server/channels/app/login.go @@ -32,7 +32,7 @@ func (a *App) CheckForClientSideCert(r *http.Request) (string, string, string) { email := "" if subject != "" { - for _, v := range strings.Split(subject, "/") { + for v := range strings.SplitSeq(subject, "/") { kv := strings.Split(v, "=") if len(kv) == 2 && kv[0] == "emailAddress" { email = kv[1] diff --git a/server/channels/app/notification_push_test.go b/server/channels/app/notification_push_test.go index 5103719e1db..6e8dc15a159 100644 --- a/server/channels/app/notification_push_test.go +++ b/server/channels/app/notification_push_test.go @@ -1468,7 +1468,7 @@ func TestAllPushNotifications(t *testing.T) { session *model.Session } var testData []userSession - for i := 0; i < 10; i++ { + for range 10 { u := th.CreateUser() sess, err := th.App.CreateSession(th.Context, &model.Session{ UserId: u.Id, @@ -1693,7 +1693,7 @@ func BenchmarkPushNotificationThroughput(b *testing.B) { session *model.Session } var testData []userSession - for i := 0; i < 50; i++ { + for range 50 { id := model.NewId() u := &model.User{ Id: id, @@ -1737,12 +1737,11 @@ func BenchmarkPushNotificationThroughput(b *testing.B) { Name: "testch", } - b.ResetTimer() // We have an inner loop which ranges the testdata slice // and we just repeat that. then := time.Now() cnt := 0 - for i := 0; i < b.N; i++ { + for b.Loop() { cnt++ var wg sync.WaitGroup for j, data := range testData { @@ -1783,6 +1782,5 @@ func BenchmarkPushNotificationThroughput(b *testing.B) { wg.Wait() } b.Logf("throughput: %f reqs/s", float64(len(testData)*cnt)/time.Since(then).Seconds()) - b.StopTimer() time.Sleep(2 * time.Second) } diff --git a/server/channels/app/notification_test.go b/server/channels/app/notification_test.go index 7569a3038b8..ff22786c3e5 100644 --- a/server/channels/app/notification_test.go +++ b/server/channels/app/notification_test.go @@ -131,7 +131,7 @@ func TestSendNotifications(t *testing.T) { t.Run("message in GM generate mention", func(t *testing.T) { users := []*model.User{} - for i := 0; i < 2; i++ { + for range 2 { user := th.CreateUser() users = append(users, user) } @@ -572,7 +572,7 @@ func TestSendNotificationsWithManyUsers(t *testing.T) { defer th.TearDown() users := []*model.User{} - for i := 0; i < 10; i++ { + for range 10 { user := th.CreateUser() th.LinkUserToTeam(user, th.BasicTeam) _, appErr := th.App.AddUserToChannel(th.Context, user, th.BasicChannel, false) diff --git a/server/channels/app/notify_admin.go b/server/channels/app/notify_admin.go index 563f68f3172..95b54cc19af 100644 --- a/server/channels/app/notify_admin.go +++ b/server/channels/app/notify_admin.go @@ -270,8 +270,8 @@ func (a *App) groupNotifyAdminByPlugin(data []*model.NotifyAdminData) map[string myMap := make(map[string][]*model.NotifyAdminData) for _, d := range data { if strings.HasPrefix(string(d.RequiredFeature), string(model.PluginFeature)) { - plugins := strings.Split(d.RequiredPlan, ",") - for _, plugin := range plugins { + plugins := strings.SplitSeq(d.RequiredPlan, ",") + for plugin := range plugins { myMap[plugin] = append(myMap[plugin], d) } } diff --git a/server/channels/app/opengraph_test.go b/server/channels/app/opengraph_test.go index 2272a856800..60657f8e2dd 100644 --- a/server/channels/app/opengraph_test.go +++ b/server/channels/app/opengraph_test.go @@ -24,7 +24,7 @@ func BenchmarkForceHTMLEncodingToUTF8(b *testing.B) { ContentType := "text/html; utf-8" b.Run("with converting", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { r := forceHTMLEncodingToUTF8(strings.NewReader(HTML), ContentType) og := opengraph.NewOpenGraph() @@ -34,7 +34,7 @@ func BenchmarkForceHTMLEncodingToUTF8(b *testing.B) { }) b.Run("without converting", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { og := opengraph.NewOpenGraph() err := og.ProcessHTML(strings.NewReader(HTML)) require.NoError(b, err) diff --git a/server/channels/app/platform/log.go b/server/channels/app/platform/log.go index d07ba5df4eb..51ed6583a52 100644 --- a/server/channels/app/platform/log.go +++ b/server/channels/app/platform/log.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "path" + "slices" "time" "github.com/hashicorp/go-multierror" @@ -305,13 +306,7 @@ func isLogFilteredByLevel(logFilter *model.LogFilter, entry *model.LogEntry) boo return false } - for _, level := range logLevels { - if entry.Level == level { - return false - } - } - - return true + return !slices.Contains(logLevels, entry.Level) } func isLogFilteredByDate(rctx request.CTX, logFilter *model.LogFilter, entry *model.LogEntry) bool { diff --git a/server/channels/app/platform/service_test.go b/server/channels/app/platform/service_test.go index c21c15074a1..59d2fce1a5a 100644 --- a/server/channels/app/platform/service_test.go +++ b/server/channels/app/platform/service_test.go @@ -211,7 +211,7 @@ func TestShutdown(t *testing.T) { // we create plenty of go routines to make sure we wait for all of them // to finish before shutting down - for i := 0; i < 1000; i++ { + for range 1000 { th.Service.Go(func() { time.Sleep(time.Millisecond * time.Duration(rand.Intn(20))) }) diff --git a/server/channels/app/platform/utils.go b/server/channels/app/platform/utils.go index 2e7af04bee2..d00722e1720 100644 --- a/server/channels/app/platform/utils.go +++ b/server/channels/app/platform/utils.go @@ -18,7 +18,7 @@ func getKeyHash(key string) string { // for getting items from cache. func allocateCacheTargets[T any](l int) []any { toPass := make([]any, 0, l) - for i := 0; i < l; i++ { + for range l { toPass = append(toPass, new(T)) } return toPass diff --git a/server/channels/app/platform/web_broadcast_hook_test.go b/server/channels/app/platform/web_broadcast_hook_test.go index 9fb13276dc9..c1fa060df00 100644 --- a/server/channels/app/platform/web_broadcast_hook_test.go +++ b/server/channels/app/platform/web_broadcast_hook_test.go @@ -110,7 +110,7 @@ func TestRunBroadcastHooks(t *testing.T) { var hookIDs []string var hookArgs []map[string]any - for i := 0; i < 10; i++ { + for i := range 10 { hookIDs = append(hookIDs, broadcastTest) hookArgs = append(hookArgs, map[string]any{ "makes_changes": i == 6, @@ -132,7 +132,7 @@ func TestRunBroadcastHooks(t *testing.T) { var hookIDs []string var hookArgs []map[string]any - for i := 0; i < 10; i++ { + for range 10 { hookIDs = append(hookIDs, broadcastTest) hookArgs = append(hookArgs, map[string]any{ "makes_changes": true, diff --git a/server/channels/app/platform/web_conn.go b/server/channels/app/platform/web_conn.go index cfcca77cfc1..2ae88d8b970 100644 --- a/server/channels/app/platform/web_conn.go +++ b/server/channels/app/platform/web_conn.go @@ -702,7 +702,7 @@ func _hasMsgLoss(deadQueue []*model.WebSocketEvent, deadQueuePtr int, seq int64) func _isInDeadQueue(deadQueue []*model.WebSocketEvent, seq int64) (bool, int) { // Can be optimized to traverse backwards from deadQueuePointer // Hopefully, traversing 128 elements is not too much overhead. - for i := 0; i < deadQueueSize; i++ { + for i := range deadQueueSize { elem := deadQueue[i] if elem == nil { return false, 0 @@ -716,7 +716,7 @@ func _isInDeadQueue(deadQueue []*model.WebSocketEvent, seq int64) (bool, int) { } func (wc *WebConn) clearDeadQueue() { - for i := 0; i < deadQueueSize; i++ { + for i := range deadQueueSize { if wc.deadQueue[i] == nil { break } diff --git a/server/channels/app/platform/web_conn_test.go b/server/channels/app/platform/web_conn_test.go index d9e3ea13c64..fa47a51c3e4 100644 --- a/server/channels/app/platform/web_conn_test.go +++ b/server/channels/app/platform/web_conn_test.go @@ -41,23 +41,23 @@ func TestWebConnAddDeadQueue(t *testing.T) { WebSocket: &websocket.Conn{}, }, th.Suite, &hookRunner{}) - for i := 0; i < 2; i++ { + for i := range 2 { msg := &model.WebSocketEvent{} msg = msg.SetSequence(int64(i)) wc.addToDeadQueue(msg) } - for i := 0; i < 2; i++ { + for i := range 2 { assert.Equal(t, int64(i), wc.deadQueue[i].GetSequence()) } // Should push out the first two elements - for i := 0; i < deadQueueSize; i++ { + for i := range deadQueueSize { msg := &model.WebSocketEvent{} msg = msg.SetSequence(int64(i + 2)) wc.addToDeadQueue(msg) } - for i := 0; i < deadQueueSize; i++ { + for i := range deadQueueSize { assert.Equal(t, int64(i+2), wc.deadQueue[(i+2)%deadQueueSize].GetSequence()) } } @@ -214,7 +214,7 @@ func TestWebConnDrainDeadQueue(t *testing.T) { wc := dialConn(t, th, s.Listener.Addr()) defer wc.WebSocket.Close() - for i := 0; i < limit; i++ { + for i := range limit { msg := model.NewWebSocketEvent("", "", "", "", map[string]bool{}, "") msg = msg.SetSequence(int64(i)) wc.addToDeadQueue(msg) diff --git a/server/channels/app/platform/web_hub.go b/server/channels/app/platform/web_hub.go index ccce892bc6e..b201cefb093 100644 --- a/server/channels/app/platform/web_hub.go +++ b/server/channels/app/platform/web_hub.go @@ -123,7 +123,7 @@ func (ps *PlatformService) hubStart(broadcastHooks map[string]BroadcastHook) { hubs := make([]*Hub, numberOfHubs) - for i := 0; i < numberOfHubs; i++ { + for i := range numberOfHubs { hubs[i] = newWebHub(ps) hubs[i].connectionIndex = i hubs[i].broadcastHooks = broadcastHooks @@ -505,7 +505,7 @@ func (h *Hub) Stop() { <-h.didStop // Ensure that all remaining elements are processed // before shutting down. - for i := 0; i < hubSemaphoreCount; i++ { + for range hubSemaphoreCount { h.hubSemaphore <- struct{}{} } } diff --git a/server/channels/app/platform/web_hub_test.go b/server/channels/app/platform/web_hub_test.go index 8e165794609..64d0926ff9f 100644 --- a/server/channels/app/platform/web_hub_test.go +++ b/server/channels/app/platform/web_hub_test.go @@ -169,7 +169,7 @@ func TestHubSessionRevokeRace(t *testing.T) { // There's no guarantee this will happen. But that's our best bet to trigger this race. wc1.InvalidateCache() - for i := 0; i < 10; i++ { + for range 10 { // If broadcast buffer has not emptied, // we sleep for a second and check again if len(hub.broadcast) > 0 { @@ -688,9 +688,8 @@ func BenchmarkHubConnIndexIteratorForUser(b *testing.B) { require.NoError(b, connIndex.Add(wc2)) require.NoError(b, connIndex.Add(wc3)) - b.ResetTimer() b.Run("2 users", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { globalIter = connIndex.ForUser(wc2.UserId) } }) @@ -704,9 +703,8 @@ func BenchmarkHubConnIndexIteratorForUser(b *testing.B) { wc4.SetSession(&model.Session{}) require.NoError(b, connIndex.Add(wc4)) - b.ResetTimer() b.Run("3 users", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { globalIter = connIndex.ForUser(wc2.UserId) } }) @@ -720,9 +718,8 @@ func BenchmarkHubConnIndexIteratorForUser(b *testing.B) { wc5.SetSession(&model.Session{}) require.NoError(b, connIndex.Add(wc5)) - b.ResetTimer() b.Run("4 users", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { globalIter = connIndex.ForUser(wc2.UserId) } }) @@ -784,8 +781,7 @@ func BenchmarkHubConnIndexIteratorForChannel(b *testing.B) { require.NoError(b, connIndex.Add(wc2)) require.NoError(b, connIndex.Add(wc3)) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { globalIter = connIndex.ForChannel(th.BasicChannel.Id) } } @@ -810,14 +806,14 @@ func BenchmarkHubConnIndex(b *testing.B) { Suite: th.Suite, UserId: model.NewId(), } - b.ResetTimer() b.Run("Add", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { err := connIndex.Add(wc1) require.NoError(b, err) err = connIndex.Add(wc2) require.NoError(b, err) + // Cleanup b.StopTimer() connIndex.Remove(wc1) connIndex.Remove(wc2) @@ -826,15 +822,15 @@ func BenchmarkHubConnIndex(b *testing.B) { }) b.Run("Remove", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { + // Setup b.StopTimer() err := connIndex.Add(wc1) require.NoError(b, err) err = connIndex.Add(wc2) require.NoError(b, err) - b.Error(err) - b.StartTimer() + b.StartTimer() connIndex.Remove(wc1) connIndex.Remove(wc2) } @@ -888,8 +884,7 @@ func BenchmarkGetHubForUserId(b *testing.B) { err := th.Service.Start(nil) require.NoError(b, err) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { hubSink = th.Service.GetHubForUserId(th.BasicUser.Id) } } diff --git a/server/channels/app/platform/websocket_reliable_test.go b/server/channels/app/platform/websocket_reliable_test.go index e9ced119e5d..1b2e57d2020 100644 --- a/server/channels/app/platform/websocket_reliable_test.go +++ b/server/channels/app/platform/websocket_reliable_test.go @@ -72,7 +72,7 @@ func TestUnmarshalDQFullBuffer(t *testing.T) { t.Run("dq full", func(t *testing.T) { // Create exactly deadQueueSize events events := make([]*model.WebSocketEvent, deadQueueSize) - for i := 0; i < deadQueueSize; i++ { + for i := range deadQueueSize { events[i] = model.NewWebSocketEvent(model.WebsocketEventPosted, "t1", "c1", "u1", nil, "").SetSequence(int64(i)) } @@ -97,7 +97,7 @@ func TestUnmarshalDQFullBuffer(t *testing.T) { // Alternative test: Create a simulation of the circular buffer behavior // This test fills up to the max and ensures wraparound works correctly events := make([]*model.WebSocketEvent, deadQueueSize) - for i := 0; i < deadQueueSize; i++ { + for i := range deadQueueSize { // Create events with sequence numbers that show wraparound // Last event will have highest sequence to demonstrate the break condition // Seq nos: 100 - 228 diff --git a/server/channels/app/plugin_api_test.go b/server/channels/app/plugin_api_test.go index 25bb36f1c4e..09d015aeeda 100644 --- a/server/channels/app/plugin_api_test.go +++ b/server/channels/app/plugin_api_test.go @@ -992,7 +992,7 @@ func TestPluginAPIGetPlugins(t *testing.T) { backend := filepath.Join(pluginDir, pluginID, "backend.exe") utils.CompileGo(t, pluginCode, backend) - err := os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(fmt.Sprintf(`{"id": "%s", "server": {"executable": "backend.exe"}}`, pluginID)), 0600) + err := os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), fmt.Appendf(nil, `{"id": "%s", "server": {"executable": "backend.exe"}}`, pluginID), 0600) require.NoError(t, err) manifest, activated, reterr := env.Activate(pluginID) @@ -2047,7 +2047,7 @@ func TestPluginHTTPUpgradeWebSocket(t *testing.T) { resp := <-wsc.ResponseChannel require.Equal(t, resp.Status, model.StatusOk) - for i := 0; i < 10; i++ { + for i := range 10 { wsc.SendMessage("custom_action", map[string]any{"value": i}) var resp *model.WebSocketResponse select { @@ -2479,7 +2479,7 @@ func TestSendPushNotification(t *testing.T) { session *model.Session } var userSessions []userSession - for i := 0; i < 3; i++ { + for range 3 { u := th.CreateUser() sess, err := th.App.CreateSession(th.Context, &model.Session{ UserId: u.Id, @@ -2879,7 +2879,7 @@ func TestPluginServeHTTPCompatibility(t *testing.T) { } ` - for _, goVersion := range strings.Fields(os.Getenv("GO_COMPATIBILITY_TEST_VERSIONS")) { + for goVersion := range strings.FieldsSeq(os.Getenv("GO_COMPATIBILITY_TEST_VERSIONS")) { t.Run(goVersion, func(t *testing.T) { tearDown, ids, errs := SetAppEnvironmentWithPluginsGoVersion(t, []string{pluginCode}, th.App, th.NewPluginAPI, goVersion) defer tearDown() diff --git a/server/channels/app/plugin_api_tests/test_kv/main.go b/server/channels/app/plugin_api_tests/test_kv/main.go index 140514011dd..b07082fbe31 100644 --- a/server/channels/app/plugin_api_tests/test_kv/main.go +++ b/server/channels/app/plugin_api_tests/test_kv/main.go @@ -43,7 +43,7 @@ func (p *MyPlugin) MessageWillBePosted(_ *plugin.Context, _ *model.Post) (*model data = []byte("some other data") var longKey string - for i := 0; i < model.KeyValueKeyMaxRunes; i++ { + for range model.KeyValueKeyMaxRunes { longKey += "k" } diff --git a/server/channels/app/plugin_hooks_test.go b/server/channels/app/plugin_hooks_test.go index dcf3a2fdb7e..6484018be2d 100644 --- a/server/channels/app/plugin_hooks_test.go +++ b/server/channels/app/plugin_hooks_test.go @@ -1537,7 +1537,7 @@ func TestHookNotificationWillBePushed(t *testing.T) { session *model.Session } var userSessions []userSession - for i := 0; i < 3; i++ { + for range 3 { u := th.CreateUser() sess, err := th.App.CreateSession(th.Context, &model.Session{ UserId: u.Id, diff --git a/server/channels/app/post_metadata_test.go b/server/channels/app/post_metadata_test.go index c76d48a5a31..03951699af7 100644 --- a/server/channels/app/post_metadata_test.go +++ b/server/channels/app/post_metadata_test.go @@ -44,7 +44,7 @@ func TestPreparePostListForClient(t *testing.T) { defer th.TearDown() postList := model.NewPostList() - for i := 0; i < 5; i++ { + for range 5 { postList.AddPost(&model.Post{}) } diff --git a/server/channels/app/post_persistent_notification.go b/server/channels/app/post_persistent_notification.go index da84bfa492b..a8ba1d9ce21 100644 --- a/server/channels/app/post_persistent_notification.go +++ b/server/channels/app/post_persistent_notification.go @@ -5,6 +5,7 @@ package app import ( "context" + "maps" "net/http" "time" @@ -213,9 +214,7 @@ func (a *App) persistentNotificationsAuxiliaryData(channelsMap map[string]*model return nil, nil, nil, nil, errors.Wrapf(err, "failed to get profiles for channel %s", c.Id) } channelGroupMap[c.Id] = make(map[string]*model.Group, len(groups)) - for groupID, group := range groups { - channelGroupMap[c.Id][groupID] = group - } + maps.Copy(channelGroupMap[c.Id], groups) props, err := a.Srv().Store().Channel().GetAllChannelMembersNotifyPropsForChannel(c.Id, true) if err != nil { return nil, nil, nil, nil, errors.Wrapf(err, "failed to get profiles for channel %s", c.Id) diff --git a/server/channels/app/post_test.go b/server/channels/app/post_test.go index f4c3b0277b7..8dfc7d74d29 100644 --- a/server/channels/app/post_test.go +++ b/server/channels/app/post_test.go @@ -1202,7 +1202,7 @@ func TestCreatePost(t *testing.T) { channelForPreview := th.CreateChannel(th.Context, th.BasicTeam) - for i := 0; i < 20; i++ { + for range 20 { user := th.CreateUser() th.LinkUserToTeam(user, th.BasicTeam) th.AddUserToChannel(user, channelForPreview) @@ -1235,7 +1235,7 @@ func TestCreatePost(t *testing.T) { n := 1000 var wg sync.WaitGroup wg.Add(n) - for i := 0; i < n; i++ { + for range n { go func() { defer wg.Done() post := previewPost.Clone() diff --git a/server/channels/app/report.go b/server/channels/app/report.go index b2fc17e5f0c..13146448c09 100644 --- a/server/channels/app/report.go +++ b/server/channels/app/report.go @@ -65,7 +65,7 @@ func (a *App) compileCSVChunks(prefix string, numberOfChunks int, headers []stri return model.NewAppError("saveCSVChunk", "app.save_csv_chunk.write_error", nil, "", http.StatusInternalServerError).Wrap(err) } - for i := 0; i < numberOfChunks; i++ { + for i := range numberOfChunks { chunkFilePath := makeFilePath(prefix, i, "csv") chunk, err := a.ReadFile(chunkFilePath) if err != nil { @@ -149,7 +149,7 @@ func (a *App) CleanupReportChunks(format string, prefix string, numberOfChunks i } func (a *App) cleanupCSVChunks(prefix string, numberOfChunks int) *model.AppError { - for i := 0; i < numberOfChunks; i++ { + for i := range numberOfChunks { chunkFilePath := makeFilePath(prefix, i, "csv") if err := a.RemoveFile(chunkFilePath); err != nil { return err diff --git a/server/channels/app/role.go b/server/channels/app/role.go index c678f92790b..424168a29fb 100644 --- a/server/channels/app/role.go +++ b/server/channels/app/role.go @@ -290,13 +290,7 @@ func removeRoles(rolesToRemove []string, roles string) string { newRoles := make([]string, 0) for _, role := range roleList { - shouldRemove := false - for _, roleToRemove := range rolesToRemove { - if role == roleToRemove { - shouldRemove = true - break - } - } + shouldRemove := slices.Contains(rolesToRemove, role) if !shouldRemove { newRoles = append(newRoles, role) } diff --git a/server/channels/app/scheduled_post_job_test.go b/server/channels/app/scheduled_post_job_test.go index 9353a859360..4e9b128e268 100644 --- a/server/channels/app/scheduled_post_job_test.go +++ b/server/channels/app/scheduled_post_job_test.go @@ -337,7 +337,7 @@ func TestHandleFailedScheduledPosts(t *testing.T) { th.App.handleFailedScheduledPosts(rctx, failedScheduledPosts) // Validate that the WebSocket events for both users are sent and received correctly - for i := 0; i < len(failedScheduledPosts); i++ { + for i := range failedScheduledPosts { var received *model.WebSocketEvent select { case received = <-messagesUser1: diff --git a/server/channels/app/server.go b/server/channels/app/server.go index 3c5e4b2ebe9..80ddadb5bde 100644 --- a/server/channels/app/server.go +++ b/server/channels/app/server.go @@ -1396,7 +1396,6 @@ func (s *Server) doLicenseExpirationCheck() { // send email to admin(s) for _, user := range users { - user := user if user.Email == "" { mlog.Error("Invalid system admin email.", mlog.String("user_email", user.Email)) continue diff --git a/server/channels/app/session.go b/server/channels/app/session.go index c61f31f6e7e..d498010c3d9 100644 --- a/server/channels/app/session.go +++ b/server/channels/app/session.go @@ -331,13 +331,13 @@ func (a *App) ExtendSessionExpiryIfNeeded(rctx request.CTX, session *model.Sessi // Only extend the expiry if the lessor of 1% or 1 day has elapsed within the // current session duration. - threshold := int64(math.Min(float64(sessionLength)*0.01, float64(model.DayInMilliseconds))) - // Minimum session length is 1 day as of this writing, therefore a minimum ~14 minutes threshold. - // However we'll add a sanity check here in case that changes. Minimum 5 minute threshold, - // meaning we won't write a new expiry more than every 5 minutes. - if threshold < 5*60*1000 { - threshold = 5 * 60 * 1000 - } + threshold := max( + int64(math.Min(float64(sessionLength)*0.01, float64(model.DayInMilliseconds))), + // Minimum session length is 1 day as of this writing, therefore a minimum ~14 minutes threshold. + // However we'll add a sanity check here in case that changes. Minimum 5 minute threshold, + // meaning we won't write a new expiry more than every 5 minutes. + 5*60*1000, + ) now := model.GetMillis() elapsed := now - (session.ExpiresAt - sessionLength) diff --git a/server/channels/app/session_test.go b/server/channels/app/session_test.go index 8b9cdbf29ed..7993b49e9ef 100644 --- a/server/channels/app/session_test.go +++ b/server/channels/app/session_test.go @@ -417,7 +417,7 @@ func TestSessionsLimit(t *testing.T) { r := &http.Request{} w := httptest.NewRecorder() - for i := 0; i < maxSessionsLimit; i++ { + for range maxSessionsLimit { session, err := th.App.DoLogin(th.Context, w, r, th.BasicUser, "", false, false, false) require.Nil(t, err) sessions = append(sessions, session) @@ -434,7 +434,7 @@ func TestSessionsLimit(t *testing.T) { } // Now add 10 more. - for i := 0; i < 10; i++ { + for range 10 { session, err := th.App.DoLogin(th.Context, w, r, th.BasicUser, "", false, false, false) require.Nil(t, err, "should not have an error creating user sessions") diff --git a/server/channels/app/shared_channel_global_user_sync_self_referential_test.go b/server/channels/app/shared_channel_global_user_sync_self_referential_test.go index bcb2fe97735..4d4084478b9 100644 --- a/server/channels/app/shared_channel_global_user_sync_self_referential_test.go +++ b/server/channels/app/shared_channel_global_user_sync_self_referential_test.go @@ -10,6 +10,7 @@ import ( "io" "net/http" "net/http/httptest" + "slices" "sync" "sync/atomic" "testing" @@ -201,7 +202,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { // Create regular users regularUsers := make([]*model.User, 3) - for i := 0; i < 3; i++ { + for i := range 3 { regularUsers[i] = th.CreateUser() regularUsers[i].UpdateAt = baseTime + int64(i*100) _, err = ss.User().Update(th.Context, regularUsers[i], true) @@ -327,7 +328,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { clusters := make([]*model.RemoteCluster, 3) testServers := make([]*httptest.Server, 3) - for i := 0; i < 3; i++ { + for i := range 3 { clusterName := fmt.Sprintf("cluster-%d", i+1) var count int32 syncMessagesPerCluster[clusterName] = &count @@ -385,7 +386,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { }() // Create remote clusters - for i := 0; i < 3; i++ { + for i := range 3 { clusters[i] = &model.RemoteCluster{ RemoteId: model.NewId(), Name: fmt.Sprintf("cluster-%d", i+1), @@ -403,7 +404,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { // Create users to sync users := make([]*model.User, 5) - for i := 0; i < 5; i++ { + for i := range 5 { users[i] = th.CreateUser() users[i].UpdateAt = model.GetMillis() + int64(i) _, err = ss.User().Update(th.Context, users[i], true) @@ -606,7 +607,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { require.NoError(t, err) // Create users - for i := 0; i < 3; i++ { + for i := range 3 { user := th.CreateUser() user.UpdateAt = model.GetMillis() + int64(i) _, err = ss.User().Update(th.Context, user, true) @@ -690,7 +691,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { defer testServer.Close() // Create users before creating remote cluster - for i := 0; i < 3; i++ { + for i := range 3 { user := th.CreateUser() user.UpdateAt = model.GetMillis() + int64(i) _, err = ss.User().Update(th.Context, user, true) @@ -815,7 +816,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { } // Create some users to sync - for i := 0; i < 3; i++ { + for i := range 3 { user := th.CreateUser() user.UpdateAt = model.GetMillis() + int64(i) _, err = ss.User().Update(th.Context, user, true) @@ -890,7 +891,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { require.NoError(t, err) // Create users to sync - for i := 0; i < 5; i++ { + for i := range 5 { user := th.CreateUser() user.UpdateAt = model.GetMillis() + int64(i) _, err = ss.User().Update(th.Context, user, true) @@ -913,7 +914,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { assert.Greater(t, firstCursor, int64(0), "Cursor should be set after first sync") // Create more users - for i := 0; i < 3; i++ { + for i := range 3 { user := th.CreateUser() user.UpdateAt = model.GetMillis() + int64(100+i) _, err = ss.User().Update(th.Context, user, true) @@ -1183,12 +1184,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { require.Eventually(t, func() bool { mu.Lock() defer mu.Unlock() - for _, userID := range syncedToB { - if userID == originalUser.Id { - return true - } - } - return false + return slices.Contains(syncedToB, originalUser.Id) }, 5*time.Second, 100*time.Millisecond, "Original user should sync from A to B") // Step 2: Simulate the synced user existing on Server B @@ -1229,12 +1225,7 @@ func TestSharedChannelGlobalUserSyncSelfReferential(t *testing.T) { require.Never(t, func() bool { mu.Lock() defer mu.Unlock() - for _, userID := range syncedBackToA { - if userID == syncedUserOnB.Id { - return true - } - } - return false + return slices.Contains(syncedBackToA, syncedUserOnB.Id) }, 2*time.Second, 100*time.Millisecond, "Synced user should NEVER be synced back to its originating cluster") // Verify that the synced user still exists locally but wasn't synced diff --git a/server/channels/app/shared_channel_membership_sync_self_referential_test.go b/server/channels/app/shared_channel_membership_sync_self_referential_test.go index 901eb50ebe6..1d747639d86 100644 --- a/server/channels/app/shared_channel_membership_sync_self_referential_test.go +++ b/server/channels/app/shared_channel_membership_sync_self_referential_test.go @@ -12,6 +12,7 @@ import ( "net/http" "net/http/httptest" "os" + "slices" "sync" "sync/atomic" "testing" @@ -231,7 +232,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { // Include different user types to test filtering numRegularUsers := (batchSize * 2) + 5 // Back to original regularUserIDs := make([]string, numRegularUsers) - for i := 0; i < numRegularUsers; i++ { + for i := range numRegularUsers { user := th.CreateUser() regularUserIDs[i] = user.Id _, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, user.Id, th.BasicUser.Id) @@ -641,12 +642,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { // Wait for successful sync with more robust checking require.Eventually(t, func() bool { - for _, syncedUserId := range successfulSyncs { - if syncedUserId == testUser.Id { - return true - } - } - return false + return slices.Contains(successfulSyncs, testUser.Id) }, 15*time.Second, 100*time.Millisecond, "Should have successful sync after recovery") // Verify recovery @@ -754,7 +750,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { // Phase 1: Add initial batch of users initialUsers := make([]*model.User, 10) - for i := 0; i < 10; i++ { + for i := range 10 { initialUsers[i] = th.CreateUser() _, _, appErr = th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, initialUsers[i].Id, th.BasicUser.Id) require.Nil(t, appErr) @@ -792,14 +788,14 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { // Phase 2: Mixed operations - remove some, add new ones // Remove first 3 users - for i := 0; i < 3; i++ { + for i := range 3 { appErr := th.App.RemoveUserFromChannel(th.Context, initialUsers[i].Id, th.SystemAdminUser.Id, channel) require.Nil(t, appErr) } // Add 5 new users newUsers := make([]*model.User, 5) - for i := 0; i < 5; i++ { + for i := range 5 { newUsers[i] = th.CreateUser() _, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, newUsers[i].Id, th.BasicUser.Id) require.Nil(t, appErr) @@ -859,7 +855,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { syncHandlers := make([]*SelfReferentialSyncHandler, 3) // Create 3 remote clusters and their servers - for i := 0; i < 3; i++ { + for i := range 3 { clusterName := fmt.Sprintf("cluster-%d", i+1) var count int32 syncMessagesPerCluster[clusterName] = &count @@ -931,7 +927,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { require.NoError(t, shareErr) // Create remote clusters - for i := 0; i < 3; i++ { + for i := range 3 { clusters[i] = &model.RemoteCluster{ RemoteId: model.NewId(), Name: fmt.Sprintf("cluster-%d", i+1), @@ -961,7 +957,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { // Add users to channel - they should sync to all remote clusters users := make([]*model.User, 5) - for i := 0; i < 5; i++ { + for i := range 5 { users[i] = th.CreateUser() _, _, addErr := th.App.AddUserToTeam(th.Context, team.Id, users[i].Id, th.BasicUser.Id) require.Nil(t, addErr) @@ -1157,7 +1153,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { }) // Add users to the channel after disabling the feature flag - for i := 0; i < 3; i++ { + for range 3 { user := th.CreateUser() _, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, user.Id, th.BasicUser.Id) require.Nil(t, appErr) @@ -1259,7 +1255,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { } // Add some users to sync - for i := 0; i < 3; i++ { + for range 3 { user := th.CreateUser() _, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, user.Id, th.BasicUser.Id) require.Nil(t, appErr) @@ -1378,7 +1374,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { // Add users to sync - use more than batch size to test batch sync // Default batch size is 20, so use 25 users to ensure batch processing - for i := 0; i < 25; i++ { + for range 25 { user := th.CreateUser() _, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, user.Id, th.BasicUser.Id) require.Nil(t, appErr) @@ -1410,7 +1406,7 @@ func TestSharedChannelMembershipSyncSelfReferential(t *testing.T) { }, 10*time.Second, 200*time.Millisecond, "Cursor should be set after first sync") // Add more users to ensure we still have > 20 total for batch sync - for i := 0; i < 5; i++ { + for range 5 { user := th.CreateUser() _, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, user.Id, th.BasicUser.Id) require.Nil(t, appErr) diff --git a/server/channels/app/slashcommands/auto_channels.go b/server/channels/app/slashcommands/auto_channels.go index 1881766882e..795b8f0134c 100644 --- a/server/channels/app/slashcommands/auto_channels.go +++ b/server/channels/app/slashcommands/auto_channels.go @@ -67,7 +67,7 @@ func (cfg *AutoChannelCreator) CreateTestChannels(c request.CTX, num utils.Range numChannels := utils.RandIntFromRange(num) channels := make([]*model.Channel, numChannels) - for i := 0; i < numChannels; i++ { + for i := range numChannels { var err error channels[i], err = cfg.createRandomChannel(c) if err != nil { diff --git a/server/channels/app/slashcommands/auto_environment.go b/server/channels/app/slashcommands/auto_environment.go index aa035f7f4f3..090098e1a6b 100644 --- a/server/channels/app/slashcommands/auto_environment.go +++ b/server/channels/app/slashcommands/auto_environment.go @@ -95,7 +95,7 @@ func CreateTestEnvironmentInTeam(a *app.App, c request.CTX, client *model.Client numPosts := utils.RandIntFromRange(rangePosts) numImages := utils.RandIntFromRange(rangePosts) / 4 - for j := 0; j < numPosts; j++ { + for range numPosts { user := users[utils.RandIntFromRange(utils.Range{Begin: 0, End: len(users) - 1})] _, _, err := client.LoginById(context.Background(), user.Id, UserPassword) if err != nil { diff --git a/server/channels/app/slashcommands/auto_teams.go b/server/channels/app/slashcommands/auto_teams.go index 064266d3dc2..ec8d4fe5264 100644 --- a/server/channels/app/slashcommands/auto_teams.go +++ b/server/channels/app/slashcommands/auto_teams.go @@ -70,7 +70,7 @@ func (cfg *AutoTeamCreator) CreateTestTeams(num utils.Range) ([]*model.Team, err numTeams := utils.RandIntFromRange(num) teams := make([]*model.Team, numTeams) - for i := 0; i < numTeams; i++ { + for i := range numTeams { var err error teams[i], err = cfg.createRandomTeam() if err != nil { diff --git a/server/channels/app/slashcommands/auto_users.go b/server/channels/app/slashcommands/auto_users.go index 6e0bc020b9b..93f976d4f15 100644 --- a/server/channels/app/slashcommands/auto_users.go +++ b/server/channels/app/slashcommands/auto_users.go @@ -140,7 +140,7 @@ func (cfg *AutoUserCreator) CreateTestUsers(c request.CTX, num utils.Range) ([]* numUsers := utils.RandIntFromRange(num) users := make([]*model.User, numUsers) - for i := 0; i < numUsers; i++ { + for i := range numUsers { var err error users[i], err = cfg.createRandomUser(c) if err != nil { diff --git a/server/channels/app/slashcommands/command_loadtest.go b/server/channels/app/slashcommands/command_loadtest.go index 402261cec46..365019e723b 100644 --- a/server/channels/app/slashcommands/command_loadtest.go +++ b/server/channels/app/slashcommands/command_loadtest.go @@ -10,6 +10,7 @@ import ( "net/http" "path" "regexp" + "slices" "strconv" "strings" @@ -207,8 +208,8 @@ func (*LoadTestProvider) HelpCommand(args *model.CommandArgs, message string) *m func (*LoadTestProvider) SetupCommand(a *app.App, rctx request.CTX, args *model.CommandArgs, message string) (*model.CommandResponse, error) { tokens := strings.Fields(strings.TrimPrefix(message, "setup")) - doTeams := contains(tokens, "teams") - doFuzz := contains(tokens, "fuzz") + doTeams := slices.Contains(tokens, "teams") + doFuzz := slices.Contains(tokens, "fuzz") numArgs := 0 if doTeams { @@ -445,7 +446,7 @@ func (*LoadTestProvider) DMsCommand(a *app.App, c request.CTX, args *model.Comma postCreator.CreateTime = time postCreator.UsersToPostFrom = []string{user.Id} numPosts := utils.RandIntFromRange(rng) - for i := 0; i < numPosts; i++ { + for range numPosts { if _, err := postCreator.CreateRandomPost(c); err != nil { return &model.CommandResponse{Text: "Failed to create test DMs: " + err.Error(), ResponseType: model.CommandResponseTypeEphemeral}, err } @@ -497,7 +498,7 @@ func (*LoadTestProvider) ThreadedPostCommand(a *app.App, c request.CTX, args *mo return &model.CommandResponse{Text: "Failed to create a post", ResponseType: model.CommandResponseTypeEphemeral}, err2 } numPosts := utils.RandIntFromRange(rng) - for i := 0; i < numPosts; i++ { + for range numPosts { _, err = testPoster.CreateRandomPostNested(c, rpost.Id) if err != nil { return &model.CommandResponse{Text: "Failed to create nested post", ResponseType: model.CommandResponseTypeEphemeral}, err @@ -561,7 +562,7 @@ func (*LoadTestProvider) PostsCommand(a *app.App, c request.CTX, args *model.Com numImages := utils.RandIntFromRange(utils.Range{Begin: 0, End: maxImages}) numPosts := utils.RandIntFromRange(rng) - for i := 0; i < numPosts; i++ { + for i := range numPosts { testPoster.HasImage = (i < numImages) _, err := testPoster.CreateRandomPost(c) if err != nil { @@ -752,12 +753,3 @@ func parseRange(rng string) (utils.Range, error) { } return utils.Range{Begin: begin, End: end}, nil } - -func contains(items []string, token string) bool { - for _, elem := range items { - if elem == token { - return true - } - } - return false -} diff --git a/server/channels/app/slashcommands/helper_test.go b/server/channels/app/slashcommands/helper_test.go index 503b839b52f..a60b9795627 100644 --- a/server/channels/app/slashcommands/helper_test.go +++ b/server/channels/app/slashcommands/helper_test.go @@ -8,6 +8,7 @@ import ( "context" "os" "path/filepath" + "slices" "strings" "testing" "time" @@ -385,10 +386,8 @@ func (th *TestHelper) addPermissionToRole(tb testing.TB, permission string, role role, appErr := th.App.GetRoleByName(context.Background(), roleName) require.Nil(tb, appErr) - for _, existingPermission := range role.Permissions { - if existingPermission == permission { - return - } + if slices.Contains(role.Permissions, permission) { + return } role.Permissions = append(role.Permissions, permission) diff --git a/server/channels/app/slashcommands/util.go b/server/channels/app/slashcommands/util.go index 7780bef39cb..ea9a7d952ee 100644 --- a/server/channels/app/slashcommands/util.go +++ b/server/channels/app/slashcommands/util.go @@ -38,7 +38,7 @@ func parseNamedArgs(cmd string) map[string]string { m[ActionKey] = split[1] // prefix with hyphen to avoid collision with arg named "action" } - for i := 0; i < len(split); i++ { + for i := range split { if !strings.HasPrefix(split[i], "--") { continue } diff --git a/server/channels/app/support_packet_test.go b/server/channels/app/support_packet_test.go index 098a5113204..0c3d396a5f2 100644 --- a/server/channels/app/support_packet_test.go +++ b/server/channels/app/support_packet_test.go @@ -385,19 +385,19 @@ func TestGetSupportPacketStats(t *testing.T) { t.Run("Happy path", func(t *testing.T) { var user *model.User - for i := 0; i < 4; i++ { + for range 4 { user = th.CreateUser() } th.BasicUser = user - for i := 0; i < 3; i++ { + for range 3 { deactivatedUser := th.CreateUser() require.NotNil(t, deactivatedUser) _, appErr := th.App.UpdateActive(th.Context, deactivatedUser, false) require.Nil(t, appErr) } - for i := 0; i < 2; i++ { + for range 2 { guest := th.CreateGuest() require.NotNil(t, guest) } @@ -407,7 +407,7 @@ func TestGetSupportPacketStats(t *testing.T) { team := th.CreateTeam() channel := th.CreateChannel(th.Context, team) - for i := 0; i < 3; i++ { + for range 3 { p := th.CreatePost(channel) require.NotNil(t, p) } @@ -462,7 +462,7 @@ func TestGetSupportPacketStats(t *testing.T) { cfg.AnalyticsSettings.MaxUsersForStatistics = model.NewPointer(1) }) - for i := 0; i < 5; i++ { + for range 5 { p := th.CreatePost(th.BasicChannel) require.NotNil(t, p) } diff --git a/server/channels/app/team.go b/server/channels/app/team.go index 96e54bcfd0b..d2f55e4156e 100644 --- a/server/channels/app/team.go +++ b/server/channels/app/team.go @@ -420,7 +420,7 @@ func (a *App) UpdateTeamMemberRoles(c request.CTX, teamID string, userID string, member.SchemeUser = false member.SchemeAdmin = false - for _, roleName := range strings.Fields(newRoles) { + for roleName := range strings.FieldsSeq(newRoles) { var role *model.Role role, err = a.GetRoleByName(context.Background(), roleName) if err != nil { diff --git a/server/channels/app/team_test.go b/server/channels/app/team_test.go index 47f8ee5594c..f1b66b003c4 100644 --- a/server/channels/app/team_test.go +++ b/server/channels/app/team_test.go @@ -1204,7 +1204,7 @@ func TestGetTeamMembers(t *testing.T) { users = append(users, *th.BasicUser) users = append(users, *th.BasicUser2) - for i := 0; i < 8; i++ { + for i := range 8 { user := model.User{ Email: strings.ToLower(model.NewId()) + "success+test@example.com", Username: fmt.Sprintf("user%v", i), @@ -1513,7 +1513,7 @@ func TestClearTeamMembersCache(t *testing.T) { mockStore := th.App.Srv().Store().(*mocks.Store) mockTeamStore := mocks.TeamStore{} tms := []*model.TeamMember{} - for i := 0; i < 200; i++ { + for range 200 { tms = append(tms, &model.TeamMember{ TeamId: "1", }) diff --git a/server/channels/app/teams/utils.go b/server/channels/app/teams/utils.go index 6ce1dd1c8c9..1a663e3d688 100644 --- a/server/channels/app/teams/utils.go +++ b/server/channels/app/teams/utils.go @@ -4,6 +4,7 @@ package teams import ( + "slices" "strings" "github.com/mattermost/mattermost/server/public/model" @@ -77,13 +78,7 @@ func (ts *TeamService) checkValidDomains(team *model.Team) error { validDomains := normalizeDomains(*ts.config().TeamSettings.RestrictCreationToDomains) if len(validDomains) > 0 { for _, domain := range normalizeDomains(team.AllowedDomains) { - matched := false - for _, d := range validDomains { - if domain == d { - matched = true - break - } - } + matched := slices.Contains(validDomains, domain) if !matched { return &DomainError{Domain: domain} } diff --git a/server/channels/app/upload_test.go b/server/channels/app/upload_test.go index e550eab799b..0d4e8cc5458 100644 --- a/server/channels/app/upload_test.go +++ b/server/channels/app/upload_test.go @@ -273,7 +273,7 @@ func TestUploadDataConcurrent(t *testing.T) { n := 8 wg.Add(n) - for i := 0; i < n; i++ { + for range n { go func() { defer wg.Done() rd := &io.LimitedReader{ @@ -296,7 +296,7 @@ func TestUploadDataConcurrent(t *testing.T) { wg.Add(n) - for i := 0; i < n; i++ { + for range n { go func() { defer wg.Done() rd := &io.LimitedReader{ diff --git a/server/channels/app/user.go b/server/channels/app/user.go index 53cf946c013..b57dd879315 100644 --- a/server/channels/app/user.go +++ b/server/channels/app/user.go @@ -2976,8 +2976,6 @@ func (a *App) UserIsFirstAdmin(rctx request.CTX, user *model.User) bool { } for _, systemAdminUser := range systemAdminUsers { - systemAdminUser := systemAdminUser - if systemAdminUser.CreateAt < user.CreateAt { return false } diff --git a/server/channels/app/user_test.go b/server/channels/app/user_test.go index 4368d60c948..5b3d90aa140 100644 --- a/server/channels/app/user_test.go +++ b/server/channels/app/user_test.go @@ -1384,7 +1384,7 @@ func TestInvalidatePasswordRecoveryTokens(t *testing.T) { defer th.TearDown() t.Run("remove manually added tokens", func(t *testing.T) { - for i := 0; i < 5; i++ { + for range 5 { token := model.NewToken( TokenTypePasswordRecovery, model.MapToJSON(map[string]string{"UserId": th.BasicUser.Id, "email": th.BasicUser.Email}), diff --git a/server/channels/app/users/utils.go b/server/channels/app/users/utils.go index 4a711e4f636..6f723dc6331 100644 --- a/server/channels/app/users/utils.go +++ b/server/channels/app/users/utils.go @@ -20,9 +20,9 @@ func CheckEmailDomain(email string, domains string) bool { return true } - domainArray := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(domains, "@", " ", -1), ",", " ", -1)))) + domainArray := strings.FieldsSeq(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(domains, "@", " ", -1), ",", " ", -1)))) - for _, d := range domainArray { + for d := range domainArray { if strings.HasSuffix(strings.ToLower(email), "@"+d) { return true } diff --git a/server/channels/app/webhook.go b/server/channels/app/webhook.go index 74b8cf15534..3c75bda011a 100644 --- a/server/channels/app/webhook.go +++ b/server/channels/app/webhook.go @@ -9,6 +9,7 @@ import ( "encoding/json" "errors" "io" + "maps" "net/http" "regexp" "strings" @@ -265,9 +266,7 @@ func splitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model. for { lastSplit := splits[len(splits)-1] newProps := make(map[string]any) - for k, v := range lastSplit.GetProps() { - newProps[k] = v - } + maps.Copy(newProps, lastSplit.GetProps()) origAttachments, _ := newProps[model.PostPropsAttachments].([]*model.SlackAttachment) newProps[model.PostPropsAttachments] = append(origAttachments, &newAttachment) newPropsString := model.StringInterfaceToJSON(newProps) diff --git a/server/channels/app/webhook_test.go b/server/channels/app/webhook_test.go index 5f3f1b2e1b1..6841a5ee9bb 100644 --- a/server/channels/app/webhook_test.go +++ b/server/channels/app/webhook_test.go @@ -818,7 +818,7 @@ func TestTriggerOutGoingWebhookWithUsernameAndIconURL(t *testing.T) { waitUntilWebhookResponseIsCreatedAsPost := func(channel *model.Channel, th *TestHelper, createdPost chan *model.Post) { go func() { - for i := 0; i < 5; i++ { + for range 5 { time.Sleep(time.Second) posts, _ := th.App.GetPosts(channel.Id, 0, 5) if len(posts.Posts) > 0 { diff --git a/server/channels/jobs/export_users_to_csv/export_users_to_csv.go b/server/channels/jobs/export_users_to_csv/export_users_to_csv.go index f76320181fb..77238f81c03 100644 --- a/server/channels/jobs/export_users_to_csv/export_users_to_csv.go +++ b/server/channels/jobs/export_users_to_csv/export_users_to_csv.go @@ -120,7 +120,7 @@ func getData(app ExportUsersToCSVAppIFace) func(jobData model.StringMap) ([]mode } reportableObjects := []model.ReportableObject{} - for i := 0; i < len(users); i++ { + for i := range users { reportableObjects = append(reportableObjects, users[i]) } diff --git a/server/channels/store/layer_generators/main.go b/server/channels/store/layer_generators/main.go index 93963b15476..b846c18539d 100644 --- a/server/channels/store/layer_generators/main.go +++ b/server/channels/store/layer_generators/main.go @@ -14,6 +14,7 @@ import ( "log" "os" "path" + "slices" "strings" "text/template" ) @@ -212,26 +213,17 @@ func generateLayer(name, templateFile string) ([]byte, error) { return strings.Join(vars, ", ") }, "errorToBoolean": func(results []string) string { - for _, typeName := range results { - if isError(typeName) { - return "err == nil" - } + if slices.ContainsFunc(results, isError) { + return "err == nil" } return "true" }, "errorPresent": func(results []string) bool { - for _, typeName := range results { - if isError(typeName) { - return true - } - } - return false + return slices.ContainsFunc(results, isError) }, "errorVar": func(results []string) string { - for _, typeName := range results { - if isError(typeName) { - return "err" - } + if slices.ContainsFunc(results, isError) { + return "err" } return "" }, diff --git a/server/channels/store/localcachelayer/layer.go b/server/channels/store/localcachelayer/layer.go index a489ab82261..6e478200389 100644 --- a/server/channels/store/localcachelayer/layer.go +++ b/server/channels/store/localcachelayer/layer.go @@ -577,7 +577,7 @@ func (s *LocalCacheStore) Invalidate() { // for getting items from cache. func allocateCacheTargets[T any](l int) []any { toPass := make([]any, 0, l) - for i := 0; i < l; i++ { + for range l { toPass = append(toPass, new(T)) } return toPass diff --git a/server/channels/store/localcachelayer/layer_test.go b/server/channels/store/localcachelayer/layer_test.go index 48d54e57bee..7819ce8fba1 100644 --- a/server/channels/store/localcachelayer/layer_test.go +++ b/server/channels/store/localcachelayer/layer_test.go @@ -45,7 +45,6 @@ func StoreTest(t *testing.T, f func(*testing.T, request.CTX, store.Store)) { } }() for _, st := range storeTypes { - st := st rctx := request.TestContext(t) t.Run(st.Name, func(t *testing.T) { @@ -65,7 +64,6 @@ func StoreTestWithSqlStore(t *testing.T, f func(*testing.T, request.CTX, store.S } }() for _, st := range storeTypes { - st := st rctx := request.TestContext(t) t.Run(st.Name, func(t *testing.T) { @@ -104,7 +102,6 @@ func initStores(logger mlog.LoggerIFace) { }() var eg errgroup.Group for _, st := range storeTypes { - st := st eg.Go(func() error { var err error @@ -137,7 +134,6 @@ func tearDownStores() { var wg sync.WaitGroup wg.Add(len(storeTypes)) for _, st := range storeTypes { - st := st go func() { if st.Store != nil { st.Store.Close() diff --git a/server/channels/store/localcachelayer/user_layer_test.go b/server/channels/store/localcachelayer/user_layer_test.go index 9ad82bb33dd..f92fb5e8054 100644 --- a/server/channels/store/localcachelayer/user_layer_test.go +++ b/server/channels/store/localcachelayer/user_layer_test.go @@ -89,7 +89,7 @@ func TestUserStoreCache(t *testing.T) { originalProps := make([]model.StringMap, len(storedUsers)) - for i := 0; i < len(storedUsers); i++ { + for i := range storedUsers { originalProps[i] = storedUsers[i].NotifyProps storedUsers[i].NotifyProps = map[string]string{} storedUsers[i].NotifyProps["key"] = "somevalue" @@ -98,13 +98,13 @@ func TestUserStoreCache(t *testing.T) { cachedUsers, err := cachedStore.User().GetProfileByIds(context.Background(), fakeUserIds, &store.UserGetByIdsOpts{}, true) require.NoError(t, err) - for i := 0; i < len(storedUsers); i++ { + for i := range storedUsers { assert.Equal(t, storedUsers[i].Id, cachedUsers[i].Id) } cachedUsers, err = cachedStore.User().GetProfileByIds(context.Background(), fakeUserIds, &store.UserGetByIdsOpts{}, true) require.NoError(t, err) - for i := 0; i < len(storedUsers); i++ { + for i := range storedUsers { storedUsers[i].Props = model.StringMap{} storedUsers[i].Timezone = model.StringMap{} assert.Equal(t, storedUsers[i], cachedUsers[i]) @@ -115,7 +115,7 @@ func TestUserStoreCache(t *testing.T) { assert.NotEqual(t, storedUsers[i], cachedUsers[i]) } - for i := 0; i < len(storedUsers); i++ { + for i := range storedUsers { storedUsers[i].NotifyProps = originalProps[i] } }) diff --git a/server/channels/store/searchlayer/layer_test.go b/server/channels/store/searchlayer/layer_test.go index 39f13545aa7..2b961793109 100644 --- a/server/channels/store/searchlayer/layer_test.go +++ b/server/channels/store/searchlayer/layer_test.go @@ -39,7 +39,7 @@ func TestUpdateConfigRace(t *testing.T) { var wg sync.WaitGroup wg.Add(5) - for i := 0; i < 5; i++ { + for range 5 { go func() { defer wg.Done() layer.UpdateConfig(cfg.Clone()) diff --git a/server/channels/store/sqlstore/channel_store.go b/server/channels/store/sqlstore/channel_store.go index fcd80e15292..d027d4d9f9a 100644 --- a/server/channels/store/sqlstore/channel_store.go +++ b/server/channels/store/sqlstore/channel_store.go @@ -256,13 +256,7 @@ func getChannelRoles(schemeGuest, schemeUser, schemeAdmin bool, defaultTeamGuest } } for _, impliedRole := range schemeImpliedRoles { - alreadyThere := false - for _, role := range result.roles { - if role == impliedRole { - alreadyThere = true - break - } - } + alreadyThere := slices.Contains(result.roles, impliedRole) if !alreadyThere { result.roles = append(result.roles, impliedRole) } @@ -468,13 +462,7 @@ func (db allChannelMember) Process() (string, string) { } } for _, impliedRole := range schemeImpliedRoles { - alreadyThere := false - for _, role := range roles { - if role == impliedRole { - alreadyThere = true - break - } - } + alreadyThere := slices.Contains(roles, impliedRole) if !alreadyThere { roles = append(roles, impliedRole) } @@ -2197,11 +2185,7 @@ func (s SqlChannelStore) GetChannelsWithUnreadsAndWithMentions(ctx context.Conte } } - if channel.LastPostAt > channel.LastViewedAt { - readTimes[channel.Id] = channel.LastPostAt - } else { - readTimes[channel.Id] = channel.LastViewedAt - } + readTimes[channel.Id] = max(channel.LastPostAt, channel.LastViewedAt) } return channelsWithUnreads, channelsWithMentions, readTimes, nil @@ -3553,7 +3537,7 @@ func (s SqlChannelStore) channelSearchQuery(opts *store.ChannelSearchOpts) sq.Se // Keep the number of likeTerms same as the number of columns // (c.Name, c.DisplayName, c.Purpose, c.Id?) likeTerms := make([]any, len(strings.Split(likeFields, ","))) - for i := 0; i < len(likeTerms); i++ { + for i := range likeTerms { likeTerms[i] = likeTerm } likeClause = strings.ReplaceAll(likeClause, ":LikeTerm", "?") @@ -3692,7 +3676,7 @@ func (s SqlChannelStore) buildLIKEClause(term string, searchColumns string) (lik // Prepare the LIKE portion of the query. var searchFields []string - for _, field := range strings.Split(searchColumns, ", ") { + for field := range strings.SplitSeq(searchColumns, ", ") { if s.DriverName() == model.DatabaseDriverPostgres { searchFields = append(searchFields, fmt.Sprintf("lower(%s) LIKE lower(%s) escape '*'", field, ":LikeTerm")) } else { @@ -4188,7 +4172,7 @@ func (s SqlChannelStore) ClearAllCustomRoleAssignments() (err error) { var newRoles []string - for _, role := range strings.Fields(member.Roles) { + for role := range strings.FieldsSeq(member.Roles) { for name := range builtInRoles { if name == role { newRoles = append(newRoles, role) diff --git a/server/channels/store/sqlstore/channel_store_categories.go b/server/channels/store/sqlstore/channel_store_categories.go index ba5e03169a0..36378767c7b 100644 --- a/server/channels/store/sqlstore/channel_store_categories.go +++ b/server/channels/store/sqlstore/channel_store_categories.go @@ -644,13 +644,7 @@ func (s SqlChannelStore) UpdateSidebarCategoryOrder(userId, teamId string, categ } for _, originalCategoryId := range existingOrder { - found := false - for _, newCategoryId := range categoryOrder { - if newCategoryId == originalCategoryId { - found = true - break - } - } + found := slices.Contains(categoryOrder, originalCategoryId) if !found { return store.NewErrInvalidInput("SidebarCategories", "id", fmt.Sprintf("%v", categoryOrder)) } @@ -873,8 +867,6 @@ func (s SqlChannelStore) UpdateSidebarChannelsByPreferences(preferences model.Pr defer finalizeTransactionX(transaction, &err) for _, preference := range preferences { - preference := preference - if preference.Category != model.PreferenceCategoryFavoriteChannel { continue } @@ -1021,8 +1013,6 @@ func (s SqlChannelStore) DeleteSidebarChannelsByPreferences(preferences model.Pr defer finalizeTransactionX(transaction, &err) for _, preference := range preferences { - preference := preference - if preference.Category != model.PreferenceCategoryFavoriteChannel { continue } diff --git a/server/channels/store/sqlstore/file_info_store.go b/server/channels/store/sqlstore/file_info_store.go index 6a82513213b..d06b747f761 100644 --- a/server/channels/store/sqlstore/file_info_store.go +++ b/server/channels/store/sqlstore/file_info_store.go @@ -676,7 +676,7 @@ func (fs SqlFileInfoStore) Search(rctx request.CTX, paramsList []*model.SearchPa queryTerms = terms + excludeClause } else { splitTerms := []string{} - for _, t := range strings.Fields(terms) { + for t := range strings.FieldsSeq(terms) { splitTerms = append(splitTerms, "+"+t) } queryTerms = strings.Join(splitTerms, " ") + excludeClause diff --git a/server/channels/store/sqlstore/post_acknowledgements_store.go b/server/channels/store/sqlstore/post_acknowledgements_store.go index cf67e4e631a..d4461df2c67 100644 --- a/server/channels/store/sqlstore/post_acknowledgements_store.go +++ b/server/channels/store/sqlstore/post_acknowledgements_store.go @@ -133,10 +133,7 @@ func (s *SqlPostAcknowledgementStore) GetForPosts(postIds []string) ([]*model.Po perPage := 200 for i := 0; i < len(postIds); i += perPage { - j := i + perPage - if len(postIds) < j { - j = len(postIds) - } + j := min(len(postIds), i+perPage) query := s.getQueryBuilder(). Select("PostId", "UserId", "ChannelId", "AcknowledgedAt", "RemoteId"). diff --git a/server/channels/store/sqlstore/post_priority_store.go b/server/channels/store/sqlstore/post_priority_store.go index 7df24791993..c1ac8f17d85 100644 --- a/server/channels/store/sqlstore/post_priority_store.go +++ b/server/channels/store/sqlstore/post_priority_store.go @@ -41,10 +41,7 @@ func (s *SqlPostPriorityStore) GetForPosts(postIds []string) ([]*model.PostPrior perPage := 200 for i := 0; i < len(postIds); i += perPage { - j := i + perPage - if len(postIds) < j { - j = len(postIds) - } + j := min(len(postIds), i+perPage) query := s.getQueryBuilder(). Select("PostId", "ChannelId", "Priority", "RequestedAck", "PersistentNotifications"). diff --git a/server/channels/store/sqlstore/post_store.go b/server/channels/store/sqlstore/post_store.go index b1b823c86c9..41c0a8db18e 100644 --- a/server/channels/store/sqlstore/post_store.go +++ b/server/channels/store/sqlstore/post_store.go @@ -2141,7 +2141,7 @@ func (s *SqlPostStore) search(teamId string, userId string, params *model.Search searchType := "Message" if params.IsHashtag { searchType = "Hashtags" - for _, term := range strings.Split(terms, " ") { + for term := range strings.SplitSeq(terms, " ") { termMap[strings.ToUpper(term)] = true } } @@ -2225,7 +2225,7 @@ func (s *SqlPostStore) search(teamId string, userId string, params *model.Search termsClause = terms + excludeClause } else { splitTerms := []string{} - for _, t := range strings.Fields(terms) { + for t := range strings.FieldsSeq(terms) { splitTerms = append(splitTerms, "+"+t) } termsClause = strings.Join(splitTerms, " ") + excludeClause @@ -2277,7 +2277,7 @@ func (s *SqlPostStore) search(teamId string, userId string, params *model.Search for _, p := range posts { if searchType == "Hashtags" { exactMatch := false - for _, tag := range strings.Split(p.Hashtags, " ") { + for tag := range strings.SplitSeq(p.Hashtags, " ") { if termMap[strings.ToUpper(tag)] { exactMatch = true break @@ -2304,8 +2304,8 @@ func removeMysqlStopWordsFromTerms(terms string) (string, error) { } newTerms := make([]string, 0) - separatedTerms := strings.Fields(terms) - for _, term := range separatedTerms { + separatedTerms := strings.FieldsSeq(terms) + for term := range separatedTerms { term = strings.TrimSpace(term) if term = re.ReplaceAllString(term, ""); term != "" { newTerms = append(newTerms, term) @@ -2781,11 +2781,7 @@ func (s *SqlPostStore) determineMaxPostSize() int { } // Assume a worst-case representation of four bytes per rune. - maxPostSize := int(maxPostSizeBytes) / 4 - - if maxPostSize < model.PostMessageMaxRunesV2 { - maxPostSize = model.PostMessageMaxRunesV2 - } + maxPostSize := max(int(maxPostSizeBytes)/4, model.PostMessageMaxRunesV2) mlog.Info("Post.Message has size restrictions", mlog.Int("max_characters", maxPostSize), mlog.Int("max_bytes", maxPostSizeBytes)) diff --git a/server/channels/store/sqlstore/preference_store.go b/server/channels/store/sqlstore/preference_store.go index 496e433e9cb..986cbe53fc0 100644 --- a/server/channels/store/sqlstore/preference_store.go +++ b/server/channels/store/sqlstore/preference_store.go @@ -50,7 +50,6 @@ func (s SqlPreferenceStore) Save(preferences model.Preferences) (err error) { defer finalizeTransactionX(transaction, &err) for _, preference := range preferences { - preference := preference if upsertErr := s.saveTx(transaction, &preference); upsertErr != nil { return upsertErr } diff --git a/server/channels/store/sqlstore/reaction_store.go b/server/channels/store/sqlstore/reaction_store.go index 62cf91dde49..2928038a8ab 100644 --- a/server/channels/store/sqlstore/reaction_store.go +++ b/server/channels/store/sqlstore/reaction_store.go @@ -240,7 +240,6 @@ func (s *SqlReactionStore) DeleteAllWithEmojiName(emojiName string) error { } for _, reaction := range reactions { - reaction := reaction _, err := s.GetMaster().Exec(UpdatePostHasReactionsOnDeleteQuery, now, reaction.PostId, reaction.PostId) if err != nil { mlog.Warn("Unable to update Post.HasReactions while removing reactions", diff --git a/server/channels/store/sqlstore/store_test.go b/server/channels/store/sqlstore/store_test.go index 434df4bc6ad..a0dc7da0476 100644 --- a/server/channels/store/sqlstore/store_test.go +++ b/server/channels/store/sqlstore/store_test.go @@ -90,7 +90,6 @@ func StoreTest(t *testing.T, f func(*testing.T, request.CTX, store.Store)) { } for _, st := range stores { - st := st rctx := request.TestContext(t) t.Run(st.Name, func(t *testing.T) { @@ -118,7 +117,6 @@ func StoreTestWithSearchTestEngine(t *testing.T, f func(*testing.T, store.Store, } for _, st := range stores { - st := st searchTestEngine := &searchtest.SearchTestEngine{ Driver: *st.SqlSettings.DriverName, } @@ -144,7 +142,6 @@ func StoreTestWithSqlStore(t *testing.T, f func(*testing.T, request.CTX, store.S } for _, st := range stores { - st := st rctx := request.TestContext(t) t.Run(st.Name, func(t *testing.T) { @@ -209,7 +206,6 @@ func initStores(logger mlog.LoggerIFace, parallelism int) { var eg errgroup.Group for _, st := range storeTypes { - st := st eg.Go(func() error { var err error st.SqlStore, err = New(*st.SqlSettings, logger, nil) @@ -238,7 +234,6 @@ func tearDownStores() { var wg sync.WaitGroup wg.Add(len(storeTypes)) for _, st := range storeTypes { - st := st go func() { if st.Store != nil { st.Store.Close() @@ -253,7 +248,6 @@ func tearDownStores() { var wgPool sync.WaitGroup wgPool.Add(len(storePools)) for _, pool := range storePools { - pool := pool go func() { defer wgPool.Done() pool.Close() @@ -393,12 +387,12 @@ func TestGetReplica(t *testing.T) { store.UpdateLicense(&model.License{}) replicas := make(map[*sqlxDBWrapper]bool) - for i := 0; i < 5; i++ { + for range 5 { replicas[store.GetReplica()] = true } searchReplicas := make(map[*sqlxDBWrapper]bool) - for i := 0; i < 5; i++ { + for range 5 { searchReplicas[store.GetSearchReplicaX()] = true } @@ -464,12 +458,12 @@ func TestGetReplica(t *testing.T) { }() replicas := make(map[*sqlxDBWrapper]bool) - for i := 0; i < 5; i++ { + for range 5 { replicas[store.GetReplica()] = true } searchReplicas := make(map[*sqlxDBWrapper]bool) - for i := 0; i < 5; i++ { + for range 5 { searchReplicas[store.GetSearchReplicaX()] = true } diff --git a/server/channels/store/sqlstore/team_store.go b/server/channels/store/sqlstore/team_store.go index 71a4b61e96e..f17b1f3133f 100644 --- a/server/channels/store/sqlstore/team_store.go +++ b/server/channels/store/sqlstore/team_store.go @@ -1420,7 +1420,7 @@ func (s SqlTeamStore) ClearAllCustomRoleAssignments() (err error) { var newRoles []string - for _, role := range strings.Fields(member.Roles) { + for role := range strings.FieldsSeq(member.Roles) { for name := range builtInRoles { if name == role { newRoles = append(newRoles, role) diff --git a/server/channels/store/sqlstore/testpool.go b/server/channels/store/sqlstore/testpool.go index e1fdabafc7b..0b2a9ab1cf3 100644 --- a/server/channels/store/sqlstore/testpool.go +++ b/server/channels/store/sqlstore/testpool.go @@ -33,7 +33,7 @@ func NewTestPool(logger mlog.LoggerIFace, driverName string, poolSize int) (*Tes var mut sync.Mutex var eg errgroup.Group - for i := 0; i < poolSize; i++ { + for range poolSize { eg.Go(func() error { settings := storetest.MakeSqlSettings(driverName, false) sqlStore, err := New(*settings, logger, nil) @@ -103,7 +103,6 @@ func (p *TestPool) Close() { var wg sync.WaitGroup wg.Add(len(p.entries)) for _, entry := range p.entries { - entry := entry go func() { defer wg.Done() entry.Store.Close() diff --git a/server/channels/store/sqlstore/user_store.go b/server/channels/store/sqlstore/user_store.go index 5116f04da75..e744de7cde0 100644 --- a/server/channels/store/sqlstore/user_store.go +++ b/server/channels/store/sqlstore/user_store.go @@ -1837,7 +1837,7 @@ func (us SqlUserStore) ClearAllCustomRoleAssignments() (err error) { var newRoles []string - for _, role := range strings.Fields(user.Roles) { + for role := range strings.FieldsSeq(user.Roles) { for name := range builtInRoles { if name == role { newRoles = append(newRoles, role) diff --git a/server/channels/store/sqlstore/utils.go b/server/channels/store/sqlstore/utils.go index 9d31c18e26c..26395e56614 100644 --- a/server/channels/store/sqlstore/utils.go +++ b/server/channels/store/sqlstore/utils.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "io" + "maps" "net/url" "strconv" "strings" @@ -202,9 +203,7 @@ func scanRowsIntoMap[K comparable, V any](rows *sql.Rows, scanner func(rows *sql results := make(map[K]V, len(defaults)) // Initialize with default values if provided - for k, v := range defaults { - results[k] = v - } + maps.Copy(results, defaults) for rows.Next() { key, value, err := scanner(rows) diff --git a/server/channels/store/sqlstore/utils_test.go b/server/channels/store/sqlstore/utils_test.go index a3eeecdf423..74b449c9526 100644 --- a/server/channels/store/sqlstore/utils_test.go +++ b/server/channels/store/sqlstore/utils_test.go @@ -49,13 +49,13 @@ var ( func BenchmarkMapStringsToQueryParams(b *testing.B) { b.Run("one item", func(b *testing.B) { input := []string{"apple"} - for i := 0; i < b.N; i++ { + for b.Loop() { keys, params = MapStringsToQueryParams(input, "Fruit") } }) b.Run("multiple items", func(b *testing.B) { input := []string{"carrot", "tomato", "potato"} - for i := 0; i < b.N; i++ { + for b.Loop() { keys, params = MapStringsToQueryParams(input, "Vegetable") } }) diff --git a/server/channels/store/storetest/attributes_store.go b/server/channels/store/storetest/attributes_store.go index 8595c84cb4b..477c7be2184 100644 --- a/server/channels/store/storetest/attributes_store.go +++ b/server/channels/store/storetest/attributes_store.go @@ -260,7 +260,7 @@ func testAttributesStoreSearchUsers(t *testing.T, rctx request.CTX, ss store.Sto } cursor := strings.Repeat("0", 26) - for i := 0; i < 5; i++ { + for range 5 { subjects, count, err := ss.Attributes().SearchUsers(rctx, model.SubjectSearchOptions{ Query: query, Args: []any{testPropertyValueA1}, diff --git a/server/channels/store/storetest/channel_store.go b/server/channels/store/storetest/channel_store.go index 1acfb1aae29..545b45f2bb8 100644 --- a/server/channels/store/storetest/channel_store.go +++ b/server/channels/store/storetest/channel_store.go @@ -4821,7 +4821,7 @@ func testChannelStoreGetMembersForUserWithCursorPagination(t *testing.T, rctx re userID := NewTestID() var channelIDs []string - for i := 0; i < 20; i++ { + for range 20 { ch := &model.Channel{ TeamId: t1.Id, DisplayName: "Channel1", @@ -6465,7 +6465,7 @@ func testAutocomplete(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore } t.Run("Limit", func(t *testing.T) { - for i := 0; i < model.ChannelSearchDefaultLimit+10; i++ { + for i := range model.ChannelSearchDefaultLimit + 10 { _, err = ss.Channel().Save(rctx, &model.Channel{ TeamId: teamID, DisplayName: "Channel " + strconv.Itoa(i), diff --git a/server/channels/store/storetest/channel_store_categories.go b/server/channels/store/storetest/channel_store_categories.go index 6bf0f41a188..8d1f72dd2d4 100644 --- a/server/channels/store/storetest/channel_store_categories.go +++ b/server/channels/store/storetest/channel_store_categories.go @@ -149,7 +149,7 @@ func testCreateInitialSidebarCategories(t *testing.T, rctx request.CTX, ss store var wg sync.WaitGroup - for i := 0; i < 10; i++ { + for range 10 { wg.Add(1) go func() { @@ -2216,8 +2216,7 @@ func testSidebarCategoryConcurrentAccess(t *testing.T, rctx request.CTX, ss stor t.Skip("This is known to fail on MySQL") } - for i := 0; i < 2; i++ { - i := i + for i := range 2 { t.Run(fmt.Sprint(i), func(t *testing.T) { t.Parallel() doTestSidebarCategoryConcurrentAccess(t, rctx, ss) @@ -2233,7 +2232,7 @@ func doTestSidebarCategoryConcurrentAccess(t *testing.T, rctx request.CTX, ss st // Create regular channels channels := make([]*model.Channel, 5) - for i := 0; i < len(channels); i++ { + for i := range channels { channel, nErr := ss.Channel().Save(rctx, &model.Channel{ Name: fmt.Sprintf("channel-%d", i), DisplayName: fmt.Sprintf("Channel %d", i), @@ -2252,7 +2251,7 @@ func doTestSidebarCategoryConcurrentAccess(t *testing.T, rctx request.CTX, ss st // Create DM channels to exercise different code paths dmChannels := make([]*model.Channel, 3) - for i := 0; i < len(dmChannels); i++ { + for i := range dmChannels { otherUserID := model.NewId() dmChannel, nErr := ss.Channel().CreateDirectChannel(rctx, &model.User{ Id: userID, @@ -2285,7 +2284,7 @@ func doTestSidebarCategoryConcurrentAccess(t *testing.T, rctx request.CTX, ss st // Create custom categories customCategories := make([]*model.SidebarCategoryWithChannels, 2) - for i := 0; i < 2; i++ { + for i := range 2 { customCategory, createErr := ss.Channel().CreateSidebarCategory(userID, team.Id, &model.SidebarCategoryWithChannels{ SidebarCategory: model.SidebarCategory{ DisplayName: fmt.Sprintf("Custom Category %d", i), @@ -2298,7 +2297,7 @@ func doTestSidebarCategoryConcurrentAccess(t *testing.T, rctx request.CTX, ss st // Run concurrent operations var wg sync.WaitGroup - for i := 0; i < numGoroutines; i++ { + for i := range numGoroutines { wg.Add(1) // Run GetSidebarCategoriesForTeamForUser go func() { diff --git a/server/channels/store/storetest/compliance_store.go b/server/channels/store/storetest/compliance_store.go index fa013b8fb6a..98553956500 100644 --- a/server/channels/store/storetest/compliance_store.go +++ b/server/channels/store/storetest/compliance_store.go @@ -376,10 +376,10 @@ func testComplianceExportDirectMessages(t *testing.T, rctx request.CTX, ss store require.NoError(t, nErr) } - for i := 0; i < 3; i++ { + for range 3 { createPost(nowMillis) } - for i := 0; i < 2; i++ { + for range 2 { createPost(nowMillis + 1) } @@ -1240,7 +1240,7 @@ func testMessageExportUntilUpdateAt(t *testing.T, rctx request.CTX, ss store.Sto var posts []*model.Post // user1 posts ten times in the public channel - for i := 0; i < 10; i++ { + for i := range 10 { post := &model.Post{ ChannelId: channel.Id, UserId: user1.Id, diff --git a/server/channels/store/storetest/group_store.go b/server/channels/store/storetest/group_store.go index 1c0ec0be78b..ef6c3d8a620 100644 --- a/server/channels/store/storetest/group_store.go +++ b/server/channels/store/storetest/group_store.go @@ -440,7 +440,7 @@ func testGroupStoreGetByIDs(t *testing.T, rctx request.CTX, ss store.Store) { var group1 *model.Group var group2 *model.Group - for i := 0; i < 2; i++ { + for i := range 2 { group := &model.Group{ Name: model.NewPointer(model.NewId()), DisplayName: model.NewId(), @@ -462,7 +462,7 @@ func testGroupStoreGetByIDs(t *testing.T, rctx request.CTX, ss store.Store) { require.NoError(t, err) require.Len(t, groups, 2) - for i := 0; i < 2; i++ { + for i := range 2 { require.True(t, (groups[i].Id == group1.Id || groups[i].Id == group2.Id)) } @@ -1506,7 +1506,7 @@ func testGroupPermanentDeleteMembersByUser(t *testing.T, rctx request.CTX, ss st var groups []*model.Group numberOfGroups := 5 - for i := 0; i < numberOfGroups; i++ { + for range numberOfGroups { g = &model.Group{ Name: model.NewPointer(model.NewId()), DisplayName: model.NewId(), @@ -1681,7 +1681,7 @@ func testGetAllGroupSyncablesByGroupTeam(t *testing.T, rctx request.CTX, ss stor groupTeams := []*model.GroupSyncable{} // Create groupTeams - for i := 0; i < numGroupSyncables; i++ { + for range numGroupSyncables { // Create Team t1 := &model.Team{ DisplayName: "Name", @@ -1754,7 +1754,7 @@ func testGetAllGroupSyncablesByGroupChannel(t *testing.T, rctx request.CTX, ss s groupChannels := []*model.GroupSyncable{} // Create groupChannels - for i := 0; i < numGroupSyncables; i++ { + for range numGroupSyncables { // Create Channel channel := &model.Channel{ TeamId: team.Id, @@ -4377,7 +4377,7 @@ func testTeamMembersMinusGroupMembers(t *testing.T, rctx request.CTX, ss store.S team, err := ss.Team().Save(team) require.NoError(t, err) - for i := 0; i < numberOfUsers; i++ { + for i := range numberOfUsers { user := &model.User{ Email: MakeEmail(), Username: fmt.Sprintf("a%d_%s", i, model.NewId()), @@ -4402,7 +4402,7 @@ func testTeamMembersMinusGroupMembers(t *testing.T, rctx request.CTX, ss store.S _, nErr := ss.Team().SaveMember(rctx, &model.TeamMember{TeamId: team.Id, UserId: user.Id, SchemeUser: true, SchemeAdmin: false}, 999) require.NoError(t, nErr) - for i := 0; i < numberOfGroups; i++ { + for i := range numberOfGroups { group := &model.Group{ Name: model.NewPointer(fmt.Sprintf("n_%d_%s", i, model.NewId())), DisplayName: model.NewId(), @@ -4420,7 +4420,7 @@ func testTeamMembersMinusGroupMembers(t *testing.T, rctx request.CTX, ss store.S }) // Add even users to even group, and the inverse - for i := 0; i < numberOfUsers; i++ { + for i := range numberOfUsers { groupIndex := int(math.Mod(float64(i), 2)) _, err := ss.Group().UpsertMember(groups[groupIndex].Id, users[i].Id) require.NoError(t, err) @@ -4529,7 +4529,7 @@ func testChannelMembersMinusGroupMembers(t *testing.T, rctx request.CTX, ss stor channel, err := ss.Channel().Save(rctx, channel, 9999) require.NoError(t, err) - for i := 0; i < numberOfUsers; i++ { + for i := range numberOfUsers { user := &model.User{ Email: MakeEmail(), Username: fmt.Sprintf("a%d_%s", i, model.NewId()), @@ -4565,7 +4565,7 @@ func testChannelMembersMinusGroupMembers(t *testing.T, rctx request.CTX, ss stor }) require.NoError(t, err) - for i := 0; i < numberOfGroups; i++ { + for i := range numberOfGroups { group := &model.Group{ Name: model.NewPointer(fmt.Sprintf("n_%d_%s", i, model.NewId())), DisplayName: model.NewId(), @@ -4583,7 +4583,7 @@ func testChannelMembersMinusGroupMembers(t *testing.T, rctx request.CTX, ss stor }) // Add even users to even group, and the inverse - for i := 0; i < numberOfUsers; i++ { + for i := range numberOfUsers { groupIndex := int(math.Mod(float64(i), 2)) _, err := ss.Group().UpsertMember(groups[groupIndex].Id, users[i].Id) require.NoError(t, err) @@ -4688,7 +4688,7 @@ func groupTestGetMemberCount(t *testing.T, rctx request.CTX, ss store.Store) { var user *model.User var nErr error - for i := 0; i < 2; i++ { + for i := range 2 { user = &model.User{ Email: MakeEmail(), Username: fmt.Sprintf("a%d_%s", i, model.NewId()), diff --git a/server/channels/store/storetest/job_store.go b/server/channels/store/storetest/job_store.go index 52c82dfbe8c..4285b46446b 100644 --- a/server/channels/store/storetest/job_store.go +++ b/server/channels/store/storetest/job_store.go @@ -63,7 +63,7 @@ func testJobSaveOnce(t *testing.T, rctx request.CTX, ss store.Store) { var wg sync.WaitGroup ids := make([]string, 2) - for i := 0; i < 2; i++ { + for i := range 2 { wg.Add(1) go func(i int) { defer wg.Done() @@ -756,7 +756,7 @@ func testJobDelete(t *testing.T, rctx request.CTX, ss store.Store) { func testJobCleanup(t *testing.T, rctx request.CTX, ss store.Store) { now := model.GetMillis() ids := make([]string, 0, 10) - for i := 0; i < 10; i++ { + for i := range 10 { job, err := ss.Job().Save(&model.Job{ Id: model.NewId(), CreateAt: now - int64(i), diff --git a/server/channels/store/storetest/plugin_store.go b/server/channels/store/storetest/plugin_store.go index 12ec4452c4c..5daf987496f 100644 --- a/server/channels/store/storetest/plugin_store.go +++ b/server/channels/store/storetest/plugin_store.go @@ -1249,7 +1249,7 @@ func testPluginList(t *testing.T, rctx request.CTX, ss store.Store) { pluginID := model.NewId() var keys []string - for i := 0; i < 150; i++ { + for range 150 { key := model.NewId() kv := &model.PluginKeyValue{ PluginId: pluginID, @@ -1287,7 +1287,7 @@ func testPluginList(t *testing.T, rctx request.CTX, ss store.Store) { var keys []string now := model.GetMillis() - for i := 0; i < 150; i++ { + for i := range 150 { key := model.NewId() var expireAt int64 @@ -1336,7 +1336,7 @@ func testPluginList(t *testing.T, rctx request.CTX, ss store.Store) { pluginID := model.NewId() var keys []string - for i := 0; i < 150; i++ { + for range 150 { key := model.NewId() kv := &model.PluginKeyValue{ PluginId: pluginID, diff --git a/server/channels/store/storetest/post_store.go b/server/channels/store/storetest/post_store.go index 4455dc7aaf2..a91338df91c 100644 --- a/server/channels/store/storetest/post_store.go +++ b/server/channels/store/storetest/post_store.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "slices" "sort" "strings" "testing" @@ -1820,7 +1821,7 @@ func testPostStorePermDeleteLimitExceeded(t *testing.T, rctx request.CTX, ss sto }, -1) require.NoError(t, err) - for i := 0; i < maxPosts+100; i++ { + for range maxPosts + 100 { post := &model.Post{ ChannelId: channel.Id, UserId: userID, @@ -2008,7 +2009,7 @@ func testPostStoreGetPostsBeforeAfter(t *testing.T, rctx request.CTX, ss store.S userID := model.NewId() var posts []*model.Post - for i := 0; i < 10; i++ { + for range 10 { post, err := ss.Post().Save(rctx, &model.Post{ ChannelId: channelID, UserId: userID, @@ -4247,7 +4248,7 @@ func testPostStorePermanentDeleteBatch(t *testing.T, rctx request.CTX, ss store. require.Equal(t, int64(0), deleted) t.Run("with pagination", func(t *testing.T) { - for i := 0; i < 3; i++ { + for range 3 { _, err = ss.Post().Save(rctx, &model.Post{ ChannelId: channel.Id, UserId: model.NewId(), @@ -4965,7 +4966,7 @@ func testPostStoreGetDirectPostParentsForExportAfterBatched(t *testing.T, rctx r o1.Type = model.ChannelTypeDirect var postIds []string - for i := 0; i < 150; i++ { + for range 150 { u1 := &model.User{} u1.Email = MakeEmail() u1.Nickname = model.NewId() @@ -5003,7 +5004,7 @@ func testPostStoreGetDirectPostParentsForExportAfterBatched(t *testing.T, rctx r require.NoError(t, nErr) postIds = append(postIds, p1.Id) } - sort.Slice(postIds, func(i, j int) bool { return postIds[i] < postIds[j] }) + slices.Sort(postIds) // Get all posts r1, err := ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26), false) @@ -5013,7 +5014,7 @@ func testPostStoreGetDirectPostParentsForExportAfterBatched(t *testing.T, rctx r for i := range r1 { exportedPostIds = append(exportedPostIds, r1[i].Id) } - sort.Slice(exportedPostIds, func(i, j int) bool { return exportedPostIds[i] < exportedPostIds[j] }) + slices.Sort(exportedPostIds) assert.ElementsMatch(t, postIds, exportedPostIds) // Get 100 @@ -5024,7 +5025,7 @@ func testPostStoreGetDirectPostParentsForExportAfterBatched(t *testing.T, rctx r for i := range r1 { exportedPostIds = append(exportedPostIds, r1[i].Id) } - sort.Slice(exportedPostIds, func(i, j int) bool { return exportedPostIds[i] < exportedPostIds[j] }) + slices.Sort(exportedPostIds) assert.ElementsMatch(t, postIds[:100], exportedPostIds) // Manually truncate Channels table until testlib can handle cleanups diff --git a/server/channels/store/storetest/preference_store.go b/server/channels/store/storetest/preference_store.go index 257e071c090..85dd1cabe88 100644 --- a/server/channels/store/storetest/preference_store.go +++ b/server/channels/store/storetest/preference_store.go @@ -256,7 +256,7 @@ func testPreferenceGetAll(t *testing.T, _ request.CTX, ss store.Store) { require.NoError(t, err) require.Equal(t, 3, len(result), "got the wrong number of preferences") - for i := 0; i < 3; i++ { + for i := range 3 { assert.Falsef(t, result[0] != preferences[i] && result[1] != preferences[i] && result[2] != preferences[i], "got incorrect preferences") } } diff --git a/server/channels/store/storetest/property_field_store.go b/server/channels/store/storetest/property_field_store.go index 3f3346d6f9e..122a139187e 100644 --- a/server/channels/store/storetest/property_field_store.go +++ b/server/channels/store/storetest/property_field_store.go @@ -682,7 +682,7 @@ func testCountForGroup(t *testing.T, _ request.CTX, ss store.Store) { groupID := model.NewId() // Create 5 property fields - for i := 0; i < 5; i++ { + for i := range 5 { field := &model.PropertyField{ GroupID: groupID, Name: fmt.Sprintf("Field %d", i), @@ -701,7 +701,7 @@ func testCountForGroup(t *testing.T, _ request.CTX, ss store.Store) { groupID := model.NewId() // Create 5 property fields - for i := 0; i < 5; i++ { + for i := range 5 { field := &model.PropertyField{ GroupID: groupID, Name: fmt.Sprintf("Field %d", i), @@ -733,7 +733,7 @@ func testCountForGroup(t *testing.T, _ request.CTX, ss store.Store) { groupID := model.NewId() // Create 5 property fields - for i := 0; i < 5; i++ { + for i := range 5 { field := &model.PropertyField{ GroupID: groupID, Name: fmt.Sprintf("Field %d", i), diff --git a/server/channels/store/storetest/property_value_store.go b/server/channels/store/storetest/property_value_store.go index 405898bf4d2..85e21857f59 100644 --- a/server/channels/store/storetest/property_value_store.go +++ b/server/channels/store/storetest/property_value_store.go @@ -160,7 +160,7 @@ func testGetManyPropertyValues(t *testing.T, _ request.CTX, ss store.Store) { groupID := model.NewId() newValues := []*model.PropertyValue{} - for i := 0; i < 3; i++ { + for i := range 3 { newValue := &model.PropertyValue{ TargetID: model.NewId(), TargetType: "test_type", diff --git a/server/channels/store/storetest/retention_policy_store.go b/server/channels/store/storetest/retention_policy_store.go index eea4601519d..d15e8a81c35 100644 --- a/server/channels/store/storetest/retention_policy_store.go +++ b/server/channels/store/storetest/retention_policy_store.go @@ -333,7 +333,7 @@ func testRetentionPolicyStoreGet(t *testing.T, rctx request.CTX, ss store.Store, // create multiple policies policiesWithCounts := make([]*model.RetentionPolicyWithTeamAndChannelCounts, 0) - for i := 0; i < 3; i++ { + for i := range 3 { teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, rctx, ss) defer deleteTeamsAndChannels(rctx, ss, teamIDs, channelIDs) policyWithIds := createRetentionPolicyWithTeamAndChannelIds( @@ -361,7 +361,7 @@ func testRetentionPolicyStoreGet(t *testing.T, rctx request.CTX, ss store.Store, } }) t.Run("get all with same display name", func(t *testing.T) { - for i := 0; i < 5; i++ { + for range 5 { teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, rctx, ss) defer deleteTeamsAndChannels(rctx, ss, teamIDs, channelIDs) proposal := createRetentionPolicyWithTeamAndChannelIds( @@ -390,7 +390,7 @@ func testRetentionPolicyStoreGetCount(t *testing.T, rctx request.CTX, ss store.S require.Equal(t, int64(0), count) }) t.Run("some policies", func(t *testing.T) { - for i := 0; i < 2; i++ { + for i := range 2 { saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy "+strconv.Itoa(i), nil, nil) } count, err := ss.RetentionPolicy().GetCount() diff --git a/server/channels/store/storetest/scheduled_post_store.go b/server/channels/store/storetest/scheduled_post_store.go index 749717eaf68..c8f6691e59e 100644 --- a/server/channels/store/storetest/scheduled_post_store.go +++ b/server/channels/store/storetest/scheduled_post_store.go @@ -514,7 +514,7 @@ func testPermanentDeleteScheduledPostsByUser(t *testing.T, rctx request.CTX, ss teamId := model.NewId() // Create multiple scheduled posts for the user - for i := 0; i < 3; i++ { + for range 3 { scheduledPost := &model.ScheduledPost{ Draft: model.Draft{ CreateAt: model.GetMillis(), diff --git a/server/channels/store/storetest/shared_channel_store.go b/server/channels/store/storetest/shared_channel_store.go index 30a2c079c64..3710b18dee0 100644 --- a/server/channels/store/storetest/shared_channel_store.go +++ b/server/channels/store/storetest/shared_channel_store.go @@ -389,7 +389,7 @@ func testDeleteSharedChannel(t *testing.T, rctx request.CTX, ss store.Store) { require.NoError(t, err, "couldn't save shared channel", err) // add some remotes - for i := 0; i < 10; i++ { + for range 10 { remote := &model.SharedChannelRemote{ ChannelId: channel.Id, CreatorId: model.NewId(), @@ -1145,7 +1145,7 @@ func testGetSingleSharedChannelUser(t *testing.T, rctx request.CTX, ss store.Sto func testGetSharedChannelUser(t *testing.T, rctx request.CTX, ss store.Store) { userId := model.NewId() - for i := 0; i < 10; i++ { + for range 10 { scUser := &model.SharedChannelUser{ UserId: userId, RemoteId: model.NewId(), @@ -1177,7 +1177,7 @@ func testGetSharedChannelUsersForSync(t *testing.T, rctx request.CTX, ss store.S later := model.GetMillis() + 300000 var users []*model.User - for i := 0; i < 10; i++ { // need real users + for range 10 { // need real users u := &model.User{ Username: model.NewUsername(), Email: model.NewId() + "@example.com", diff --git a/server/channels/store/storetest/team_store.go b/server/channels/store/storetest/team_store.go index ea097600a16..b9ee446e5c9 100644 --- a/server/channels/store/storetest/team_store.go +++ b/server/channels/store/storetest/team_store.go @@ -2886,7 +2886,7 @@ func testSaveTeamMemberMaxMembers(t *testing.T, rctx request.CTX, ss store.Store userIds := make([]string, maxUsersPerTeam) - for i := 0; i < maxUsersPerTeam; i++ { + for i := range maxUsersPerTeam { user, err := ss.User().Save(rctx, &model.User{ Username: "a" + NewTestID(), Email: MakeEmail(), diff --git a/server/channels/store/storetest/tokens_store.go b/server/channels/store/storetest/tokens_store.go index 931f574111f..5254e8a752e 100644 --- a/server/channels/store/storetest/tokens_store.go +++ b/server/channels/store/storetest/tokens_store.go @@ -21,7 +21,7 @@ func TestTokensStore(t *testing.T, rctx request.CTX, ss store.Store) { func testTokensCleanup(t *testing.T, rctx request.CTX, ss store.Store) { now := model.GetMillis() - for i := 0; i < 10; i++ { + for i := range 10 { err := ss.Token().Save(&model.Token{ Token: model.NewRandomString(model.TokenSize), CreateAt: now - int64(i), diff --git a/server/channels/store/storetest/upload_session_store.go b/server/channels/store/storetest/upload_session_store.go index b2eb645f8c5..54bafca92b0 100644 --- a/server/channels/store/storetest/upload_session_store.go +++ b/server/channels/store/storetest/upload_session_store.go @@ -153,7 +153,7 @@ func testUploadSessionStoreGetForUser(t *testing.T, rctx request.CTX, ss store.S require.Empty(t, us) }) - for i := 0; i < len(sessions); i++ { + for i := range sessions { us, err := ss.UploadSession().Save(sessions[i]) require.NoError(t, err) require.NotNil(t, us) diff --git a/server/channels/store/storetest/user_access_token_store.go b/server/channels/store/storetest/user_access_token_store.go index 2037ec1e4e5..61eb8459378 100644 --- a/server/channels/store/storetest/user_access_token_store.go +++ b/server/channels/store/storetest/user_access_token_store.go @@ -168,7 +168,7 @@ func testUserAccessTokenPagination(t *testing.T, rctx request.CTX, ss store.Stor // Create 10 tokens for the user tokens := make([]*model.UserAccessToken, 10) - for i := 0; i < 10; i++ { + for i := range 10 { tokens[i] = &model.UserAccessToken{ Token: model.NewId(), UserId: u1.Id, diff --git a/server/channels/store/storetest/user_store.go b/server/channels/store/storetest/user_store.go index a7a23870fb7..d941f5339a7 100644 --- a/server/channels/store/storetest/user_store.go +++ b/server/channels/store/storetest/user_store.go @@ -151,7 +151,7 @@ func testUserStoreSave(t *testing.T, rctx request.CTX, ss store.Store) { _, err = ss.User().Save(rctx, &u3) require.Error(t, err, "auto responder message size should not be greater than maxPostSize") - for i := 0; i < 49; i++ { + for range 49 { u := model.User{ Email: MakeEmail(), Username: model.NewUsername(), @@ -5058,7 +5058,7 @@ func testUserStoreGetTeamGroupUsers(t *testing.T, rctx request.CTX, ss store.Sto // create users var testUsers []*model.User - for i := 0; i < 3; i++ { + for range 3 { id = model.NewId() user, userErr := ss.User().Save(rctx, &model.User{ Email: id + "@test.com", @@ -5085,7 +5085,7 @@ func testUserStoreGetTeamGroupUsers(t *testing.T, rctx request.CTX, ss store.Sto // create groups var testGroups []*model.Group - for i := 0; i < 2; i++ { + for range 2 { id = model.NewId() var group *model.Group @@ -5179,7 +5179,7 @@ func testUserStoreGetChannelGroupUsers(t *testing.T, rctx request.CTX, ss store. // create users var testUsers []*model.User - for i := 0; i < 3; i++ { + for range 3 { id = model.NewId() user, userErr := ss.User().Save(rctx, &model.User{ Email: id + "@test.com", @@ -5207,7 +5207,7 @@ func testUserStoreGetChannelGroupUsers(t *testing.T, rctx request.CTX, ss store. // create groups var testGroups []*model.Group - for i := 0; i < 2; i++ { + for range 2 { id = model.NewId() var group *model.Group group, err = ss.Group().Create(&model.Group{ @@ -6236,7 +6236,7 @@ func testGetUserReport(t *testing.T, rctx request.CTX, ss store.Store, s SqlStor now := time.Now() users := make([]*model.User, numUsers) - for i := 0; i < numUsers; i++ { + for i := range numUsers { user := &model.User{Username: fmt.Sprintf("username_%d", i), DeleteAt: 0} user.Email = MakeEmail() @@ -6265,7 +6265,7 @@ func testGetUserReport(t *testing.T, rctx request.CTX, ss store.Store, s SqlStor }() for _, user := range users { - for i := 0; i < numPostsPerUser; i++ { + for i := range numPostsPerUser { post := model.Post{UserId: user.Id, ChannelId: model.NewId(), Message: NewTestID(), CreateAt: now.AddDate(0, 0, -i).UnixMilli()} _, err := ss.Post().Save(rctx, &post) require.NoError(t, err) diff --git a/server/channels/store/storetest/utils_test.go b/server/channels/store/storetest/utils_test.go index 71d93286ecf..f224b3ee4c6 100644 --- a/server/channels/store/storetest/utils_test.go +++ b/server/channels/store/storetest/utils_test.go @@ -13,7 +13,7 @@ import ( func TestNewTestId(t *testing.T) { rg := regexp.MustCompile(`(\S\d){13}`) - for i := 0; i < 1000; i++ { + for range 1000 { id := NewTestID() require.LessOrEqual(t, len(id), 26, "test ids shouldn't be longer than 26 chars") require.Regexp(t, rg, id, "test ids should have pattern e.g a1b2c3...") diff --git a/server/channels/utils/api.go b/server/channels/utils/api.go index f603bd98796..2e47a6ec1a3 100644 --- a/server/channels/utils/api.go +++ b/server/channels/utils/api.go @@ -28,12 +28,7 @@ func CheckOrigin(r *http.Request, allowedOrigins string) bool { if allowedOrigins == "*" { return true } - for _, allowed := range strings.Split(allowedOrigins, " ") { - if allowed == origin { - return true - } - } - return false + return slices.Contains(strings.Split(allowedOrigins, " "), origin) } func OriginChecker(allowedOrigins string) func(*http.Request) bool { diff --git a/server/channels/utils/backoff.go b/server/channels/utils/backoff.go index a2ded50beaf..243bedbaa07 100644 --- a/server/channels/utils/backoff.go +++ b/server/channels/utils/backoff.go @@ -23,7 +23,7 @@ func LongProgressiveRetry(operation func() error) error { func CustomProgressiveRetry(operation func() error, backoffTimeouts []time.Duration) error { var err error - for attempts := 0; attempts < len(backoffTimeouts); attempts++ { + for attempts := range backoffTimeouts { err = operation() if err == nil { return nil diff --git a/server/channels/utils/emoji.go b/server/channels/utils/emoji.go index 9e70b89fd65..af1d8903d4a 100644 --- a/server/channels/utils/emoji.go +++ b/server/channels/utils/emoji.go @@ -31,7 +31,7 @@ func CreateTestAnimatedGif(tb testing.TB, width int, height int, frames int) []b Image: make([]*image.Paletted, frames), Delay: make([]int, frames), } - for i := 0; i < frames; i++ { + for i := range frames { img.Image[i] = image.NewPaletted(image.Rect(0, 0, width, height), color.Palette{color.Black}) img.Delay[i] = 0 } diff --git a/server/channels/utils/imgutils/gif.go b/server/channels/utils/imgutils/gif.go index 9bad0fc5cfc..e781b4d0a49 100644 --- a/server/channels/utils/imgutils/gif.go +++ b/server/channels/utils/imgutils/gif.go @@ -497,7 +497,7 @@ func GenGIFData(width, height uint16, nFrames int) []byte { } trailer := []byte{0x3b} gifData := header - for i := 0; i < nFrames; i++ { + for range nFrames { gifData = append(gifData, frame...) } gifData = append(gifData, trailer...) diff --git a/server/channels/utils/license.go b/server/channels/utils/license.go index fdd13b92d84..0f873e0ebf9 100644 --- a/server/channels/utils/license.go +++ b/server/channels/utils/license.go @@ -13,6 +13,7 @@ import ( "encoding/pem" "fmt" "io" + "maps" "net/http" "os" "path/filepath" @@ -202,9 +203,7 @@ func GetClientLicense(l *model.License) map[string]string { func GetSanitizedClientLicense(l map[string]string) map[string]string { sanitizedLicense := make(map[string]string) - for k, v := range l { - sanitizedLicense[k] = v - } + maps.Copy(sanitizedLicense, l) delete(sanitizedLicense, "Id") delete(sanitizedLicense, "Name") diff --git a/server/channels/utils/license_test.go b/server/channels/utils/license_test.go index 0d3a78b55c5..87cfa817db6 100644 --- a/server/channels/utils/license_test.go +++ b/server/channels/utils/license_test.go @@ -31,7 +31,7 @@ func TestValidateLicense(t *testing.T) { var licenseData bytes.Buffer var inputData []byte - for i := 0; i < 255; i++ { + for range 255 { inputData = append(inputData, 'A') } inputData = append(inputData, 0x00) @@ -51,7 +51,7 @@ func TestValidateLicense(t *testing.T) { var licenseData bytes.Buffer var inputData []byte - for i := 0; i < 256; i++ { + for range 256 { inputData = append(inputData, 0x00) } diff --git a/server/channels/utils/textgeneration.go b/server/channels/utils/textgeneration.go index 4a8f5f8e878..4b5f704e13b 100644 --- a/server/channels/utils/textgeneration.go +++ b/server/channels/utils/textgeneration.go @@ -469,7 +469,7 @@ Up to and hey without pill that this squid alas brusque on inventoried and sprea func RandString(l int, charset string) string { ret := make([]byte, l) - for i := 0; i < l; i++ { + for i := range l { ret[i] = charset[mrand.Intn(len(charset))] } return string(ret) @@ -479,7 +479,7 @@ func SecureRandString(n int) string { charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%&*0123456789" var str strings.Builder - for i := 0; i < n; i++ { + for range n { num, _ := crand.Int(crand.Reader, big.NewInt(int64(len(charset)))) str.WriteString(string(charset[num.Int64()])) } @@ -518,12 +518,12 @@ func RandomText(length Range, hashtags Range, mentions Range, users []string) st startPosition := RandIntFromRange(Range{0, len(GibberishText) - textLength - 1}) words := strings.Split(GibberishText[startPosition:startPosition+textLength], " ") - for i := 0; i < numHashtags; i++ { + for range numHashtags { randword := RandIntFromRange(Range{0, len(words) - 1}) words = append(words, " #"+words[randword]) } if len(users) > 0 { - for i := 0; i < numMentions; i++ { + for range numMentions { randuser := RandIntFromRange(Range{0, len(users) - 1}) words = append(words, " @"+users[randuser]) } diff --git a/server/channels/web/handlers.go b/server/channels/web/handlers.go index 7312b4cd8a5..7e2be7e763d 100644 --- a/server/channels/web/handlers.go +++ b/server/channels/web/handlers.go @@ -98,7 +98,7 @@ func generateDevCSP(c Context) string { // Add supported flags for debugging during development, even if not on a dev build. if *c.App.Config().ServiceSettings.DeveloperFlags != "" { - for _, devFlagKVStr := range strings.Split(*c.App.Config().ServiceSettings.DeveloperFlags, ",") { + for devFlagKVStr := range strings.SplitSeq(*c.App.Config().ServiceSettings.DeveloperFlags, ",") { devFlagKVSplit := strings.SplitN(devFlagKVStr, "=", 2) if len(devFlagKVSplit) != 2 { c.Logger.Warn("Unable to parse developer flag", mlog.String("developer_flag", devFlagKVStr)) diff --git a/server/channels/web/oauth_test.go b/server/channels/web/oauth_test.go index 20f0d056d9a..6912ca50be1 100644 --- a/server/channels/web/oauth_test.go +++ b/server/channels/web/oauth_test.go @@ -11,6 +11,7 @@ import ( "net/http" "net/http/httptest" "net/url" + "slices" "strings" "testing" @@ -845,10 +846,8 @@ func (th *TestHelper) AddPermissionToRole(permission string, roleName string) { panic(err1) } - for _, existingPermission := range role.Permissions { - if existingPermission == permission { - return - } + if slices.Contains(role.Permissions, permission) { + return } role.Permissions = append(role.Permissions, permission) diff --git a/server/channels/web/webhook_test.go b/server/channels/web/webhook_test.go index dafdb43ee00..38373d56044 100644 --- a/server/channels/web/webhook_test.go +++ b/server/channels/web/webhook_test.go @@ -31,7 +31,7 @@ func TestIncomingWebhook(t *testing.T) { url := apiClient.URL + "/hooks/" + hook.Id tooLongText := "" - for i := 0; i < 8200; i++ { + for range 8200 { tooLongText += "a" } @@ -264,7 +264,7 @@ func TestCommandWebhooks(t *testing.T) { require.NoError(t, err) assert.Equal(t, http.StatusBadRequest, resp.StatusCode) - for i := 0; i < 5; i++ { + for range 5 { response, err2 := http.Post(apiClient.URL+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString(`{"text":"this is a test"}`)) require.NoError(t, err2) require.Equal(t, http.StatusOK, response.StatusCode) diff --git a/server/cmd/mattermost/commands/cmdtestlib.go b/server/cmd/mattermost/commands/cmdtestlib.go index 1349cb6d7ad..e4d8ef1a23a 100644 --- a/server/cmd/mattermost/commands/cmdtestlib.go +++ b/server/cmd/mattermost/commands/cmdtestlib.go @@ -12,6 +12,7 @@ import ( "os" "os/exec" "path/filepath" + "slices" "strings" "testing" @@ -159,11 +160,8 @@ func (h *testHelper) execArgs(t *testing.T, args []string) []string { // Unless the test passes a `--config` of its own, create a temporary one from the default // configuration with the current test database applied. hasConfig := h.disableAutoConfig - for _, arg := range args { - if arg == "--config" { - hasConfig = true - break - } + if slices.Contains(args, "--config") { + hasConfig = true } if !hasConfig { diff --git a/server/cmd/mmctl/commands/auth.go b/server/cmd/mmctl/commands/auth.go index 20685c183d7..1fae8ec3e57 100644 --- a/server/cmd/mmctl/commands/auth.go +++ b/server/cmd/mmctl/commands/auth.go @@ -10,7 +10,7 @@ import ( "net/http" "net/url" "os" - "sort" + "slices" "strings" "syscall" @@ -322,9 +322,7 @@ func listCmdF(cmd *cobra.Command, args []string) error { maxInstanceURLLen = len(c.InstanceURL) } } - sort.Slice(serverNames, func(i, j int) bool { - return serverNames[i] < serverNames[j] - }) + slices.Sort(serverNames) printer.Print(fmt.Sprintf("\n | Active | %*s | %*s | %*s |", maxNameLen, nameTitle, maxUsernameLen, usernameTitle, maxInstanceURLLen, instanceURLTitle)) printer.Print(fmt.Sprintf(" |%s|%s|%s|%s|", strings.Repeat("-", 8), strings.Repeat("-", maxNameLen+2), strings.Repeat("-", maxUsernameLen+2), strings.Repeat("-", maxInstanceURLLen+2))) diff --git a/server/cmd/mmctl/commands/channel_e2e_test.go b/server/cmd/mmctl/commands/channel_e2e_test.go index 9df4dfadc81..8f72b6f40e8 100644 --- a/server/cmd/mmctl/commands/channel_e2e_test.go +++ b/server/cmd/mmctl/commands/channel_e2e_test.go @@ -23,7 +23,7 @@ func (s *MmctlE2ETestSuite) TestListChannelsCmdF() { var assertChannelNames = func(want []string, lines []any) { var got []string - for i := 0; i < len(lines); i++ { + for i := range lines { got = append(got, lines[i].(*model.Channel).Name) } diff --git a/server/cmd/mmctl/commands/completion_test.go b/server/cmd/mmctl/commands/completion_test.go index b6eb876de12..8e1a32dbd28 100644 --- a/server/cmd/mmctl/commands/completion_test.go +++ b/server/cmd/mmctl/commands/completion_test.go @@ -35,7 +35,7 @@ func TestFetchAndComplete(t *testing.T) { listNames := func(n int) []string { ret := []string{} - for i := 0; i < n; i++ { + for i := range n { ret = append(ret, fmt.Sprintf("name_%d", i)) } return ret diff --git a/server/cmd/mmctl/commands/export_e2e_test.go b/server/cmd/mmctl/commands/export_e2e_test.go index 67a2ad4b21a..0e03e67e309 100644 --- a/server/cmd/mmctl/commands/export_e2e_test.go +++ b/server/cmd/mmctl/commands/export_e2e_test.go @@ -50,7 +50,7 @@ func (s *MmctlE2ETestSuite) TestExportListCmdF() { cmd := &cobra.Command{} numExports := 3 - for i := 0; i < numExports; i++ { + for i := range numExports { exportName := fmt.Sprintf("export_%d.zip", i) err := utils.CopyFile(importFilePath, filepath.Join(exportPath, exportName)) s.Require().Nil(err) diff --git a/server/cmd/mmctl/commands/import_e2e_test.go b/server/cmd/mmctl/commands/import_e2e_test.go index 3b822e1424c..80e0ffa8e6f 100644 --- a/server/cmd/mmctl/commands/import_e2e_test.go +++ b/server/cmd/mmctl/commands/import_e2e_test.go @@ -162,7 +162,7 @@ func (s *MmctlE2ETestSuite) TestImportListAvailableCmdF() { } numImports := 3 - for i := 0; i < numImports; i++ { + for range numImports { err := importUploadCmdF(c, cmd, []string{importFilePath}) s.Require().Nil(err) } diff --git a/server/cmd/mmctl/commands/import_test.go b/server/cmd/mmctl/commands/import_test.go index eca00791ee4..893392735a5 100644 --- a/server/cmd/mmctl/commands/import_test.go +++ b/server/cmd/mmctl/commands/import_test.go @@ -284,8 +284,8 @@ func (s *MmctlUnitTestSuite) TestImportValidateCmdF() { _, err = wr.Write([]byte(importBase)) s.Require().NoError(err) - _, err = wr.Write([]byte(fmt.Sprintf(` -{"type":"post","post":{"team":"ad-1","channel":"iusto-9","user":"ashley.berry","message":"%s","props":{},"create_at":1603398068740,"reactions":null,"replies":null}}`, msg))) + _, err = wr.Write(fmt.Appendf(nil, ` +{"type":"post","post":{"team":"ad-1","channel":"iusto-9","user":"ashley.berry","message":"%s","props":{},"create_at":1603398068740,"reactions":null,"replies":null}}`, msg)) s.Require().NoError(err) err = zipWr.Close() @@ -324,8 +324,8 @@ func (s *MmctlUnitTestSuite) TestImportValidateCmdF() { _, err = wr.Write([]byte(importBase)) s.Require().NoError(err) - _, err = wr.Write([]byte(fmt.Sprintf(` -{"type":"post","post":{"team":"ad-1","channel":"iusto-9","user":"ashley.berry","message":"%s","props":{},"create_at":1603398068740,"reactions":null,"replies":null}}`, msg))) + _, err = wr.Write(fmt.Appendf(nil, ` +{"type":"post","post":{"team":"ad-1","channel":"iusto-9","user":"ashley.berry","message":"%s","props":{},"create_at":1603398068740,"reactions":null,"replies":null}}`, msg)) s.Require().NoError(err) err = zipWr.Close() @@ -367,8 +367,8 @@ func (s *MmctlUnitTestSuite) TestImportValidateCmdF() { _, err = wr.Write([]byte(importBase)) s.Require().NoError(err) - _, err = wr.Write([]byte(fmt.Sprintf(` -{"type":"post","post":{"team":"ad-1","channel":"iusto-9","user":"ashley.berry","message":"%s","props":{},"create_at":1603398068740,"reactions":null,"replies":null}}`, msg))) + _, err = wr.Write(fmt.Appendf(nil, ` +{"type":"post","post":{"team":"ad-1","channel":"iusto-9","user":"ashley.berry","message":"%s","props":{},"create_at":1603398068740,"reactions":null,"replies":null}}`, msg)) s.Require().NoError(err) err = zipWr.Close() @@ -428,8 +428,8 @@ func (s *MmctlUnitTestSuite) TestImportValidateCmdF() { _, err = wr.Write([]byte(importBase)) s.Require().NoError(err) - _, err = wr.Write([]byte(fmt.Sprintf(` -{"type":"direct_post","direct_post":{"channel_members":["ashley.berry","ashley.berry"],"user":"ashley.berry","message":"%s","props":{},"create_at":1603398112372,"flagged_by":null,"reactions":null,"replies":null,"attachments":null}}`, msg))) + _, err = wr.Write(fmt.Appendf(nil, ` +{"type":"direct_post","direct_post":{"channel_members":["ashley.berry","ashley.berry"],"user":"ashley.berry","message":"%s","props":{},"create_at":1603398112372,"flagged_by":null,"reactions":null,"replies":null,"attachments":null}}`, msg)) s.Require().NoError(err) err = zipWr.Close() diff --git a/server/cmd/mmctl/commands/init.go b/server/cmd/mmctl/commands/init.go index 77c611a3be7..af5e94f0f05 100644 --- a/server/cmd/mmctl/commands/init.go +++ b/server/cmd/mmctl/commands/init.go @@ -11,6 +11,7 @@ import ( "net/http" "os" "runtime" + "slices" "strings" "time" @@ -163,10 +164,8 @@ func isValidChain(chain []*x509.Certificate) bool { func VerifyCertificates(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { // loop over certificate chains - for _, chain := range verifiedChains { - if isValidChain(chain) { - return nil - } + if slices.ContainsFunc(verifiedChains, isValidChain) { + return nil } return fmt.Errorf("insecure algorithm found in the certificate chain. Use --insecure-sha1-intermediate flag to ignore. Aborting") } diff --git a/server/cmd/mmctl/commands/ldap_test.go b/server/cmd/mmctl/commands/ldap_test.go index fe94bf94786..c1eb5035924 100644 --- a/server/cmd/mmctl/commands/ldap_test.go +++ b/server/cmd/mmctl/commands/ldap_test.go @@ -230,14 +230,14 @@ func (s *MmctlUnitTestSuite) TestLdapJobShowCmdF() { s.Run("more elements then the limit match", func() { var mockJobs []*model.Job - for i := 0; i < 100; i++ { + for i := range 100 { mockJobs = append(mockJobs, &model.Job{ Id: fmt.Sprintf("id_%d", i), }) } var expected []string - for i := 0; i < shellCompletionMaxItems; i++ { + for i := range shellCompletionMaxItems { expected = append(expected, fmt.Sprintf("id_%d", i)) } diff --git a/server/cmd/mmctl/commands/roles.go b/server/cmd/mmctl/commands/roles.go index 080dc806438..4d1efc811b6 100644 --- a/server/cmd/mmctl/commands/roles.go +++ b/server/cmd/mmctl/commands/roles.go @@ -107,8 +107,8 @@ func rolesMemberCmdF(c client.Client, _ *cobra.Command, args []string) error { shouldRemoveSysadmin := false var newRoles []string - roles := strings.Fields(user.Roles) - for _, role := range roles { + roles := strings.FieldsSeq(user.Roles) + for role := range roles { switch role { case model.SystemAdminRoleId: shouldRemoveSysadmin = true diff --git a/server/cmd/mmctl/commands/sampledata.go b/server/cmd/mmctl/commands/sampledata.go index 34c1825c54a..a818267ef05 100644 --- a/server/cmd/mmctl/commands/sampledata.go +++ b/server/cmd/mmctl/commands/sampledata.go @@ -268,7 +268,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro rand.Seed(seed) teamsAndChannels := make(map[string][]string, teams) - for i := 0; i < teams; i++ { + for i := range teams { teamLine := createTeam(i) teamsAndChannels[*teamLine.Team.Name] = []string{} if err := encoder.Encode(teamLine); err != nil { @@ -285,7 +285,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro sort.Strings(teamsList) for _, teamName := range teamsList { - for i := 0; i < channelsPerTeam; i++ { + for i := range channelsPerTeam { channelLine := createChannel(i, teamName) teamsAndChannels[teamName] = append(teamsAndChannels[teamName], *channelLine.Channel.Name) if err := encoder.Encode(channelLine); err != nil { @@ -296,7 +296,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro allUsers := make([]string, users+guests+deactivatedUsers) allUsersIndex := 0 - for i := 0; i < users; i++ { + for i := range users { userLine := createUser(i, teamMemberships, channelMemberships, teamsAndChannels, profileImages, "") if err := encoder.Encode(userLine); err != nil { return fmt.Errorf("cannot encode user line: %w", err) @@ -304,7 +304,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro allUsers[allUsersIndex] = *userLine.User.Username allUsersIndex++ } - for i := 0; i < guests; i++ { + for i := range guests { userLine := createUser(i, teamMemberships, channelMemberships, teamsAndChannels, profileImages, guestUser) if err := encoder.Encode(userLine); err != nil { return fmt.Errorf("cannot encode user line: %w", err) @@ -312,7 +312,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro allUsers[allUsersIndex] = *userLine.User.Username allUsersIndex++ } - for i := 0; i < deactivatedUsers; i++ { + for i := range deactivatedUsers { userLine := createUser(i, teamMemberships, channelMemberships, teamsAndChannels, profileImages, deactivatedUser) if err := encoder.Encode(userLine); err != nil { return fmt.Errorf("cannot encode user line: %w", err) @@ -325,7 +325,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro for _, channel := range channels { dates := sortedRandomDates(postsPerChannel) - for i := 0; i < postsPerChannel; i++ { + for i := range postsPerChannel { postLine := createPost(team, channel, allUsers, dates[i]) if err := encoder.Encode(postLine); err != nil { return fmt.Errorf("cannot encode post line: %w", err) @@ -334,7 +334,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro } } - for i := 0; i < directChannels; i++ { + for range directChannels { user1 := allUsers[rand.Intn(len(allUsers))] user2 := allUsers[rand.Intn(len(allUsers))] channelLine := createDirectChannel([]string{user1, user2}) @@ -343,12 +343,12 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro } } - for i := 0; i < directChannels; i++ { + for range directChannels { user1 := allUsers[rand.Intn(len(allUsers))] user2 := allUsers[rand.Intn(len(allUsers))] dates := sortedRandomDates(postsPerDirectChannel) - for j := 0; j < postsPerDirectChannel; j++ { + for j := range postsPerDirectChannel { postLine := createDirectPost([]string{user1, user2}, dates[j]) if err := encoder.Encode(postLine); err != nil { return fmt.Errorf("cannot encode post line: %w", err) @@ -356,7 +356,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro } } - for i := 0; i < groupChannels; i++ { + for range groupChannels { users := []string{} totalUsers := 3 + rand.Intn(3) for len(users) < totalUsers { @@ -371,7 +371,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro } } - for i := 0; i < groupChannels; i++ { + for range groupChannels { users := []string{} totalUsers := 3 + rand.Intn(3) for len(users) < totalUsers { @@ -382,7 +382,7 @@ func sampledataCmdF(c client.Client, command *cobra.Command, args []string) erro } dates := sortedRandomDates(postsPerGroupChannel) - for j := 0; j < postsPerGroupChannel; j++ { + for j := range postsPerGroupChannel { postLine := createDirectPost(users, dates[j]) if err := encoder.Encode(postLine); err != nil { return fmt.Errorf("cannot encode post line: %w", err) diff --git a/server/cmd/mmctl/commands/sampledata_util.go b/server/cmd/mmctl/commands/sampledata_util.go index a5d9bec440b..bbe381c8e56 100644 --- a/server/cmd/mmctl/commands/sampledata_util.go +++ b/server/cmd/mmctl/commands/sampledata_util.go @@ -7,6 +7,7 @@ package commands import ( "fmt" "math/rand" + "slices" "sort" "strings" "time" @@ -26,10 +27,10 @@ func randomPastTime(seconds int) int64 { func sortedRandomDates(size int) []int64 { dates := make([]int64, size) - for i := 0; i < size; i++ { + for i := range size { dates[i] = randomPastTime(50000) } - sort.Slice(dates, func(a, b int) bool { return dates[a] < dates[b] }) + slices.Sort(dates) return dates } @@ -197,7 +198,7 @@ func createUser(idx int, teamMemberships int, channelMemberships int, teamsAndCh possibleTeams = append(possibleTeams, teamName) } sort.Strings(possibleTeams) - for x := 0; x < teamMemberships; x++ { + for range teamMemberships { if len(possibleTeams) == 0 { break } @@ -249,7 +250,7 @@ func createTeamMembership(numOfchannels int, teamChannels []string, teamName *st } channels := []imports.UserChannelImportData{} teamChannelsCopy := append([]string(nil), teamChannels...) - for x := 0; x < numOfchannels; x++ { + for range numOfchannels { if len(teamChannelsCopy) == 0 { break } diff --git a/server/cmd/mmctl/commands/team_test.go b/server/cmd/mmctl/commands/team_test.go index cf429f9b70a..1e28c9ea537 100644 --- a/server/cmd/mmctl/commands/team_test.go +++ b/server/cmd/mmctl/commands/team_test.go @@ -384,7 +384,7 @@ func (s *MmctlUnitTestSuite) TestListTeamsCmdF() { printer.Clean() mockTeamsPage1 := make([]*model.Team, DefaultPageSize) - for i := 0; i < DefaultPageSize; i++ { + for i := range DefaultPageSize { mockTeamsPage1[i] = &model.Team{Name: fmt.Sprintf("Team%d", i)} } mockTeamsPage2 := []*model.Team{{Name: fmt.Sprintf("Team%d", DefaultPageSize)}} @@ -404,7 +404,7 @@ func (s *MmctlUnitTestSuite) TestListTeamsCmdF() { err := listTeamsCmdF(s.client, &cobra.Command{}, []string{}) s.Require().NoError(err) s.Require().Len(printer.GetLines(), DefaultPageSize+1) - for i := 0; i < DefaultPageSize+1; i++ { + for i := range DefaultPageSize + 1 { s.Require().Equal(printer.GetLines()[i].(*model.Team).Name, fmt.Sprintf("Team%d", i)) } s.Require().Len(printer.GetErrorLines(), 0) diff --git a/server/cmd/mmctl/commands/user_e2e_test.go b/server/cmd/mmctl/commands/user_e2e_test.go index b0ff15a9afe..e7f4bf28642 100644 --- a/server/cmd/mmctl/commands/user_e2e_test.go +++ b/server/cmd/mmctl/commands/user_e2e_test.go @@ -215,7 +215,7 @@ func (s *MmctlE2ETestSuite) TestListUserCmd() { s.th.SystemAdminUser.Username, s.th.SystemManagerUser.Username, } - for i := 0; i < 10; i++ { + for range 10 { userData := model.User{ Username: "fakeuser" + model.NewRandomString(10), Password: "Pa$$word11", @@ -228,7 +228,7 @@ func (s *MmctlE2ETestSuite) TestListUserCmd() { inactivePool := []string{} // create inactive users - for i := 0; i < 2; i++ { + for range 2 { userData := model.User{ Username: "fakeuser" + model.NewRandomString(10), Password: "Pa$$word11", @@ -294,7 +294,7 @@ func (s *MmctlE2ETestSuite) TestListUserCmd() { }) // create users with team - for i := 0; i < 10; i++ { + for range 10 { userData := model.User{ Username: "teamuser" + model.NewRandomString(10), Password: "Pa$$word11", @@ -327,7 +327,7 @@ func (s *MmctlE2ETestSuite) TestListUserCmd() { // create inactive users with team inactiveUserPool := []string{} - for i := 0; i < 10; i++ { + for range 10 { userData := model.User{ Username: "inactiveteamuser" + model.NewRandomString(10), Password: "Pa$$word11", @@ -1037,7 +1037,7 @@ func (s *MmctlE2ETestSuite) TestDeleteAllUserCmd() { printer.Clean() // populate with some user - for i := 0; i < 10; i++ { + for range 10 { userData := model.User{ Username: "fakeuser" + model.NewRandomString(10), Password: "Pa$$word11", diff --git a/server/cmd/mmctl/commands/user_test.go b/server/cmd/mmctl/commands/user_test.go index 8b177cfd801..9be18106e18 100644 --- a/server/cmd/mmctl/commands/user_test.go +++ b/server/cmd/mmctl/commands/user_test.go @@ -1171,7 +1171,7 @@ func (s *MmctlUnitTestSuite) TestUserInviteCmd() { err := userInviteCmdF(s.client, &cobra.Command{}, append([]string{argUser}, argTeam...)) s.Require().Nil(err) s.Require().Len(printer.GetLines(), len(argTeam)) - for i := 0; i < len(argTeam); i++ { + for i := range argTeam { s.Require().Equal("Invites may or may not have been sent.", printer.GetLines()[i]) } s.Require().Len(printer.GetErrorLines(), 0) @@ -1331,7 +1331,7 @@ func (s *MmctlUnitTestSuite) TestUserInviteCmd() { err := userInviteCmdF(s.client, &cobra.Command{}, append([]string{argUser}, argTeam...)) s.Require().Error(err) s.Require().Len(printer.GetLines(), 4) - for i := 0; i < 4; i++ { + for i := range 4 { s.Require().Equal("Invites may or may not have been sent.", printer.GetLines()[i]) } s.Require().Len(printer.GetErrorLines(), 2) @@ -2319,7 +2319,7 @@ func (s *MmctlUnitTestSuite) TestUserDeactivateCmd() { argEmails := []string{mockUser1.Email, mockUser2.Email, mockUser3.Email} argUsers := []model.User{mockUser1, mockUser2, mockUser3} - for i := 0; i < len(argEmails); i++ { + for i := range argEmails { s.client. EXPECT(). GetUserByEmail(context.TODO(), argEmails[i], ""). @@ -2327,7 +2327,7 @@ func (s *MmctlUnitTestSuite) TestUserDeactivateCmd() { Times(1) } - for i := 0; i < len(argEmails); i++ { + for i := range argEmails { s.client. EXPECT(). UpdateUserActive(context.TODO(), argUsers[i].Id, false). diff --git a/server/cmd/mmctl/commands/webhook_test.go b/server/cmd/mmctl/commands/webhook_test.go index 27172bb7841..c663741d2bb 100644 --- a/server/cmd/mmctl/commands/webhook_test.go +++ b/server/cmd/mmctl/commands/webhook_test.go @@ -35,22 +35,22 @@ func (s *MmctlUnitTestSuite) TestListWebhookCmd() { } var mockIncomingWebhooksPage1 []*model.IncomingWebhook - for i := 0; i < 200; i++ { + for range 200 { mockIncomingWebhooksPage1 = append(mockIncomingWebhooksPage1, &mockIncomingWebhook) } var mockIncomingWebhooksPage2 []*model.IncomingWebhook - for i := 0; i < 50; i++ { + for range 50 { mockIncomingWebhooksPage2 = append(mockIncomingWebhooksPage2, &mockIncomingWebhook) } var mockOutgoingWebhooksPage1 []*model.OutgoingWebhook - for i := 0; i < 200; i++ { + for range 200 { mockOutgoingWebhooksPage1 = append(mockOutgoingWebhooksPage1, &mockOutgoingWebhook) } var mockOutgoingWebhooksPage2 []*model.OutgoingWebhook - for i := 0; i < 50; i++ { + for range 50 { mockOutgoingWebhooksPage2 = append(mockOutgoingWebhooksPage2, &mockOutgoingWebhook) } @@ -112,7 +112,7 @@ func (s *MmctlUnitTestSuite) TestListWebhookCmd() { err := listWebhookCmdF(s.client, &cobra.Command{}, []string{}) s.Require().Nil(err) if s.Len(printer.GetLines(), 500) { - for i := 0; i < 250; i++ { + for i := range 250 { s.Require().Equal(&mockIncomingWebhook, printer.GetLines()[i]) } for i := 250; i < 500; i++ { @@ -178,7 +178,7 @@ func (s *MmctlUnitTestSuite) TestListWebhookCmd() { s.Require().Nil(err) s.Len(printer.GetErrorLines(), 0) if s.Len(printer.GetLines(), 500) { - for i := 0; i < 250; i++ { + for i := range 250 { s.Require().Equal(&mockIncomingWebhook, printer.GetLines()[i]) } for i := 250; i < 500; i++ { diff --git a/server/config/database_test.go b/server/config/database_test.go index 46563e51454..3ce60861600 100644 --- a/server/config/database_test.go +++ b/server/config/database_test.go @@ -1131,7 +1131,7 @@ func TestCleanUp(t *testing.T) { ds.config.JobSettings.CleanupConfigThresholdDays = model.NewPointer(30) // we set 30 days as threshold now := time.Now() - for i := 0; i < 5; i++ { + for i := range 5 { // 20 days, we expect to remove at least 3 configuration values from the store // first 2 (0 and 1) will be within a month constraint, others will be older than // a month hence we expect 3 configurations to be removed from the database. diff --git a/server/config/diff_test.go b/server/config/diff_test.go index ba585f949dd..f084e10c1f1 100644 --- a/server/config/diff_test.go +++ b/server/config/diff_test.go @@ -21,8 +21,7 @@ func BenchmarkDiff(b *testing.B) { b.Run("equal empty", func(b *testing.B) { baseCfg := &model.Config{} actualCfg := &model.Config{} - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { _, _ = Diff(baseCfg, actualCfg) } }) @@ -30,8 +29,7 @@ func BenchmarkDiff(b *testing.B) { b.Run("equal with defaults", func(b *testing.B) { baseCfg := defaultConfigGen() actualCfg := defaultConfigGen() - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { _, _ = Diff(baseCfg, actualCfg) } }) @@ -39,8 +37,7 @@ func BenchmarkDiff(b *testing.B) { b.Run("actual empty", func(b *testing.B) { baseCfg := defaultConfigGen() actualCfg := &model.Config{} - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { _, _ = Diff(baseCfg, actualCfg) } }) @@ -48,8 +45,7 @@ func BenchmarkDiff(b *testing.B) { b.Run("base empty", func(b *testing.B) { baseCfg := &model.Config{} actualCfg := defaultConfigGen() - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { _, _ = Diff(baseCfg, actualCfg) } }) @@ -68,8 +64,7 @@ func BenchmarkDiff(b *testing.B) { "ds1", "ds2", } - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { _, _ = Diff(baseCfg, actualCfg) } }) diff --git a/server/config/utils.go b/server/config/utils.go index 6e14b7d7227..cb6b645abc6 100644 --- a/server/config/utils.go +++ b/server/config/utils.go @@ -134,7 +134,7 @@ func fixInvalidLocales(cfg *model.Config) bool { if *cfg.LocalizationSettings.AvailableLocales != "" { isDefaultClientLocaleInAvailableLocales := false - for _, word := range strings.Split(*cfg.LocalizationSettings.AvailableLocales, ",") { + for word := range strings.SplitSeq(*cfg.LocalizationSettings.AvailableLocales, ",") { if _, ok := locales[word]; !ok { *cfg.LocalizationSettings.AvailableLocales = "" isDefaultClientLocaleInAvailableLocales = true diff --git a/server/enterprise/elasticsearch/elasticsearch/aggregation_job_test.go b/server/enterprise/elasticsearch/elasticsearch/aggregation_job_test.go index 3722ff6fb4a..2bb9994e165 100644 --- a/server/enterprise/elasticsearch/elasticsearch/aggregation_job_test.go +++ b/server/enterprise/elasticsearch/elasticsearch/aggregation_job_test.go @@ -88,7 +88,7 @@ func TestElasticsearchAggregation(t *testing.T) { ChannelId: "channel", Message: "hi", } - for i := 0; i < indexDeletionBatchSize+1; i++ { + for i := range indexDeletionBatchSize + 1 { indexPost(t, th, esImpl.(*ElasticsearchInterfaceImpl), post, time.Now().Add(-time.Duration(4+i)*24*time.Hour)) diff --git a/server/enterprise/elasticsearch/elasticsearch/elasticsearch.go b/server/enterprise/elasticsearch/elasticsearch/elasticsearch.go index 6370ad7c927..e4443808d70 100644 --- a/server/enterprise/elasticsearch/elasticsearch/elasticsearch.go +++ b/server/enterprise/elasticsearch/elasticsearch/elasticsearch.go @@ -7,6 +7,7 @@ import ( "context" "encoding/json" "net/http" + "slices" "strings" "sync" "sync/atomic" @@ -283,7 +284,7 @@ func (es *ElasticsearchInterfaceImpl) SearchPosts(channels model.ChannelList, se var filters, notFilters []types.Query for i, params := range searchParams { newTerms := []string{} - for _, term := range strings.Split(params.Terms, " ") { + for term := range strings.SplitSeq(params.Terms, " ") { if searchengine.EmailRegex.MatchString(term) { term = `"` + term + `"` } @@ -439,7 +440,7 @@ func (es *ElasticsearchInterfaceImpl) SearchPosts(channels model.ChannelList, se termQueries = append(termQueries, query) hashtagTerms := []string{} - for _, term := range strings.Split(params.Terms, " ") { + for term := range strings.SplitSeq(params.Terms, " ") { hashtagTerms = append(hashtagTerms, "#"+term) } @@ -1282,7 +1283,7 @@ func (es *ElasticsearchInterfaceImpl) PurgeIndexes(rctx request.CTX) *model.AppE // we are checking if provided indexes exist. If an index doesn't exist, // elasticsearch returns an error while trying to purge it even we intend to // ignore it. - for _, ignorePurgeIndex := range strings.Split(ignorePurgeIndexes, ",") { + for ignorePurgeIndex := range strings.SplitSeq(ignorePurgeIndexes, ",") { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(*es.Platform.Config().ElasticsearchSettings.RequestTimeoutSeconds)*time.Second) defer cancel() @@ -1327,13 +1328,7 @@ func (es *ElasticsearchInterfaceImpl) PurgeIndexList(rctx request.CTX, indexes [ indexPrefix := *es.Platform.Config().ElasticsearchSettings.IndexPrefix indexToDeleteMap := map[string]bool{} for _, index := range indexes { - isKnownIndex := false - for _, allowedIndex := range purgeIndexListAllowedIndexes { - if index == allowedIndex { - isKnownIndex = true - break - } - } + isKnownIndex := slices.Contains(purgeIndexListAllowedIndexes, index) if !isKnownIndex { return model.NewAppError("Elasticsearch.PurgeIndexList", "ent.elasticsearch.purge_indexes.unknown_index", map[string]any{"unknown_index": index}, "", http.StatusBadRequest) @@ -1344,7 +1339,7 @@ func (es *ElasticsearchInterfaceImpl) PurgeIndexList(rctx request.CTX, indexes [ if ign := *es.Platform.Config().ElasticsearchSettings.IgnoredPurgeIndexes; ign != "" { // make sure we're not purging any index configured to be ignored - for _, ix := range strings.Split(ign, ",") { + for ix := range strings.SplitSeq(ign, ",") { delete(indexToDeleteMap, ix) } } @@ -1472,7 +1467,7 @@ func (es *ElasticsearchInterfaceImpl) SearchFiles(channels model.ChannelList, se var filters, notFilters []types.Query for i, params := range searchParams { newTerms := []string{} - for _, term := range strings.Split(params.Terms, " ") { + for term := range strings.SplitSeq(params.Terms, " ") { if searchengine.EmailRegex.MatchString(term) { term = `"` + term + `"` } diff --git a/server/enterprise/elasticsearch/opensearch/aggregation_job_test.go b/server/enterprise/elasticsearch/opensearch/aggregation_job_test.go index ff6054f23b6..6380c5a7875 100644 --- a/server/enterprise/elasticsearch/opensearch/aggregation_job_test.go +++ b/server/enterprise/elasticsearch/opensearch/aggregation_job_test.go @@ -110,7 +110,7 @@ func TestElasticsearchAggregation(t *testing.T) { ChannelId: "channel", Message: "hi", } - for i := 0; i < indexDeletionBatchSize+1; i++ { + for i := range indexDeletionBatchSize + 1 { indexPost(t, th, esImpl.(*OpensearchInterfaceImpl), post, time.Now().Add(-time.Duration(4+i)*24*time.Hour)) diff --git a/server/enterprise/elasticsearch/opensearch/opensearch.go b/server/enterprise/elasticsearch/opensearch/opensearch.go index 99c1b56d661..69bb30b8758 100644 --- a/server/enterprise/elasticsearch/opensearch/opensearch.go +++ b/server/enterprise/elasticsearch/opensearch/opensearch.go @@ -8,6 +8,7 @@ import ( "context" "encoding/json" "net/http" + "slices" "strings" "sync" "sync/atomic" @@ -313,7 +314,7 @@ func (os *OpensearchInterfaceImpl) SearchPosts(channels model.ChannelList, searc var filters, notFilters []types.Query for i, params := range searchParams { newTerms := []string{} - for _, term := range strings.Split(params.Terms, " ") { + for term := range strings.SplitSeq(params.Terms, " ") { if searchengine.EmailRegex.MatchString(term) { term = `"` + term + `"` } @@ -469,7 +470,7 @@ func (os *OpensearchInterfaceImpl) SearchPosts(channels model.ChannelList, searc termQueries = append(termQueries, query) hashtagTerms := []string{} - for _, term := range strings.Split(params.Terms, " ") { + for term := range strings.SplitSeq(params.Terms, " ") { hashtagTerms = append(hashtagTerms, "#"+term) } @@ -1390,7 +1391,7 @@ func (os *OpensearchInterfaceImpl) PurgeIndexes(rctx request.CTX) *model.AppErro // we are checking if provided indexes exist. If an index doesn't exist, // opensearch returns an error while trying to purge it even we intend to // ignore it. - for _, ignorePurgeIndex := range strings.Split(ignorePurgeIndexes, ",") { + for ignorePurgeIndex := range strings.SplitSeq(ignorePurgeIndexes, ",") { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(*os.Platform.Config().ElasticsearchSettings.RequestTimeoutSeconds)*time.Second) defer cancel() @@ -1439,13 +1440,7 @@ func (os *OpensearchInterfaceImpl) PurgeIndexList(rctx request.CTX, indexes []st indexPrefix := *os.Platform.Config().ElasticsearchSettings.IndexPrefix indexToDeleteMap := map[string]bool{} for _, index := range indexes { - isKnownIndex := false - for _, allowedIndex := range purgeIndexListAllowedIndexes { - if index == allowedIndex { - isKnownIndex = true - break - } - } + isKnownIndex := slices.Contains(purgeIndexListAllowedIndexes, index) if !isKnownIndex { return model.NewAppError("Opensearch.PurgeIndexList", "ent.elasticsearch.purge_indexes.unknown_index", map[string]any{"unknown_index": index}, "", http.StatusBadRequest) @@ -1456,7 +1451,7 @@ func (os *OpensearchInterfaceImpl) PurgeIndexList(rctx request.CTX, indexes []st if ign := *os.Platform.Config().ElasticsearchSettings.IgnoredPurgeIndexes; ign != "" { // make sure we're not purging any index configured to be ignored - for _, ix := range strings.Split(ign, ",") { + for ix := range strings.SplitSeq(ign, ",") { delete(indexToDeleteMap, ix) } } @@ -1596,7 +1591,7 @@ func (os *OpensearchInterfaceImpl) SearchFiles(channels model.ChannelList, searc var filters, notFilters []types.Query for i, params := range searchParams { newTerms := []string{} - for _, term := range strings.Split(params.Terms, " ") { + for term := range strings.SplitSeq(params.Terms, " ") { if searchengine.EmailRegex.MatchString(term) { term = `"` + term + `"` } diff --git a/server/enterprise/message_export/global_relay_export/deliver_test.go b/server/enterprise/message_export/global_relay_export/deliver_test.go index 28ca0816e26..bf1d369fb8d 100644 --- a/server/enterprise/message_export/global_relay_export/deliver_test.go +++ b/server/enterprise/message_export/global_relay_export/deliver_test.go @@ -115,7 +115,7 @@ func TestDeliver(t *testing.T) { emptyZipFile, err := os.CreateTemp("", "export") require.NoError(t, err) zipFile := zip.NewWriter(emptyZipFile) - for x := 0; x < 50; x++ { + for x := range 50 { var file io.Writer file, err = zipFile.Create(fmt.Sprintf("test-%d", x)) require.NoError(t, err) diff --git a/server/enterprise/message_export/message_export_test.go b/server/enterprise/message_export/message_export_test.go index f5f2eeb036a..8ef2103e178 100644 --- a/server/enterprise/message_export/message_export_test.go +++ b/server/enterprise/message_export/message_export_test.go @@ -12,6 +12,7 @@ import ( "io" "os" "path" + "slices" "strconv" "strings" "testing" @@ -364,7 +365,7 @@ func testRunExportJobE2E(t *testing.T, exportBackend filestore.FileBackend, expo *cfg.MessageExportSettings.BatchSize = 2 }) - for i := 0; i < 3; i++ { + for range 3 { _, err2 := th.App.Srv().Store().Post().Save(th.Context, &model.Post{ ChannelId: th.BasicChannel.Id, UserId: st.NewTestID(), @@ -568,7 +569,7 @@ func testRunExportJobE2E(t *testing.T, exportBackend filestore.FileBackend, expo zipReader, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes))) require.NoError(t, err) - for i := 0; i < 3; i++ { + for i := range 3 { num := b*3 + i attachmentInZip, err := zipReader.Open(attachments[num].Path) require.NoError(t, err) @@ -1745,13 +1746,7 @@ func testRunExportJobE2E(t *testing.T, exportBackend filestore.FileBackend, expo export := openZipAndReadFileNum(t, exportBackend, batches[0], 0) - matched := false - for _, perm := range expectedExports { - if export == perm { - matched = true - break - } - } + matched := slices.Contains(expectedExports, export) assert.True(t, matched, "batch 1 didn't match one of the expected permutations") expectedExports = []string{ @@ -1776,13 +1771,7 @@ func testRunExportJobE2E(t *testing.T, exportBackend filestore.FileBackend, expo export = openZipAndReadFileNum(t, exportBackend, batches[1], 0) - matched = false - for _, perm := range expectedExports { - if export == perm { - matched = true - break - } - } + matched = slices.Contains(expectedExports, export) assert.True(t, matched, "batch 2 didn't match one of the expected permutations") }) @@ -2157,7 +2146,7 @@ func testRunExportJobE2E(t *testing.T, exportBackend filestore.FileBackend, expo } numMessages := 0 - for _, l := range strings.Split(msg, "\n") { + for l := range strings.SplitSeq(msg, "\n") { if strings.Contains(l, "