github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/app/channel_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"fmt"
     8  	"net/http"
     9  	"sort"
    10  	"strings"
    11  	"sync"
    12  	"testing"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	"github.com/mattermost/mattermost-server/v5/model"
    18  	"github.com/mattermost/mattermost-server/v5/store/storetest/mocks"
    19  )
    20  
    21  func TestPermanentDeleteChannel(t *testing.T) {
    22  	th := Setup(t).InitBasic()
    23  	defer th.TearDown()
    24  
    25  	th.App.UpdateConfig(func(cfg *model.Config) {
    26  		*cfg.ServiceSettings.EnableIncomingWebhooks = true
    27  		*cfg.ServiceSettings.EnableOutgoingWebhooks = true
    28  	})
    29  
    30  	channel, err := th.App.CreateChannel(&model.Channel{DisplayName: "deletion-test", Name: "deletion-test", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}, false)
    31  	require.NotNil(t, channel, "Channel shouldn't be nil")
    32  	require.Nil(t, err)
    33  	defer func() {
    34  		th.App.PermanentDeleteChannel(channel)
    35  	}()
    36  
    37  	incoming, err := th.App.CreateIncomingWebhookForChannel(th.BasicUser.Id, channel, &model.IncomingWebhook{ChannelId: channel.Id})
    38  	require.NotNil(t, incoming, "incoming webhook should not be nil")
    39  	require.Nil(t, err, "Unable to create Incoming Webhook for Channel")
    40  	defer th.App.DeleteIncomingWebhook(incoming.Id)
    41  
    42  	incoming, err = th.App.GetIncomingWebhook(incoming.Id)
    43  	require.NotNil(t, incoming, "incoming webhook should not be nil")
    44  	require.Nil(t, err, "Unable to get new incoming webhook")
    45  
    46  	outgoing, err := th.App.CreateOutgoingWebhook(&model.OutgoingWebhook{
    47  		ChannelId:    channel.Id,
    48  		TeamId:       channel.TeamId,
    49  		CreatorId:    th.BasicUser.Id,
    50  		CallbackURLs: []string{"http://foo"},
    51  	})
    52  	require.Nil(t, err)
    53  	defer th.App.DeleteOutgoingWebhook(outgoing.Id)
    54  
    55  	outgoing, err = th.App.GetOutgoingWebhook(outgoing.Id)
    56  	require.NotNil(t, outgoing, "Outgoing webhook should not be nil")
    57  	require.Nil(t, err, "Unable to get new outgoing webhook")
    58  
    59  	err = th.App.PermanentDeleteChannel(channel)
    60  	require.Nil(t, err)
    61  
    62  	incoming, err = th.App.GetIncomingWebhook(incoming.Id)
    63  	require.Nil(t, incoming, "Incoming webhook should be nil")
    64  	require.NotNil(t, err, "Incoming webhook wasn't deleted")
    65  
    66  	outgoing, err = th.App.GetOutgoingWebhook(outgoing.Id)
    67  	require.Nil(t, outgoing, "Outgoing webhook should be nil")
    68  	require.NotNil(t, err, "Outgoing webhook wasn't deleted")
    69  }
    70  
    71  func TestRemoveAllDeactivatedMembersFromChannel(t *testing.T) {
    72  	th := Setup(t).InitBasic()
    73  	defer th.TearDown()
    74  	var err *model.AppError
    75  
    76  	team := th.CreateTeam()
    77  	channel := th.CreateChannel(team)
    78  	defer func() {
    79  		th.App.PermanentDeleteChannel(channel)
    80  		th.App.PermanentDeleteTeam(team)
    81  	}()
    82  
    83  	_, err = th.App.AddUserToTeam(team.Id, th.BasicUser.Id, "")
    84  	require.Nil(t, err)
    85  
    86  	deacivatedUser := th.CreateUser()
    87  	_, err = th.App.AddUserToTeam(team.Id, deacivatedUser.Id, "")
    88  	require.Nil(t, err)
    89  	_, err = th.App.AddUserToChannel(deacivatedUser, channel)
    90  	require.Nil(t, err)
    91  	channelMembers, err := th.App.GetChannelMembersPage(channel.Id, 0, 10000000)
    92  	require.Nil(t, err)
    93  	require.Len(t, *channelMembers, 2)
    94  	_, err = th.App.UpdateActive(deacivatedUser, false)
    95  	require.Nil(t, err)
    96  
    97  	err = th.App.RemoveAllDeactivatedMembersFromChannel(channel)
    98  	require.Nil(t, err)
    99  
   100  	channelMembers, err = th.App.GetChannelMembersPage(channel.Id, 0, 10000000)
   101  	require.Nil(t, err)
   102  	require.Len(t, *channelMembers, 1)
   103  }
   104  
   105  func TestMoveChannel(t *testing.T) {
   106  	t.Run("should move channels between teams", func(t *testing.T) {
   107  		th := Setup(t).InitBasic()
   108  		defer th.TearDown()
   109  		var err *model.AppError
   110  
   111  		sourceTeam := th.CreateTeam()
   112  		targetTeam := th.CreateTeam()
   113  		channel1 := th.CreateChannel(sourceTeam)
   114  		defer func() {
   115  			th.App.PermanentDeleteChannel(channel1)
   116  			th.App.PermanentDeleteTeam(sourceTeam)
   117  			th.App.PermanentDeleteTeam(targetTeam)
   118  		}()
   119  
   120  		_, err = th.App.AddUserToTeam(sourceTeam.Id, th.BasicUser.Id, "")
   121  		require.Nil(t, err)
   122  
   123  		_, err = th.App.AddUserToTeam(sourceTeam.Id, th.BasicUser2.Id, "")
   124  		require.Nil(t, err)
   125  
   126  		_, err = th.App.AddUserToTeam(targetTeam.Id, th.BasicUser.Id, "")
   127  		require.Nil(t, err)
   128  
   129  		_, err = th.App.AddUserToChannel(th.BasicUser, channel1)
   130  		require.Nil(t, err)
   131  
   132  		_, err = th.App.AddUserToChannel(th.BasicUser2, channel1)
   133  		require.Nil(t, err)
   134  
   135  		err = th.App.MoveChannel(targetTeam, channel1, th.BasicUser)
   136  		require.Error(t, err, "Should have failed due to mismatched members.")
   137  
   138  		_, err = th.App.AddUserToTeam(targetTeam.Id, th.BasicUser2.Id, "")
   139  		require.Nil(t, err)
   140  
   141  		err = th.App.MoveChannel(targetTeam, channel1, th.BasicUser)
   142  		require.Nil(t, err)
   143  
   144  		// Test moving a channel with a deactivated user who isn't in the destination team.
   145  		// It should fail, unless removeDeactivatedMembers is true.
   146  		deacivatedUser := th.CreateUser()
   147  		channel2 := th.CreateChannel(sourceTeam)
   148  		defer th.App.PermanentDeleteChannel(channel2)
   149  
   150  		_, err = th.App.AddUserToTeam(sourceTeam.Id, deacivatedUser.Id, "")
   151  		require.Nil(t, err)
   152  		_, err = th.App.AddUserToChannel(th.BasicUser, channel2)
   153  		require.Nil(t, err)
   154  
   155  		_, err = th.App.AddUserToChannel(deacivatedUser, channel2)
   156  		require.Nil(t, err)
   157  
   158  		_, err = th.App.UpdateActive(deacivatedUser, false)
   159  		require.Nil(t, err)
   160  
   161  		err = th.App.MoveChannel(targetTeam, channel2, th.BasicUser)
   162  		require.Error(t, err, "Should have failed due to mismatched deacivated member.")
   163  
   164  		// Test moving a channel with no members.
   165  		channel3 := &model.Channel{
   166  			DisplayName: "dn_" + model.NewId(),
   167  			Name:        "name_" + model.NewId(),
   168  			Type:        model.CHANNEL_OPEN,
   169  			TeamId:      sourceTeam.Id,
   170  			CreatorId:   th.BasicUser.Id,
   171  		}
   172  
   173  		channel3, err = th.App.CreateChannel(channel3, false)
   174  		require.Nil(t, err)
   175  		defer th.App.PermanentDeleteChannel(channel3)
   176  
   177  		err = th.App.MoveChannel(targetTeam, channel3, th.BasicUser)
   178  		assert.Nil(t, err)
   179  	})
   180  
   181  	t.Run("should remove sidebar entries when moving channels from one team to another", func(t *testing.T) {
   182  		th := Setup(t).InitBasic()
   183  		defer th.TearDown()
   184  
   185  		sourceTeam := th.CreateTeam()
   186  		targetTeam := th.CreateTeam()
   187  		channel := th.CreateChannel(sourceTeam)
   188  
   189  		th.LinkUserToTeam(th.BasicUser, sourceTeam)
   190  		th.LinkUserToTeam(th.BasicUser, targetTeam)
   191  		th.AddUserToChannel(th.BasicUser, channel)
   192  
   193  		// Put the channel in a custom category so that it explicitly exists in SidebarChannels
   194  		category, err := th.App.CreateSidebarCategory(th.BasicUser.Id, sourceTeam.Id, &model.SidebarCategoryWithChannels{
   195  			SidebarCategory: model.SidebarCategory{
   196  				DisplayName: "new category",
   197  			},
   198  			Channels: []string{channel.Id},
   199  		})
   200  		require.Nil(t, err)
   201  		require.Equal(t, []string{channel.Id}, category.Channels)
   202  
   203  		err = th.App.MoveChannel(targetTeam, channel, th.BasicUser)
   204  		require.Nil(t, err)
   205  
   206  		moved, err := th.App.GetChannel(channel.Id)
   207  		require.Nil(t, err)
   208  		require.Equal(t, targetTeam.Id, moved.TeamId)
   209  
   210  		// The channel should no longer be on the old team
   211  		updatedCategory, err := th.App.GetSidebarCategory(category.Id)
   212  		require.Nil(t, err)
   213  		assert.Equal(t, []string{}, updatedCategory.Channels)
   214  
   215  		// And it should be on the new team instead
   216  		categories, err := th.App.GetSidebarCategories(th.BasicUser.Id, targetTeam.Id)
   217  		require.Nil(t, err)
   218  		require.Equal(t, model.SidebarCategoryChannels, categories.Categories[1].Type)
   219  		assert.Contains(t, categories.Categories[1].Channels, channel.Id)
   220  	})
   221  }
   222  
   223  func TestRemoveUsersFromChannelNotMemberOfTeam(t *testing.T) {
   224  	th := Setup(t).InitBasic()
   225  	defer th.TearDown()
   226  
   227  	team := th.CreateTeam()
   228  	team2 := th.CreateTeam()
   229  	channel1 := th.CreateChannel(team)
   230  	defer func() {
   231  		th.App.PermanentDeleteChannel(channel1)
   232  		th.App.PermanentDeleteTeam(team)
   233  		th.App.PermanentDeleteTeam(team2)
   234  	}()
   235  
   236  	_, err := th.App.AddUserToTeam(team.Id, th.BasicUser.Id, "")
   237  	require.Nil(t, err)
   238  	_, err = th.App.AddUserToTeam(team2.Id, th.BasicUser.Id, "")
   239  	require.Nil(t, err)
   240  	_, err = th.App.AddUserToTeam(team.Id, th.BasicUser2.Id, "")
   241  	require.Nil(t, err)
   242  
   243  	_, err = th.App.AddUserToChannel(th.BasicUser, channel1)
   244  	require.Nil(t, err)
   245  	_, err = th.App.AddUserToChannel(th.BasicUser2, channel1)
   246  	require.Nil(t, err)
   247  
   248  	err = th.App.RemoveUsersFromChannelNotMemberOfTeam(th.SystemAdminUser, channel1, team2)
   249  	require.Nil(t, err)
   250  
   251  	channelMembers, err := th.App.GetChannelMembersPage(channel1.Id, 0, 10000000)
   252  	require.Nil(t, err)
   253  	require.Len(t, *channelMembers, 1)
   254  	members := make([]model.ChannelMember, len(*channelMembers))
   255  	for i, m := range *channelMembers {
   256  		members[i] = m
   257  	}
   258  	require.Equal(t, members[0].UserId, th.BasicUser.Id)
   259  }
   260  
   261  func TestJoinDefaultChannelsCreatesChannelMemberHistoryRecordTownSquare(t *testing.T) {
   262  	th := Setup(t).InitBasic()
   263  	defer th.TearDown()
   264  
   265  	// figure out the initial number of users in town square
   266  	channel, err := th.App.Srv().Store.Channel().GetByName(th.BasicTeam.Id, "town-square", true)
   267  	require.Nil(t, err)
   268  	townSquareChannelId := channel.Id
   269  	users, nErr := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)
   270  	require.Nil(t, nErr)
   271  	initialNumTownSquareUsers := len(users)
   272  
   273  	// create a new user that joins the default channels
   274  	user := th.CreateUser()
   275  	th.App.JoinDefaultChannels(th.BasicTeam.Id, user, false, "")
   276  
   277  	// there should be a ChannelMemberHistory record for the user
   278  	histories, nErr := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)
   279  	require.Nil(t, nErr)
   280  	assert.Len(t, histories, initialNumTownSquareUsers+1)
   281  
   282  	found := false
   283  	for _, history := range histories {
   284  		if user.Id == history.UserId && townSquareChannelId == history.ChannelId {
   285  			found = true
   286  			break
   287  		}
   288  	}
   289  	assert.True(t, found)
   290  }
   291  
   292  func TestJoinDefaultChannelsCreatesChannelMemberHistoryRecordOffTopic(t *testing.T) {
   293  	th := Setup(t).InitBasic()
   294  	defer th.TearDown()
   295  
   296  	// figure out the initial number of users in off-topic
   297  	channel, err := th.App.Srv().Store.Channel().GetByName(th.BasicTeam.Id, "off-topic", true)
   298  	require.Nil(t, err)
   299  	offTopicChannelId := channel.Id
   300  	users, nErr := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)
   301  	require.Nil(t, nErr)
   302  	initialNumTownSquareUsers := len(users)
   303  
   304  	// create a new user that joins the default channels
   305  	user := th.CreateUser()
   306  	th.App.JoinDefaultChannels(th.BasicTeam.Id, user, false, "")
   307  
   308  	// there should be a ChannelMemberHistory record for the user
   309  	histories, nErr := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)
   310  	require.Nil(t, nErr)
   311  	assert.Len(t, histories, initialNumTownSquareUsers+1)
   312  
   313  	found := false
   314  	for _, history := range histories {
   315  		if user.Id == history.UserId && offTopicChannelId == history.ChannelId {
   316  			found = true
   317  			break
   318  		}
   319  	}
   320  	assert.True(t, found)
   321  }
   322  
   323  func TestJoinDefaultChannelsExperimentalDefaultChannels(t *testing.T) {
   324  	th := Setup(t).InitBasic()
   325  	defer th.TearDown()
   326  
   327  	basicChannel2 := th.CreateChannel(th.BasicTeam)
   328  	defer th.App.PermanentDeleteChannel(basicChannel2)
   329  	defaultChannelList := []string{th.BasicChannel.Name, basicChannel2.Name, basicChannel2.Name}
   330  	th.App.Config().TeamSettings.ExperimentalDefaultChannels = defaultChannelList
   331  
   332  	user := th.CreateUser()
   333  	th.App.JoinDefaultChannels(th.BasicTeam.Id, user, false, "")
   334  
   335  	for _, channelName := range defaultChannelList {
   336  		channel, err := th.App.GetChannelByName(channelName, th.BasicTeam.Id, false)
   337  		require.Nil(t, err, "Expected nil, didn't receive nil")
   338  
   339  		member, err := th.App.GetChannelMember(channel.Id, user.Id)
   340  
   341  		require.NotNil(t, member, "Expected member object, got nil")
   342  		require.Nil(t, err, "Expected nil object, didn't receive nil")
   343  	}
   344  }
   345  
   346  func TestCreateChannelPublicCreatesChannelMemberHistoryRecord(t *testing.T) {
   347  	th := Setup(t).InitBasic()
   348  	defer th.TearDown()
   349  
   350  	// creates a public channel and adds basic user to it
   351  	publicChannel := th.createChannel(th.BasicTeam, model.CHANNEL_OPEN)
   352  
   353  	// there should be a ChannelMemberHistory record for the user
   354  	histories, err := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)
   355  	require.Nil(t, err)
   356  	assert.Len(t, histories, 1)
   357  	assert.Equal(t, th.BasicUser.Id, histories[0].UserId)
   358  	assert.Equal(t, publicChannel.Id, histories[0].ChannelId)
   359  }
   360  
   361  func TestCreateChannelPrivateCreatesChannelMemberHistoryRecord(t *testing.T) {
   362  	th := Setup(t).InitBasic()
   363  	defer th.TearDown()
   364  
   365  	// creates a private channel and adds basic user to it
   366  	privateChannel := th.createChannel(th.BasicTeam, model.CHANNEL_PRIVATE)
   367  
   368  	// there should be a ChannelMemberHistory record for the user
   369  	histories, err := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, privateChannel.Id)
   370  	require.Nil(t, err)
   371  	assert.Len(t, histories, 1)
   372  	assert.Equal(t, th.BasicUser.Id, histories[0].UserId)
   373  	assert.Equal(t, privateChannel.Id, histories[0].ChannelId)
   374  }
   375  func TestCreateChannelDisplayNameTrimsWhitespace(t *testing.T) {
   376  	th := Setup(t).InitBasic()
   377  	defer th.TearDown()
   378  
   379  	channel, err := th.App.CreateChannel(&model.Channel{DisplayName: "  Public 1  ", Name: "public1", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}, false)
   380  	defer th.App.PermanentDeleteChannel(channel)
   381  	require.Nil(t, err)
   382  	require.Equal(t, channel.DisplayName, "Public 1")
   383  }
   384  
   385  func TestUpdateChannelPrivacy(t *testing.T) {
   386  	th := Setup(t).InitBasic()
   387  	defer th.TearDown()
   388  
   389  	privateChannel := th.createChannel(th.BasicTeam, model.CHANNEL_PRIVATE)
   390  	privateChannel.Type = model.CHANNEL_OPEN
   391  
   392  	publicChannel, err := th.App.UpdateChannelPrivacy(privateChannel, th.BasicUser)
   393  	require.Nil(t, err, "Failed to update channel privacy.")
   394  	assert.Equal(t, publicChannel.Id, privateChannel.Id)
   395  	assert.Equal(t, publicChannel.Type, model.CHANNEL_OPEN)
   396  }
   397  
   398  func TestCreateGroupChannelCreatesChannelMemberHistoryRecord(t *testing.T) {
   399  	th := Setup(t).InitBasic()
   400  	defer th.TearDown()
   401  
   402  	user1 := th.CreateUser()
   403  	user2 := th.CreateUser()
   404  
   405  	groupUserIds := make([]string, 0)
   406  	groupUserIds = append(groupUserIds, user1.Id)
   407  	groupUserIds = append(groupUserIds, user2.Id)
   408  	groupUserIds = append(groupUserIds, th.BasicUser.Id)
   409  
   410  	channel, err := th.App.CreateGroupChannel(groupUserIds, th.BasicUser.Id)
   411  
   412  	require.Nil(t, err, "Failed to create group channel.")
   413  	histories, nErr := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)
   414  	require.Nil(t, nErr)
   415  	assert.Len(t, histories, 3)
   416  
   417  	channelMemberHistoryUserIds := make([]string, 0)
   418  	for _, history := range histories {
   419  		assert.Equal(t, channel.Id, history.ChannelId)
   420  		channelMemberHistoryUserIds = append(channelMemberHistoryUserIds, history.UserId)
   421  	}
   422  
   423  	sort.Strings(groupUserIds)
   424  	sort.Strings(channelMemberHistoryUserIds)
   425  	assert.Equal(t, groupUserIds, channelMemberHistoryUserIds)
   426  }
   427  
   428  func TestCreateDirectChannelCreatesChannelMemberHistoryRecord(t *testing.T) {
   429  	th := Setup(t)
   430  	defer th.TearDown()
   431  
   432  	user1 := th.CreateUser()
   433  	user2 := th.CreateUser()
   434  
   435  	channel, err := th.App.GetOrCreateDirectChannel(user1.Id, user2.Id)
   436  	require.Nil(t, err, "Failed to create direct channel.")
   437  
   438  	histories, nErr := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)
   439  	require.Nil(t, nErr)
   440  	assert.Len(t, histories, 2)
   441  
   442  	historyId0 := histories[0].UserId
   443  	historyId1 := histories[1].UserId
   444  	switch historyId0 {
   445  	case user1.Id:
   446  		assert.Equal(t, user2.Id, historyId1)
   447  	case user2.Id:
   448  		assert.Equal(t, user1.Id, historyId1)
   449  	default:
   450  		require.Fail(t, "Unexpected user id in ChannelMemberHistory table", historyId0)
   451  	}
   452  }
   453  
   454  func TestGetDirectChannelCreatesChannelMemberHistoryRecord(t *testing.T) {
   455  	th := Setup(t)
   456  	defer th.TearDown()
   457  
   458  	user1 := th.CreateUser()
   459  	user2 := th.CreateUser()
   460  
   461  	// this function call implicitly creates a direct channel between the two users if one doesn't already exist
   462  	channel, err := th.App.GetOrCreateDirectChannel(user1.Id, user2.Id)
   463  	require.Nil(t, err, "Failed to create direct channel.")
   464  
   465  	// there should be a ChannelMemberHistory record for both users
   466  	histories, nErr := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)
   467  	require.Nil(t, nErr)
   468  	assert.Len(t, histories, 2)
   469  
   470  	historyId0 := histories[0].UserId
   471  	historyId1 := histories[1].UserId
   472  	switch historyId0 {
   473  	case user1.Id:
   474  		assert.Equal(t, user2.Id, historyId1)
   475  	case user2.Id:
   476  		assert.Equal(t, user1.Id, historyId1)
   477  	default:
   478  		require.Fail(t, "Unexpected user id in ChannelMemberHistory table", historyId0)
   479  	}
   480  }
   481  
   482  func TestAddUserToChannelCreatesChannelMemberHistoryRecord(t *testing.T) {
   483  	th := Setup(t).InitBasic()
   484  	defer th.TearDown()
   485  
   486  	// create a user and add it to a channel
   487  	user := th.CreateUser()
   488  	_, err := th.App.AddTeamMember(th.BasicTeam.Id, user.Id)
   489  	require.Nil(t, err, "Failed to add user to team.")
   490  
   491  	groupUserIds := make([]string, 0)
   492  	groupUserIds = append(groupUserIds, th.BasicUser.Id)
   493  	groupUserIds = append(groupUserIds, user.Id)
   494  
   495  	channel := th.createChannel(th.BasicTeam, model.CHANNEL_OPEN)
   496  
   497  	_, err = th.App.AddUserToChannel(user, channel)
   498  	require.Nil(t, err, "Failed to add user to channel.")
   499  
   500  	// there should be a ChannelMemberHistory record for the user
   501  	histories, nErr := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)
   502  	require.Nil(t, nErr)
   503  	assert.Len(t, histories, 2)
   504  	channelMemberHistoryUserIds := make([]string, 0)
   505  	for _, history := range histories {
   506  		assert.Equal(t, channel.Id, history.ChannelId)
   507  		channelMemberHistoryUserIds = append(channelMemberHistoryUserIds, history.UserId)
   508  	}
   509  	assert.Equal(t, groupUserIds, channelMemberHistoryUserIds)
   510  }
   511  
   512  func TestLeaveDefaultChannel(t *testing.T) {
   513  	th := Setup(t).InitBasic()
   514  	defer th.TearDown()
   515  
   516  	guest := th.CreateGuest()
   517  	th.LinkUserToTeam(guest, th.BasicTeam)
   518  
   519  	townSquare, err := th.App.GetChannelByName("town-square", th.BasicTeam.Id, false)
   520  	require.Nil(t, err)
   521  	th.AddUserToChannel(guest, townSquare)
   522  	th.AddUserToChannel(th.BasicUser, townSquare)
   523  
   524  	t.Run("User tries to leave the default channel", func(t *testing.T) {
   525  		err = th.App.LeaveChannel(townSquare.Id, th.BasicUser.Id)
   526  		assert.NotNil(t, err, "It should fail to remove a regular user from the default channel")
   527  		assert.Equal(t, err.Id, "api.channel.remove.default.app_error")
   528  		_, err = th.App.GetChannelMember(townSquare.Id, th.BasicUser.Id)
   529  		assert.Nil(t, err)
   530  	})
   531  
   532  	t.Run("Guest leaves the default channel", func(t *testing.T) {
   533  		err = th.App.LeaveChannel(townSquare.Id, guest.Id)
   534  		assert.Nil(t, err, "It should allow to remove a guest user from the default channel")
   535  		_, err = th.App.GetChannelMember(townSquare.Id, guest.Id)
   536  		assert.NotNil(t, err)
   537  	})
   538  }
   539  
   540  func TestLeaveLastChannel(t *testing.T) {
   541  	th := Setup(t).InitBasic()
   542  	defer th.TearDown()
   543  
   544  	guest := th.CreateGuest()
   545  	th.LinkUserToTeam(guest, th.BasicTeam)
   546  
   547  	townSquare, err := th.App.GetChannelByName("town-square", th.BasicTeam.Id, false)
   548  	require.Nil(t, err)
   549  	th.AddUserToChannel(guest, townSquare)
   550  	th.AddUserToChannel(guest, th.BasicChannel)
   551  
   552  	t.Run("Guest leaves not last channel", func(t *testing.T) {
   553  		err = th.App.LeaveChannel(townSquare.Id, guest.Id)
   554  		require.Nil(t, err)
   555  		_, err = th.App.GetTeamMember(th.BasicTeam.Id, guest.Id)
   556  		assert.Nil(t, err, "It should maintain the team membership")
   557  	})
   558  
   559  	t.Run("Guest leaves last channel", func(t *testing.T) {
   560  		err = th.App.LeaveChannel(th.BasicChannel.Id, guest.Id)
   561  		assert.Nil(t, err, "It should allow to remove a guest user from the default channel")
   562  		_, err = th.App.GetChannelMember(th.BasicChannel.Id, guest.Id)
   563  		assert.NotNil(t, err)
   564  		_, err = th.App.GetTeamMember(th.BasicTeam.Id, guest.Id)
   565  		assert.Nil(t, err, "It should remove the team membership")
   566  	})
   567  }
   568  
   569  func TestAddChannelMemberNoUserRequestor(t *testing.T) {
   570  	th := Setup(t).InitBasic()
   571  	defer th.TearDown()
   572  
   573  	// create a user and add it to a channel
   574  	user := th.CreateUser()
   575  	_, err := th.App.AddTeamMember(th.BasicTeam.Id, user.Id)
   576  	require.Nil(t, err)
   577  
   578  	groupUserIds := make([]string, 0)
   579  	groupUserIds = append(groupUserIds, th.BasicUser.Id)
   580  	groupUserIds = append(groupUserIds, user.Id)
   581  
   582  	channel := th.createChannel(th.BasicTeam, model.CHANNEL_OPEN)
   583  	userRequestorId := ""
   584  	postRootId := ""
   585  	_, err = th.App.AddChannelMember(user.Id, channel, userRequestorId, postRootId)
   586  	require.Nil(t, err, "Failed to add user to channel.")
   587  
   588  	// there should be a ChannelMemberHistory record for the user
   589  	histories, nErr := th.App.Srv().Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)
   590  	require.Nil(t, nErr)
   591  	assert.Len(t, histories, 2)
   592  	channelMemberHistoryUserIds := make([]string, 0)
   593  	for _, history := range histories {
   594  		assert.Equal(t, channel.Id, history.ChannelId)
   595  		channelMemberHistoryUserIds = append(channelMemberHistoryUserIds, history.UserId)
   596  	}
   597  	assert.Equal(t, groupUserIds, channelMemberHistoryUserIds)
   598  
   599  	postList, err := th.App.Srv().Store.Post().GetPosts(model.GetPostsOptions{ChannelId: channel.Id, Page: 0, PerPage: 1}, false)
   600  	require.Nil(t, err)
   601  
   602  	if assert.Len(t, postList.Order, 1) {
   603  		post := postList.Posts[postList.Order[0]]
   604  
   605  		assert.Equal(t, model.POST_JOIN_CHANNEL, post.Type)
   606  		assert.Equal(t, user.Id, post.UserId)
   607  		assert.Equal(t, user.Username, post.GetProp("username"))
   608  	}
   609  }
   610  
   611  func TestAppUpdateChannelScheme(t *testing.T) {
   612  	th := Setup(t).InitBasic()
   613  	defer th.TearDown()
   614  
   615  	channel := th.BasicChannel
   616  	mockID := model.NewString("x")
   617  	channel.SchemeId = mockID
   618  
   619  	updatedChannel, err := th.App.UpdateChannelScheme(channel)
   620  	require.Nil(t, err)
   621  
   622  	if updatedChannel.SchemeId != mockID {
   623  		require.Fail(t, "Wrong Channel SchemeId")
   624  	}
   625  }
   626  
   627  func TestFillInChannelProps(t *testing.T) {
   628  	th := Setup(t).InitBasic()
   629  	defer th.TearDown()
   630  
   631  	channelPublic1, err := th.App.CreateChannel(&model.Channel{DisplayName: "Public 1", Name: "public1", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}, false)
   632  	require.Nil(t, err)
   633  	defer th.App.PermanentDeleteChannel(channelPublic1)
   634  
   635  	channelPublic2, err := th.App.CreateChannel(&model.Channel{DisplayName: "Public 2", Name: "public2", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}, false)
   636  	require.Nil(t, err)
   637  	defer th.App.PermanentDeleteChannel(channelPublic2)
   638  
   639  	channelPrivate, err := th.App.CreateChannel(&model.Channel{DisplayName: "Private", Name: "private", Type: model.CHANNEL_PRIVATE, TeamId: th.BasicTeam.Id}, false)
   640  	require.Nil(t, err)
   641  	defer th.App.PermanentDeleteChannel(channelPrivate)
   642  
   643  	otherTeamId := model.NewId()
   644  	otherTeam := &model.Team{
   645  		DisplayName: "dn_" + otherTeamId,
   646  		Name:        "name" + otherTeamId,
   647  		Email:       "success+" + otherTeamId + "@simulator.amazonses.com",
   648  		Type:        model.TEAM_OPEN,
   649  	}
   650  	otherTeam, err = th.App.CreateTeam(otherTeam)
   651  	require.Nil(t, err)
   652  	defer th.App.PermanentDeleteTeam(otherTeam)
   653  
   654  	channelOtherTeam, err := th.App.CreateChannel(&model.Channel{DisplayName: "Other Team Channel", Name: "other-team", Type: model.CHANNEL_OPEN, TeamId: otherTeam.Id}, false)
   655  	require.Nil(t, err)
   656  	defer th.App.PermanentDeleteChannel(channelOtherTeam)
   657  
   658  	// Note that purpose is intentionally plaintext below.
   659  
   660  	t.Run("single channels", func(t *testing.T) {
   661  		testCases := []struct {
   662  			Description          string
   663  			Channel              *model.Channel
   664  			ExpectedChannelProps map[string]interface{}
   665  		}{
   666  			{
   667  				"channel on basic team without references",
   668  				&model.Channel{
   669  					TeamId:  th.BasicTeam.Id,
   670  					Header:  "No references",
   671  					Purpose: "No references",
   672  				},
   673  				nil,
   674  			},
   675  			{
   676  				"channel on basic team",
   677  				&model.Channel{
   678  					TeamId:  th.BasicTeam.Id,
   679  					Header:  "~public1, ~private, ~other-team",
   680  					Purpose: "~public2, ~private, ~other-team",
   681  				},
   682  				map[string]interface{}{
   683  					"channel_mentions": map[string]interface{}{
   684  						"public1": map[string]interface{}{
   685  							"display_name": "Public 1",
   686  						},
   687  					},
   688  				},
   689  			},
   690  			{
   691  				"channel on other team",
   692  				&model.Channel{
   693  					TeamId:  otherTeam.Id,
   694  					Header:  "~public1, ~private, ~other-team",
   695  					Purpose: "~public2, ~private, ~other-team",
   696  				},
   697  				map[string]interface{}{
   698  					"channel_mentions": map[string]interface{}{
   699  						"other-team": map[string]interface{}{
   700  							"display_name": "Other Team Channel",
   701  						},
   702  					},
   703  				},
   704  			},
   705  		}
   706  
   707  		for _, testCase := range testCases {
   708  			t.Run(testCase.Description, func(t *testing.T) {
   709  				err = th.App.FillInChannelProps(testCase.Channel)
   710  				require.Nil(t, err)
   711  
   712  				assert.Equal(t, testCase.ExpectedChannelProps, testCase.Channel.Props)
   713  			})
   714  		}
   715  	})
   716  
   717  	t.Run("multiple channels", func(t *testing.T) {
   718  		testCases := []struct {
   719  			Description          string
   720  			Channels             *model.ChannelList
   721  			ExpectedChannelProps map[string]interface{}
   722  		}{
   723  			{
   724  				"single channel on basic team",
   725  				&model.ChannelList{
   726  					{
   727  						Name:    "test",
   728  						TeamId:  th.BasicTeam.Id,
   729  						Header:  "~public1, ~private, ~other-team",
   730  						Purpose: "~public2, ~private, ~other-team",
   731  					},
   732  				},
   733  				map[string]interface{}{
   734  					"test": map[string]interface{}{
   735  						"channel_mentions": map[string]interface{}{
   736  							"public1": map[string]interface{}{
   737  								"display_name": "Public 1",
   738  							},
   739  						},
   740  					},
   741  				},
   742  			},
   743  			{
   744  				"multiple channels on basic team",
   745  				&model.ChannelList{
   746  					{
   747  						Name:    "test",
   748  						TeamId:  th.BasicTeam.Id,
   749  						Header:  "~public1, ~private, ~other-team",
   750  						Purpose: "~public2, ~private, ~other-team",
   751  					},
   752  					{
   753  						Name:    "test2",
   754  						TeamId:  th.BasicTeam.Id,
   755  						Header:  "~private, ~other-team",
   756  						Purpose: "~public2, ~private, ~other-team",
   757  					},
   758  					{
   759  						Name:    "test3",
   760  						TeamId:  th.BasicTeam.Id,
   761  						Header:  "No references",
   762  						Purpose: "No references",
   763  					},
   764  				},
   765  				map[string]interface{}{
   766  					"test": map[string]interface{}{
   767  						"channel_mentions": map[string]interface{}{
   768  							"public1": map[string]interface{}{
   769  								"display_name": "Public 1",
   770  							},
   771  						},
   772  					},
   773  					"test2": map[string]interface{}(nil),
   774  					"test3": map[string]interface{}(nil),
   775  				},
   776  			},
   777  			{
   778  				"multiple channels across teams",
   779  				&model.ChannelList{
   780  					{
   781  						Name:    "test",
   782  						TeamId:  th.BasicTeam.Id,
   783  						Header:  "~public1, ~private, ~other-team",
   784  						Purpose: "~public2, ~private, ~other-team",
   785  					},
   786  					{
   787  						Name:    "test2",
   788  						TeamId:  otherTeam.Id,
   789  						Header:  "~private, ~other-team",
   790  						Purpose: "~public2, ~private, ~other-team",
   791  					},
   792  					{
   793  						Name:    "test3",
   794  						TeamId:  th.BasicTeam.Id,
   795  						Header:  "No references",
   796  						Purpose: "No references",
   797  					},
   798  				},
   799  				map[string]interface{}{
   800  					"test": map[string]interface{}{
   801  						"channel_mentions": map[string]interface{}{
   802  							"public1": map[string]interface{}{
   803  								"display_name": "Public 1",
   804  							},
   805  						},
   806  					},
   807  					"test2": map[string]interface{}{
   808  						"channel_mentions": map[string]interface{}{
   809  							"other-team": map[string]interface{}{
   810  								"display_name": "Other Team Channel",
   811  							},
   812  						},
   813  					},
   814  					"test3": map[string]interface{}(nil),
   815  				},
   816  			},
   817  		}
   818  
   819  		for _, testCase := range testCases {
   820  			t.Run(testCase.Description, func(t *testing.T) {
   821  				err = th.App.FillInChannelsProps(testCase.Channels)
   822  				require.Nil(t, err)
   823  
   824  				for _, channel := range *testCase.Channels {
   825  					assert.Equal(t, testCase.ExpectedChannelProps[channel.Name], channel.Props)
   826  				}
   827  			})
   828  		}
   829  	})
   830  }
   831  
   832  func TestRenameChannel(t *testing.T) {
   833  	th := Setup(t).InitBasic()
   834  	defer th.TearDown()
   835  
   836  	testCases := []struct {
   837  		Name                string
   838  		Channel             *model.Channel
   839  		ExpectError         bool
   840  		ChannelName         string
   841  		ExpectedName        string
   842  		ExpectedDisplayName string
   843  	}{
   844  		{
   845  			"Rename open channel",
   846  			th.createChannel(th.BasicTeam, model.CHANNEL_OPEN),
   847  			false,
   848  			"newchannelname",
   849  			"newchannelname",
   850  			"New Display Name",
   851  		},
   852  		{
   853  			"Fail on rename open channel with bad name",
   854  			th.createChannel(th.BasicTeam, model.CHANNEL_OPEN),
   855  			true,
   856  			"6zii9a9g6pruzj451x3esok54h__wr4j4g8zqtnhmkw771pfpynqwo",
   857  			"",
   858  			"",
   859  		},
   860  		{
   861  			"Success on rename open channel with consecutive underscores in name",
   862  			th.createChannel(th.BasicTeam, model.CHANNEL_OPEN),
   863  			false,
   864  			"foo__bar",
   865  			"foo__bar",
   866  			"New Display Name",
   867  		},
   868  		{
   869  			"Fail on rename direct message channel",
   870  			th.CreateDmChannel(th.BasicUser2),
   871  			true,
   872  			"newchannelname",
   873  			"",
   874  			"",
   875  		},
   876  		{
   877  			"Fail on rename group message channel",
   878  			th.CreateGroupChannel(th.BasicUser2, th.CreateUser()),
   879  			true,
   880  			"newchannelname",
   881  			"",
   882  			"",
   883  		},
   884  	}
   885  
   886  	for _, tc := range testCases {
   887  		t.Run(tc.Name, func(t *testing.T) {
   888  			channel, err := th.App.RenameChannel(tc.Channel, tc.ChannelName, "New Display Name")
   889  			if tc.ExpectError {
   890  				assert.NotNil(t, err)
   891  			} else {
   892  				assert.Equal(t, tc.ExpectedName, channel.Name)
   893  				assert.Equal(t, tc.ExpectedDisplayName, channel.DisplayName)
   894  			}
   895  		})
   896  	}
   897  }
   898  
   899  func TestGetChannelMembersTimezones(t *testing.T) {
   900  	th := Setup(t).InitBasic()
   901  	defer th.TearDown()
   902  
   903  	userRequestorId := ""
   904  	postRootId := ""
   905  	_, err := th.App.AddChannelMember(th.BasicUser2.Id, th.BasicChannel, userRequestorId, postRootId)
   906  	require.Nil(t, err, "Failed to add user to channel.")
   907  
   908  	user := th.BasicUser
   909  	user.Timezone["useAutomaticTimezone"] = "false"
   910  	user.Timezone["manualTimezone"] = "XOXO/BLABLA"
   911  	th.App.UpdateUser(user, false)
   912  
   913  	user2 := th.BasicUser2
   914  	user2.Timezone["automaticTimezone"] = "NoWhere/Island"
   915  	th.App.UpdateUser(user2, false)
   916  
   917  	user3 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
   918  	ruser, _ := th.App.CreateUser(&user3)
   919  	th.App.AddUserToChannel(ruser, th.BasicChannel)
   920  
   921  	ruser.Timezone["automaticTimezone"] = "NoWhere/Island"
   922  	th.App.UpdateUser(ruser, false)
   923  
   924  	user4 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
   925  	ruser, _ = th.App.CreateUser(&user4)
   926  	th.App.AddUserToChannel(ruser, th.BasicChannel)
   927  
   928  	timezones, err := th.App.GetChannelMembersTimezones(th.BasicChannel.Id)
   929  	require.Nil(t, err, "Failed to get the timezones for a channel.")
   930  
   931  	assert.Equal(t, 2, len(timezones))
   932  }
   933  
   934  func TestGetChannelsForUser(t *testing.T) {
   935  	th := Setup(t).InitBasic()
   936  	channel := &model.Channel{
   937  		DisplayName: "Public",
   938  		Name:        "public",
   939  		Type:        model.CHANNEL_OPEN,
   940  		CreatorId:   th.BasicUser.Id,
   941  		TeamId:      th.BasicTeam.Id,
   942  	}
   943  	th.App.CreateChannel(channel, true)
   944  	defer th.App.PermanentDeleteChannel(channel)
   945  	defer th.TearDown()
   946  
   947  	channelList, err := th.App.GetChannelsForUser(th.BasicTeam.Id, th.BasicUser.Id, false, 0)
   948  	require.Nil(t, err)
   949  	require.Len(t, *channelList, 4)
   950  
   951  	th.App.DeleteChannel(channel, th.BasicUser.Id)
   952  
   953  	// Now we get all the non-archived channels for the user
   954  	channelList, err = th.App.GetChannelsForUser(th.BasicTeam.Id, th.BasicUser.Id, false, 0)
   955  	require.Nil(t, err)
   956  	require.Len(t, *channelList, 3)
   957  
   958  	// Now we get all the channels, even though are archived, for the user
   959  	channelList, err = th.App.GetChannelsForUser(th.BasicTeam.Id, th.BasicUser.Id, true, 0)
   960  	require.Nil(t, err)
   961  	require.Len(t, *channelList, 4)
   962  }
   963  
   964  func TestGetPublicChannelsForTeam(t *testing.T) {
   965  	th := Setup(t)
   966  	team := th.CreateTeam()
   967  	defer th.TearDown()
   968  
   969  	var expectedChannels []*model.Channel
   970  
   971  	townSquare, err := th.App.GetChannelByName("town-square", team.Id, false)
   972  	require.Nil(t, err)
   973  	require.NotNil(t, townSquare)
   974  	expectedChannels = append(expectedChannels, townSquare)
   975  
   976  	offTopic, err := th.App.GetChannelByName("off-topic", team.Id, false)
   977  	require.Nil(t, err)
   978  	require.NotNil(t, offTopic)
   979  	expectedChannels = append(expectedChannels, offTopic)
   980  
   981  	for i := 0; i < 8; i++ {
   982  		channel := model.Channel{
   983  			DisplayName: fmt.Sprintf("Public %v", i),
   984  			Name:        fmt.Sprintf("public_%v", i),
   985  			Type:        model.CHANNEL_OPEN,
   986  			TeamId:      team.Id,
   987  		}
   988  		var rchannel *model.Channel
   989  		rchannel, err = th.App.CreateChannel(&channel, false)
   990  		require.Nil(t, err)
   991  		require.NotNil(t, rchannel)
   992  		defer th.App.PermanentDeleteChannel(rchannel)
   993  
   994  		// Store the user ids for comparison later
   995  		expectedChannels = append(expectedChannels, rchannel)
   996  	}
   997  
   998  	// Fetch public channels multipile times
   999  	channelList, err := th.App.GetPublicChannelsForTeam(team.Id, 0, 5)
  1000  	require.Nil(t, err)
  1001  	channelList2, err := th.App.GetPublicChannelsForTeam(team.Id, 5, 5)
  1002  	require.Nil(t, err)
  1003  
  1004  	channels := append(*channelList, *channelList2...)
  1005  	assert.ElementsMatch(t, expectedChannels, channels)
  1006  }
  1007  
  1008  func TestGetPrivateChannelsForTeam(t *testing.T) {
  1009  	th := Setup(t)
  1010  	team := th.CreateTeam()
  1011  	defer th.TearDown()
  1012  
  1013  	var expectedChannels []*model.Channel
  1014  	for i := 0; i < 8; i++ {
  1015  		channel := model.Channel{
  1016  			DisplayName: fmt.Sprintf("Private %v", i),
  1017  			Name:        fmt.Sprintf("private_%v", i),
  1018  			Type:        model.CHANNEL_PRIVATE,
  1019  			TeamId:      team.Id,
  1020  		}
  1021  		var rchannel *model.Channel
  1022  		rchannel, err := th.App.CreateChannel(&channel, false)
  1023  		require.Nil(t, err)
  1024  		require.NotNil(t, rchannel)
  1025  		defer th.App.PermanentDeleteChannel(rchannel)
  1026  
  1027  		// Store the user ids for comparison later
  1028  		expectedChannels = append(expectedChannels, rchannel)
  1029  	}
  1030  
  1031  	// Fetch private channels multipile times
  1032  	channelList, err := th.App.GetPrivateChannelsForTeam(team.Id, 0, 5)
  1033  	require.Nil(t, err)
  1034  	channelList2, err := th.App.GetPrivateChannelsForTeam(team.Id, 5, 5)
  1035  	require.Nil(t, err)
  1036  
  1037  	channels := append(*channelList, *channelList2...)
  1038  	assert.ElementsMatch(t, expectedChannels, channels)
  1039  }
  1040  
  1041  func TestUpdateChannelMemberRolesChangingGuest(t *testing.T) {
  1042  	th := Setup(t).InitBasic()
  1043  	defer th.TearDown()
  1044  
  1045  	t.Run("from guest to user", func(t *testing.T) {
  1046  		user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
  1047  		ruser, _ := th.App.CreateGuest(&user)
  1048  
  1049  		_, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, "")
  1050  		require.Nil(t, err)
  1051  
  1052  		_, err = th.App.AddUserToChannel(ruser, th.BasicChannel)
  1053  		require.Nil(t, err)
  1054  
  1055  		_, err = th.App.UpdateChannelMemberRoles(th.BasicChannel.Id, ruser.Id, "channel_user")
  1056  		require.NotNil(t, err, "Should fail when try to modify the guest role")
  1057  	})
  1058  
  1059  	t.Run("from user to guest", func(t *testing.T) {
  1060  		user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
  1061  		ruser, _ := th.App.CreateUser(&user)
  1062  
  1063  		_, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, "")
  1064  		require.Nil(t, err)
  1065  
  1066  		_, err = th.App.AddUserToChannel(ruser, th.BasicChannel)
  1067  		require.Nil(t, err)
  1068  
  1069  		_, err = th.App.UpdateChannelMemberRoles(th.BasicChannel.Id, ruser.Id, "channel_guest")
  1070  		require.NotNil(t, err, "Should fail when try to modify the guest role")
  1071  	})
  1072  
  1073  	t.Run("from user to admin", func(t *testing.T) {
  1074  		user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
  1075  		ruser, _ := th.App.CreateUser(&user)
  1076  
  1077  		_, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, "")
  1078  		require.Nil(t, err)
  1079  
  1080  		_, err = th.App.AddUserToChannel(ruser, th.BasicChannel)
  1081  		require.Nil(t, err)
  1082  
  1083  		_, err = th.App.UpdateChannelMemberRoles(th.BasicChannel.Id, ruser.Id, "channel_user channel_admin")
  1084  		require.Nil(t, err, "Should work when you not modify guest role")
  1085  	})
  1086  
  1087  	t.Run("from guest to guest plus custom", func(t *testing.T) {
  1088  		user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
  1089  		ruser, _ := th.App.CreateGuest(&user)
  1090  
  1091  		_, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, "")
  1092  		require.Nil(t, err)
  1093  
  1094  		_, err = th.App.AddUserToChannel(ruser, th.BasicChannel)
  1095  		require.Nil(t, err)
  1096  
  1097  		_, err = th.App.CreateRole(&model.Role{Name: "custom", DisplayName: "custom", Description: "custom"})
  1098  		require.Nil(t, err)
  1099  
  1100  		_, err = th.App.UpdateChannelMemberRoles(th.BasicChannel.Id, ruser.Id, "channel_guest custom")
  1101  		require.Nil(t, err, "Should work when you not modify guest role")
  1102  	})
  1103  
  1104  	t.Run("a guest cant have user role", func(t *testing.T) {
  1105  		user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
  1106  		ruser, _ := th.App.CreateGuest(&user)
  1107  
  1108  		_, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, "")
  1109  		require.Nil(t, err)
  1110  
  1111  		_, err = th.App.AddUserToChannel(ruser, th.BasicChannel)
  1112  		require.Nil(t, err)
  1113  
  1114  		_, err = th.App.UpdateChannelMemberRoles(th.BasicChannel.Id, ruser.Id, "channel_guest channel_user")
  1115  		require.NotNil(t, err, "Should work when you not modify guest role")
  1116  	})
  1117  }
  1118  
  1119  func TestDefaultChannelNames(t *testing.T) {
  1120  	th := Setup(t)
  1121  	defer th.TearDown()
  1122  
  1123  	actual := th.App.DefaultChannelNames()
  1124  	expect := []string{"town-square", "off-topic"}
  1125  	require.ElementsMatch(t, expect, actual)
  1126  
  1127  	th.App.UpdateConfig(func(cfg *model.Config) {
  1128  		cfg.TeamSettings.ExperimentalDefaultChannels = []string{"foo", "bar"}
  1129  	})
  1130  
  1131  	actual = th.App.DefaultChannelNames()
  1132  	expect = []string{"town-square", "foo", "bar"}
  1133  	require.ElementsMatch(t, expect, actual)
  1134  }
  1135  
  1136  func TestSearchChannelsForUser(t *testing.T) {
  1137  	th := Setup(t).InitBasic()
  1138  	defer th.TearDown()
  1139  
  1140  	c1, err := th.App.CreateChannel(&model.Channel{DisplayName: "test-dev-1", Name: "test-dev-1", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}, false)
  1141  	require.Nil(t, err)
  1142  
  1143  	c2, err := th.App.CreateChannel(&model.Channel{DisplayName: "test-dev-2", Name: "test-dev-2", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}, false)
  1144  	require.Nil(t, err)
  1145  
  1146  	c3, err := th.App.CreateChannel(&model.Channel{DisplayName: "dev-3", Name: "dev-3", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}, false)
  1147  	require.Nil(t, err)
  1148  
  1149  	defer func() {
  1150  		th.App.PermanentDeleteChannel(c1)
  1151  		th.App.PermanentDeleteChannel(c2)
  1152  		th.App.PermanentDeleteChannel(c3)
  1153  	}()
  1154  
  1155  	// add user to test-dev-1 and dev3
  1156  	_, err = th.App.AddUserToChannel(th.BasicUser, c1)
  1157  	require.Nil(t, err)
  1158  	_, err = th.App.AddUserToChannel(th.BasicUser, c3)
  1159  	require.Nil(t, err)
  1160  
  1161  	searchAndCheck := func(t *testing.T, term string, expectedDisplayNames []string) {
  1162  		res, searchErr := th.App.SearchChannelsForUser(th.BasicUser.Id, th.BasicTeam.Id, term)
  1163  		require.Nil(t, searchErr)
  1164  		require.Len(t, *res, len(expectedDisplayNames))
  1165  
  1166  		resultDisplayNames := []string{}
  1167  		for _, c := range *res {
  1168  			resultDisplayNames = append(resultDisplayNames, c.Name)
  1169  		}
  1170  		require.ElementsMatch(t, expectedDisplayNames, resultDisplayNames)
  1171  	}
  1172  
  1173  	t.Run("Search for test, only test-dev-1 should be returned", func(t *testing.T) {
  1174  		searchAndCheck(t, "test", []string{"test-dev-1"})
  1175  	})
  1176  
  1177  	t.Run("Search for dev, both test-dev-1 and dev-3 should be returned", func(t *testing.T) {
  1178  		searchAndCheck(t, "dev", []string{"test-dev-1", "dev-3"})
  1179  	})
  1180  
  1181  	t.Run("After adding user to test-dev-2, search for dev, the three channels should be returned", func(t *testing.T) {
  1182  		_, err = th.App.AddUserToChannel(th.BasicUser, c2)
  1183  		require.Nil(t, err)
  1184  
  1185  		searchAndCheck(t, "dev", []string{"test-dev-1", "test-dev-2", "dev-3"})
  1186  	})
  1187  }
  1188  
  1189  func TestMarkChannelAsUnreadFromPost(t *testing.T) {
  1190  	th := Setup(t).InitBasic()
  1191  	defer th.TearDown()
  1192  
  1193  	u1 := th.BasicUser
  1194  	u2 := th.BasicUser2
  1195  	c1 := th.BasicChannel
  1196  	pc1 := th.CreatePrivateChannel(th.BasicTeam)
  1197  	th.AddUserToChannel(u2, c1)
  1198  	th.AddUserToChannel(u1, pc1)
  1199  	th.AddUserToChannel(u2, pc1)
  1200  
  1201  	p1 := th.CreatePost(c1)
  1202  	p2 := th.CreatePost(c1)
  1203  	p3 := th.CreatePost(c1)
  1204  
  1205  	pp1 := th.CreatePost(pc1)
  1206  	require.NotNil(t, pp1)
  1207  	pp2 := th.CreatePost(pc1)
  1208  
  1209  	unread, err := th.App.GetChannelUnread(c1.Id, u1.Id)
  1210  	require.Nil(t, err)
  1211  	require.Equal(t, int64(4), unread.MsgCount)
  1212  	unread, err = th.App.GetChannelUnread(c1.Id, u2.Id)
  1213  	require.Nil(t, err)
  1214  	require.Equal(t, int64(4), unread.MsgCount)
  1215  	err = th.App.UpdateChannelLastViewedAt([]string{c1.Id, pc1.Id}, u1.Id)
  1216  	require.Nil(t, err)
  1217  	err = th.App.UpdateChannelLastViewedAt([]string{c1.Id, pc1.Id}, u2.Id)
  1218  	require.Nil(t, err)
  1219  	unread, err = th.App.GetChannelUnread(c1.Id, u2.Id)
  1220  	require.Nil(t, err)
  1221  	require.Equal(t, int64(0), unread.MsgCount)
  1222  
  1223  	t.Run("Unread but last one", func(t *testing.T) {
  1224  		response, err := th.App.MarkChannelAsUnreadFromPost(p2.Id, u1.Id)
  1225  		require.Nil(t, err)
  1226  		require.NotNil(t, response)
  1227  		assert.Equal(t, int64(2), response.MsgCount)
  1228  		unread, err := th.App.GetChannelUnread(c1.Id, u1.Id)
  1229  		require.Nil(t, err)
  1230  		assert.Equal(t, int64(2), unread.MsgCount)
  1231  		assert.Equal(t, p2.CreateAt-1, response.LastViewedAt)
  1232  	})
  1233  
  1234  	t.Run("Unread last one", func(t *testing.T) {
  1235  		response, err := th.App.MarkChannelAsUnreadFromPost(p3.Id, u1.Id)
  1236  		require.Nil(t, err)
  1237  		require.NotNil(t, response)
  1238  		assert.Equal(t, int64(3), response.MsgCount)
  1239  		unread, err := th.App.GetChannelUnread(c1.Id, u1.Id)
  1240  		require.Nil(t, err)
  1241  		assert.Equal(t, int64(1), unread.MsgCount)
  1242  		assert.Equal(t, p3.CreateAt-1, response.LastViewedAt)
  1243  	})
  1244  
  1245  	t.Run("Unread first one", func(t *testing.T) {
  1246  		response, err := th.App.MarkChannelAsUnreadFromPost(p1.Id, u1.Id)
  1247  		require.Nil(t, err)
  1248  		require.NotNil(t, response)
  1249  		assert.Equal(t, int64(1), response.MsgCount)
  1250  		unread, err := th.App.GetChannelUnread(c1.Id, u1.Id)
  1251  		require.Nil(t, err)
  1252  		assert.Equal(t, int64(3), unread.MsgCount)
  1253  		assert.Equal(t, p1.CreateAt-1, response.LastViewedAt)
  1254  	})
  1255  
  1256  	t.Run("Other users are unaffected", func(t *testing.T) {
  1257  		unread, err := th.App.GetChannelUnread(c1.Id, u2.Id)
  1258  		require.Nil(t, err)
  1259  		assert.Equal(t, int64(0), unread.MsgCount)
  1260  	})
  1261  
  1262  	t.Run("Unread on a private channel", func(t *testing.T) {
  1263  		response, err := th.App.MarkChannelAsUnreadFromPost(pp1.Id, u1.Id)
  1264  		require.Nil(t, err)
  1265  		require.NotNil(t, response)
  1266  		assert.Equal(t, int64(0), response.MsgCount)
  1267  		unread, err := th.App.GetChannelUnread(pc1.Id, u1.Id)
  1268  		require.Nil(t, err)
  1269  		assert.Equal(t, int64(2), unread.MsgCount)
  1270  		assert.Equal(t, pp1.CreateAt-1, response.LastViewedAt)
  1271  
  1272  		response, err = th.App.MarkChannelAsUnreadFromPost(pp2.Id, u1.Id)
  1273  		assert.Nil(t, err)
  1274  		assert.Equal(t, int64(1), response.MsgCount)
  1275  		unread, err = th.App.GetChannelUnread(pc1.Id, u1.Id)
  1276  		require.Nil(t, err)
  1277  		assert.Equal(t, int64(1), unread.MsgCount)
  1278  		assert.Equal(t, pp2.CreateAt-1, response.LastViewedAt)
  1279  	})
  1280  
  1281  	t.Run("Unread with mentions", func(t *testing.T) {
  1282  		c2 := th.CreateChannel(th.BasicTeam)
  1283  		_, err := th.App.AddUserToChannel(u2, c2)
  1284  		require.Nil(t, err)
  1285  
  1286  		p4, err := th.App.CreatePost(&model.Post{
  1287  			UserId:    u2.Id,
  1288  			ChannelId: c2.Id,
  1289  			Message:   "@" + u1.Username,
  1290  		}, c2, false, true)
  1291  		require.Nil(t, err)
  1292  		th.CreatePost(c2)
  1293  
  1294  		response, err := th.App.MarkChannelAsUnreadFromPost(p4.Id, u1.Id)
  1295  		assert.Nil(t, err)
  1296  		assert.Equal(t, int64(1), response.MsgCount)
  1297  		assert.Equal(t, int64(1), response.MentionCount)
  1298  
  1299  		unread, err := th.App.GetChannelUnread(c2.Id, u1.Id)
  1300  		require.Nil(t, err)
  1301  		assert.Equal(t, int64(1), unread.MsgCount)
  1302  		assert.Equal(t, int64(1), unread.MentionCount)
  1303  	})
  1304  
  1305  	t.Run("Unread on a DM channel", func(t *testing.T) {
  1306  		dc := th.CreateDmChannel(u2)
  1307  
  1308  		dm1 := th.CreatePost(dc)
  1309  		th.CreatePost(dc)
  1310  		th.CreatePost(dc)
  1311  
  1312  		response, err := th.App.MarkChannelAsUnreadFromPost(dm1.Id, u2.Id)
  1313  		assert.Nil(t, err)
  1314  		assert.Equal(t, int64(0), response.MsgCount)
  1315  		assert.Equal(t, int64(3), response.MentionCount)
  1316  
  1317  		unread, err := th.App.GetChannelUnread(dc.Id, u2.Id)
  1318  		require.Nil(t, err)
  1319  		assert.Equal(t, int64(3), unread.MsgCount)
  1320  		assert.Equal(t, int64(3), unread.MentionCount)
  1321  	})
  1322  
  1323  	t.Run("Can't unread an imaginary post", func(t *testing.T) {
  1324  		response, err := th.App.MarkChannelAsUnreadFromPost("invalid4ofngungryquinj976y", u1.Id)
  1325  		assert.NotNil(t, err)
  1326  		assert.Nil(t, response)
  1327  	})
  1328  }
  1329  
  1330  func TestAddUserToChannel(t *testing.T) {
  1331  	th := Setup(t).InitBasic()
  1332  	defer th.TearDown()
  1333  
  1334  	user1 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
  1335  	ruser1, _ := th.App.CreateUser(&user1)
  1336  	defer th.App.PermanentDeleteUser(&user1)
  1337  	bot := th.CreateBot()
  1338  	botUser, _ := th.App.GetUser(bot.UserId)
  1339  	defer th.App.PermanentDeleteBot(botUser.Id)
  1340  
  1341  	th.App.AddTeamMember(th.BasicTeam.Id, ruser1.Id)
  1342  	th.App.AddTeamMember(th.BasicTeam.Id, bot.UserId)
  1343  
  1344  	group := th.CreateGroup()
  1345  
  1346  	_, err := th.App.UpsertGroupMember(group.Id, user1.Id)
  1347  	require.Nil(t, err)
  1348  
  1349  	gs, err := th.App.UpsertGroupSyncable(&model.GroupSyncable{
  1350  		AutoAdd:     true,
  1351  		SyncableId:  th.BasicChannel.Id,
  1352  		Type:        model.GroupSyncableTypeChannel,
  1353  		GroupId:     group.Id,
  1354  		SchemeAdmin: false,
  1355  	})
  1356  	require.Nil(t, err)
  1357  
  1358  	err = th.App.JoinChannel(th.BasicChannel, ruser1.Id)
  1359  	require.Nil(t, err)
  1360  
  1361  	// verify user was added as a non-admin
  1362  	cm1, err := th.App.GetChannelMember(th.BasicChannel.Id, ruser1.Id)
  1363  	require.Nil(t, err)
  1364  	require.False(t, cm1.SchemeAdmin)
  1365  
  1366  	user2 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
  1367  	ruser2, _ := th.App.CreateUser(&user2)
  1368  	defer th.App.PermanentDeleteUser(&user2)
  1369  	th.App.AddTeamMember(th.BasicTeam.Id, ruser2.Id)
  1370  
  1371  	_, err = th.App.UpsertGroupMember(group.Id, user2.Id)
  1372  	require.Nil(t, err)
  1373  
  1374  	gs.SchemeAdmin = true
  1375  	_, err = th.App.UpdateGroupSyncable(gs)
  1376  	require.Nil(t, err)
  1377  
  1378  	err = th.App.JoinChannel(th.BasicChannel, ruser2.Id)
  1379  	require.Nil(t, err)
  1380  
  1381  	// Should allow a bot to be added to a public group synced channel
  1382  	_, err = th.App.AddUserToChannel(botUser, th.BasicChannel)
  1383  	require.Nil(t, err)
  1384  
  1385  	// verify user was added as an admin
  1386  	cm2, err := th.App.GetChannelMember(th.BasicChannel.Id, ruser2.Id)
  1387  	require.Nil(t, err)
  1388  	require.True(t, cm2.SchemeAdmin)
  1389  
  1390  	privateChannel := th.CreatePrivateChannel(th.BasicTeam)
  1391  	privateChannel.GroupConstrained = model.NewBool(true)
  1392  	_, err = th.App.UpdateChannel(privateChannel)
  1393  	require.Nil(t, err)
  1394  
  1395  	_, err = th.App.UpsertGroupSyncable(&model.GroupSyncable{
  1396  		GroupId:    group.Id,
  1397  		SyncableId: privateChannel.Id,
  1398  		Type:       model.GroupSyncableTypeChannel,
  1399  	})
  1400  	require.Nil(t, err)
  1401  
  1402  	// Should allow a group synced user to be added to a group synced private channel
  1403  	_, err = th.App.AddUserToChannel(ruser1, privateChannel)
  1404  	require.Nil(t, err)
  1405  
  1406  	// Should allow a bot to be added to a private group synced channel
  1407  	_, err = th.App.AddUserToChannel(botUser, privateChannel)
  1408  	require.Nil(t, err)
  1409  }
  1410  
  1411  func TestRemoveUserFromChannel(t *testing.T) {
  1412  	th := Setup(t).InitBasic()
  1413  	defer th.TearDown()
  1414  
  1415  	user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
  1416  	ruser, _ := th.App.CreateUser(&user)
  1417  	defer th.App.PermanentDeleteUser(ruser)
  1418  
  1419  	bot := th.CreateBot()
  1420  	botUser, _ := th.App.GetUser(bot.UserId)
  1421  	defer th.App.PermanentDeleteBot(botUser.Id)
  1422  
  1423  	th.App.AddTeamMember(th.BasicTeam.Id, ruser.Id)
  1424  	th.App.AddTeamMember(th.BasicTeam.Id, bot.UserId)
  1425  
  1426  	privateChannel := th.CreatePrivateChannel(th.BasicTeam)
  1427  
  1428  	_, err := th.App.AddUserToChannel(ruser, privateChannel)
  1429  	require.Nil(t, err)
  1430  	_, err = th.App.AddUserToChannel(botUser, privateChannel)
  1431  	require.Nil(t, err)
  1432  
  1433  	group := th.CreateGroup()
  1434  	_, err = th.App.UpsertGroupMember(group.Id, ruser.Id)
  1435  	require.Nil(t, err)
  1436  
  1437  	_, err = th.App.UpsertGroupSyncable(&model.GroupSyncable{
  1438  		GroupId:    group.Id,
  1439  		SyncableId: privateChannel.Id,
  1440  		Type:       model.GroupSyncableTypeChannel,
  1441  	})
  1442  	require.Nil(t, err)
  1443  
  1444  	privateChannel.GroupConstrained = model.NewBool(true)
  1445  	_, err = th.App.UpdateChannel(privateChannel)
  1446  	require.Nil(t, err)
  1447  
  1448  	// Should not allow a group synced user to be removed from channel
  1449  	err = th.App.RemoveUserFromChannel(ruser.Id, th.SystemAdminUser.Id, privateChannel)
  1450  	assert.Equal(t, err.Id, "api.channel.remove_members.denied")
  1451  
  1452  	// Should allow a user to remove themselves from group synced channel
  1453  	err = th.App.RemoveUserFromChannel(ruser.Id, ruser.Id, privateChannel)
  1454  	require.Nil(t, err)
  1455  
  1456  	// Should allow a bot to be removed from a group synced channel
  1457  	err = th.App.RemoveUserFromChannel(botUser.Id, th.SystemAdminUser.Id, privateChannel)
  1458  	require.Nil(t, err)
  1459  }
  1460  
  1461  func TestPatchChannelModerationsForChannel(t *testing.T) {
  1462  	th := Setup(t).InitBasic()
  1463  	defer th.TearDown()
  1464  
  1465  	th.App.SetPhase2PermissionsMigrationStatus(true)
  1466  	channel := th.BasicChannel
  1467  
  1468  	createPosts := model.CHANNEL_MODERATED_PERMISSIONS[0]
  1469  	createReactions := model.CHANNEL_MODERATED_PERMISSIONS[1]
  1470  	manageMembers := model.CHANNEL_MODERATED_PERMISSIONS[2]
  1471  	channelMentions := model.CHANNEL_MODERATED_PERMISSIONS[3]
  1472  
  1473  	nonChannelModeratedPermission := model.PERMISSION_CREATE_BOT.Id
  1474  
  1475  	testCases := []struct {
  1476  		Name                          string
  1477  		ChannelModerationsPatch       []*model.ChannelModerationPatch
  1478  		PermissionsModeratedByPatch   map[string]*model.ChannelModeratedRoles
  1479  		RevertChannelModerationsPatch []*model.ChannelModerationPatch
  1480  		HigherScopedMemberPermissions []string
  1481  		HigherScopedGuestPermissions  []string
  1482  		ShouldError                   bool
  1483  		ShouldHaveNoChannelScheme     bool
  1484  	}{
  1485  		{
  1486  			Name: "Removing create posts from members role",
  1487  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1488  				{
  1489  					Name:  &createPosts,
  1490  					Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(false)},
  1491  				},
  1492  			},
  1493  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
  1494  				createPosts: {
  1495  					Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
  1496  				},
  1497  			},
  1498  			RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
  1499  				{
  1500  					Name:  &createPosts,
  1501  					Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(true)},
  1502  				},
  1503  			},
  1504  		},
  1505  		{
  1506  			Name: "Removing create reactions from members role",
  1507  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1508  				{
  1509  					Name:  &createReactions,
  1510  					Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(false)},
  1511  				},
  1512  			},
  1513  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
  1514  				createReactions: {
  1515  					Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
  1516  				},
  1517  			},
  1518  			RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
  1519  				{
  1520  					Name:  &createReactions,
  1521  					Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(true)},
  1522  				},
  1523  			},
  1524  		},
  1525  		{
  1526  			Name: "Removing channel mentions from members role",
  1527  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1528  				{
  1529  					Name:  &channelMentions,
  1530  					Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(false)},
  1531  				},
  1532  			},
  1533  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
  1534  				channelMentions: {
  1535  					Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
  1536  				},
  1537  			},
  1538  			RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
  1539  				{
  1540  					Name:  &channelMentions,
  1541  					Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(true)},
  1542  				},
  1543  			},
  1544  		},
  1545  		{
  1546  			Name: "Removing manage members from members role",
  1547  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1548  				{
  1549  					Name:  &manageMembers,
  1550  					Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(false)},
  1551  				},
  1552  			},
  1553  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
  1554  				manageMembers: {
  1555  					Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
  1556  				},
  1557  			},
  1558  			RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
  1559  				{
  1560  					Name:  &manageMembers,
  1561  					Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(true)},
  1562  				},
  1563  			},
  1564  		},
  1565  		{
  1566  			Name: "Removing create posts from guests role",
  1567  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1568  				{
  1569  					Name:  &createPosts,
  1570  					Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(false)},
  1571  				},
  1572  			},
  1573  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
  1574  				createPosts: {
  1575  					Guests: &model.ChannelModeratedRole{Value: false, Enabled: true},
  1576  				},
  1577  			},
  1578  			RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
  1579  				{
  1580  					Name:  &createPosts,
  1581  					Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(true)},
  1582  				},
  1583  			},
  1584  		},
  1585  		{
  1586  			Name: "Removing create reactions from guests role",
  1587  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1588  				{
  1589  					Name:  &createReactions,
  1590  					Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(false)},
  1591  				},
  1592  			},
  1593  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
  1594  				createReactions: {
  1595  					Guests: &model.ChannelModeratedRole{Value: false, Enabled: true},
  1596  				},
  1597  			},
  1598  			RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
  1599  				{
  1600  					Name:  &createReactions,
  1601  					Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(true)},
  1602  				},
  1603  			},
  1604  		},
  1605  		{
  1606  			Name: "Removing channel mentions from guests role",
  1607  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1608  				{
  1609  					Name:  &channelMentions,
  1610  					Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(false)},
  1611  				},
  1612  			},
  1613  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
  1614  				channelMentions: {
  1615  					Guests: &model.ChannelModeratedRole{Value: false, Enabled: true},
  1616  				},
  1617  			},
  1618  			RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
  1619  				{
  1620  					Name:  &channelMentions,
  1621  					Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(true)},
  1622  				},
  1623  			},
  1624  		},
  1625  		{
  1626  			Name: "Removing manage members from guests role should error",
  1627  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1628  				{
  1629  					Name:  &manageMembers,
  1630  					Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(false)},
  1631  				},
  1632  			},
  1633  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{},
  1634  			ShouldError:                 true,
  1635  		},
  1636  		{
  1637  			Name: "Removing a permission that is not channel moderated should error",
  1638  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1639  				{
  1640  					Name: &nonChannelModeratedPermission,
  1641  					Roles: &model.ChannelModeratedRolesPatch{
  1642  						Members: model.NewBool(false),
  1643  						Guests:  model.NewBool(false),
  1644  					},
  1645  				},
  1646  			},
  1647  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{},
  1648  			ShouldError:                 true,
  1649  		},
  1650  		{
  1651  			Name: "Error when adding a permission that is disabled in the parent member role",
  1652  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1653  				{
  1654  					Name: &createPosts,
  1655  					Roles: &model.ChannelModeratedRolesPatch{
  1656  						Members: model.NewBool(true),
  1657  						Guests:  model.NewBool(false),
  1658  					},
  1659  				},
  1660  			},
  1661  			PermissionsModeratedByPatch:   map[string]*model.ChannelModeratedRoles{},
  1662  			HigherScopedMemberPermissions: []string{},
  1663  			ShouldError:                   true,
  1664  		},
  1665  		{
  1666  			Name: "Error when adding a permission that is disabled in the parent guest role",
  1667  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1668  				{
  1669  					Name: &createPosts,
  1670  					Roles: &model.ChannelModeratedRolesPatch{
  1671  						Members: model.NewBool(false),
  1672  						Guests:  model.NewBool(true),
  1673  					},
  1674  				},
  1675  			},
  1676  			PermissionsModeratedByPatch:  map[string]*model.ChannelModeratedRoles{},
  1677  			HigherScopedGuestPermissions: []string{},
  1678  			ShouldError:                  true,
  1679  		},
  1680  		{
  1681  			Name: "Removing a permission from the member role that is disabled in the parent guest role",
  1682  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1683  				{
  1684  					Name: &createPosts,
  1685  					Roles: &model.ChannelModeratedRolesPatch{
  1686  						Members: model.NewBool(false),
  1687  					},
  1688  				},
  1689  			},
  1690  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
  1691  				createPosts: {
  1692  					Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
  1693  					Guests:  &model.ChannelModeratedRole{Value: false, Enabled: false},
  1694  				},
  1695  				createReactions: {
  1696  					Guests: &model.ChannelModeratedRole{Value: false, Enabled: false},
  1697  				},
  1698  				channelMentions: {
  1699  					Guests: &model.ChannelModeratedRole{Value: false, Enabled: false},
  1700  				},
  1701  			},
  1702  			HigherScopedGuestPermissions: []string{},
  1703  			ShouldError:                  false,
  1704  		},
  1705  		{
  1706  			Name: "Channel should have no scheme when all moderated permissions are equivalent to higher scoped role",
  1707  			ChannelModerationsPatch: []*model.ChannelModerationPatch{
  1708  				{
  1709  					Name: &createPosts,
  1710  					Roles: &model.ChannelModeratedRolesPatch{
  1711  						Members: model.NewBool(true),
  1712  						Guests:  model.NewBool(true),
  1713  					},
  1714  				},
  1715  				{
  1716  					Name: &createReactions,
  1717  					Roles: &model.ChannelModeratedRolesPatch{
  1718  						Members: model.NewBool(true),
  1719  						Guests:  model.NewBool(true),
  1720  					},
  1721  				},
  1722  				{
  1723  					Name: &channelMentions,
  1724  					Roles: &model.ChannelModeratedRolesPatch{
  1725  						Members: model.NewBool(true),
  1726  						Guests:  model.NewBool(true),
  1727  					},
  1728  				},
  1729  				{
  1730  					Name: &manageMembers,
  1731  					Roles: &model.ChannelModeratedRolesPatch{
  1732  						Members: model.NewBool(true),
  1733  					},
  1734  				},
  1735  			},
  1736  			PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{},
  1737  			ShouldHaveNoChannelScheme:   true,
  1738  		},
  1739  	}
  1740  
  1741  	for _, tc := range testCases {
  1742  		t.Run(tc.Name, func(t *testing.T) {
  1743  			higherScopedPermissionsOverriden := tc.HigherScopedMemberPermissions != nil || tc.HigherScopedGuestPermissions != nil
  1744  			// If the test case restricts higher scoped permissions.
  1745  			if higherScopedPermissionsOverriden {
  1746  				higherScopedGuestRoleName, higherScopedMemberRoleName, _, _ := th.App.GetTeamSchemeChannelRoles(channel.TeamId)
  1747  				if tc.HigherScopedMemberPermissions != nil {
  1748  					higherScopedMemberRole, err := th.App.GetRoleByName(higherScopedMemberRoleName)
  1749  					require.Nil(t, err)
  1750  					originalPermissions := higherScopedMemberRole.Permissions
  1751  
  1752  					th.App.PatchRole(higherScopedMemberRole, &model.RolePatch{Permissions: &tc.HigherScopedMemberPermissions})
  1753  					defer th.App.PatchRole(higherScopedMemberRole, &model.RolePatch{Permissions: &originalPermissions})
  1754  				}
  1755  
  1756  				if tc.HigherScopedGuestPermissions != nil {
  1757  					higherScopedGuestRole, err := th.App.GetRoleByName(higherScopedGuestRoleName)
  1758  					require.Nil(t, err)
  1759  					originalPermissions := higherScopedGuestRole.Permissions
  1760  
  1761  					th.App.PatchRole(higherScopedGuestRole, &model.RolePatch{Permissions: &tc.HigherScopedGuestPermissions})
  1762  					defer th.App.PatchRole(higherScopedGuestRole, &model.RolePatch{Permissions: &originalPermissions})
  1763  				}
  1764  			}
  1765  
  1766  			moderations, err := th.App.PatchChannelModerationsForChannel(channel, tc.ChannelModerationsPatch)
  1767  			if tc.ShouldError {
  1768  				require.Error(t, err)
  1769  				return
  1770  			}
  1771  			require.Nil(t, err)
  1772  
  1773  			updatedChannel, _ := th.App.GetChannel(channel.Id)
  1774  			if tc.ShouldHaveNoChannelScheme {
  1775  				require.Nil(t, updatedChannel.SchemeId)
  1776  			} else {
  1777  				require.NotNil(t, updatedChannel.SchemeId)
  1778  			}
  1779  
  1780  			for _, moderation := range moderations {
  1781  				// If the permission is not found in the expected modified permissions table then require it to be true
  1782  				if permission, found := tc.PermissionsModeratedByPatch[moderation.Name]; found && permission.Members != nil {
  1783  					require.Equal(t, moderation.Roles.Members.Value, permission.Members.Value)
  1784  					require.Equal(t, moderation.Roles.Members.Enabled, permission.Members.Enabled)
  1785  				} else {
  1786  					require.Equal(t, moderation.Roles.Members.Value, true)
  1787  					require.Equal(t, moderation.Roles.Members.Enabled, true)
  1788  				}
  1789  
  1790  				if permission, found := tc.PermissionsModeratedByPatch[moderation.Name]; found && permission.Guests != nil {
  1791  					require.Equal(t, moderation.Roles.Guests.Value, permission.Guests.Value)
  1792  					require.Equal(t, moderation.Roles.Guests.Enabled, permission.Guests.Enabled)
  1793  				} else if moderation.Name == manageMembers {
  1794  					require.Empty(t, moderation.Roles.Guests)
  1795  				} else {
  1796  					require.Equal(t, moderation.Roles.Guests.Value, true)
  1797  					require.Equal(t, moderation.Roles.Guests.Enabled, true)
  1798  				}
  1799  			}
  1800  
  1801  			if tc.RevertChannelModerationsPatch != nil {
  1802  				th.App.PatchChannelModerationsForChannel(channel, tc.RevertChannelModerationsPatch)
  1803  			}
  1804  		})
  1805  	}
  1806  
  1807  	t.Run("Handles concurrent patch requests gracefully", func(t *testing.T) {
  1808  		addCreatePosts := []*model.ChannelModerationPatch{
  1809  			{
  1810  				Name: &createPosts,
  1811  				Roles: &model.ChannelModeratedRolesPatch{
  1812  					Members: model.NewBool(false),
  1813  					Guests:  model.NewBool(false),
  1814  				},
  1815  			},
  1816  		}
  1817  		removeCreatePosts := []*model.ChannelModerationPatch{
  1818  			{
  1819  				Name: &createPosts,
  1820  				Roles: &model.ChannelModeratedRolesPatch{
  1821  					Members: model.NewBool(false),
  1822  					Guests:  model.NewBool(false),
  1823  				},
  1824  			},
  1825  		}
  1826  
  1827  		wg := sync.WaitGroup{}
  1828  		wg.Add(20)
  1829  		for i := 0; i < 10; i++ {
  1830  			go func() {
  1831  				th.App.PatchChannelModerationsForChannel(channel, addCreatePosts)
  1832  				th.App.PatchChannelModerationsForChannel(channel, removeCreatePosts)
  1833  				wg.Done()
  1834  			}()
  1835  		}
  1836  		for i := 0; i < 10; i++ {
  1837  			go func() {
  1838  				th.App.PatchChannelModerationsForChannel(channel, addCreatePosts)
  1839  				th.App.PatchChannelModerationsForChannel(channel, removeCreatePosts)
  1840  				wg.Done()
  1841  			}()
  1842  		}
  1843  		wg.Wait()
  1844  
  1845  		higherScopedGuestRoleName, higherScopedMemberRoleName, _, _ := th.App.GetTeamSchemeChannelRoles(channel.TeamId)
  1846  		higherScopedMemberRole, _ := th.App.GetRoleByName(higherScopedMemberRoleName)
  1847  		higherScopedGuestRole, _ := th.App.GetRoleByName(higherScopedGuestRoleName)
  1848  		assert.Contains(t, higherScopedMemberRole.Permissions, createPosts)
  1849  		assert.Contains(t, higherScopedGuestRole.Permissions, createPosts)
  1850  	})
  1851  
  1852  }
  1853  
  1854  // TestMarkChannelsAsViewedPanic verifies that returning an error from a.GetUser
  1855  // does not cause a panic.
  1856  func TestMarkChannelsAsViewedPanic(t *testing.T) {
  1857  	th := SetupWithStoreMock(t)
  1858  	defer th.TearDown()
  1859  
  1860  	mockStore := th.App.Srv().Store.(*mocks.Store)
  1861  	mockUserStore := mocks.UserStore{}
  1862  	mockUserStore.On("Get", "userID").Return(nil, model.NewAppError("SqlUserStore.Get", "store.sql_user.get.app_error", nil, "user_id=userID", http.StatusInternalServerError))
  1863  	mockChannelStore := mocks.ChannelStore{}
  1864  	mockChannelStore.On("Get", "channelID", true).Return(&model.Channel{}, nil)
  1865  	mockChannelStore.On("GetMember", "channelID", "userID").Return(&model.ChannelMember{
  1866  		NotifyProps: model.StringMap{
  1867  			model.PUSH_NOTIFY_PROP: model.CHANNEL_NOTIFY_DEFAULT,
  1868  		}}, nil)
  1869  	times := map[string]int64{
  1870  		"userID": 1,
  1871  	}
  1872  	mockChannelStore.On("UpdateLastViewedAt", []string{"channelID"}, "userID").Return(times, nil)
  1873  	mockStore.On("User").Return(&mockUserStore)
  1874  	mockStore.On("Channel").Return(&mockChannelStore)
  1875  
  1876  	_, err := th.App.MarkChannelsAsViewed([]string{"channelID"}, "userID", th.App.Session().Id)
  1877  	require.Nil(t, err)
  1878  }
  1879  
  1880  func TestClearChannelMembersCache(t *testing.T) {
  1881  	th := SetupWithStoreMock(t)
  1882  	defer th.TearDown()
  1883  
  1884  	mockStore := th.App.Srv().Store.(*mocks.Store)
  1885  	mockChannelStore := mocks.ChannelStore{}
  1886  	cms := model.ChannelMembers{}
  1887  	for i := 0; i < 200; i++ {
  1888  		cms = append(cms, model.ChannelMember{
  1889  			ChannelId: "1",
  1890  		})
  1891  	}
  1892  	mockChannelStore.On("GetMembers", "channelID", 0, 100).Return(&cms, nil)
  1893  	mockChannelStore.On("GetMembers", "channelID", 100, 100).Return(&model.ChannelMembers{
  1894  		model.ChannelMember{
  1895  			ChannelId: "1",
  1896  		}}, nil)
  1897  	mockStore.On("Channel").Return(&mockChannelStore)
  1898  
  1899  	th.App.ClearChannelMembersCache("channelID")
  1900  }
  1901  
  1902  func TestSidebarCategory(t *testing.T) {
  1903  	th := Setup(t).InitBasic()
  1904  	defer th.TearDown()
  1905  
  1906  	basicChannel2 := th.CreateChannel(th.BasicTeam)
  1907  	defer th.App.PermanentDeleteChannel(basicChannel2)
  1908  	user := th.CreateUser()
  1909  	defer th.App.Srv().Store.User().PermanentDelete(user.Id)
  1910  	th.LinkUserToTeam(user, th.BasicTeam)
  1911  	th.AddUserToChannel(user, basicChannel2)
  1912  
  1913  	var createdCategory *model.SidebarCategoryWithChannels
  1914  	t.Run("CreateSidebarCategory", func(t *testing.T) {
  1915  		catData := model.SidebarCategoryWithChannels{
  1916  			SidebarCategory: model.SidebarCategory{
  1917  				DisplayName: "TEST",
  1918  			},
  1919  			Channels: []string{th.BasicChannel.Id, basicChannel2.Id, basicChannel2.Id},
  1920  		}
  1921  		_, err := th.App.CreateSidebarCategory(user.Id, th.BasicTeam.Id, &catData)
  1922  		require.NotNil(t, err, "Should return error due to duplicate IDs")
  1923  		catData.Channels = []string{th.BasicChannel.Id, basicChannel2.Id}
  1924  		cat, err := th.App.CreateSidebarCategory(user.Id, th.BasicTeam.Id, &catData)
  1925  		require.Nil(t, err, "Expected no error")
  1926  		require.NotNil(t, cat, "Expected category object, got nil")
  1927  		createdCategory = cat
  1928  	})
  1929  
  1930  	t.Run("UpdateSidebarCategories", func(t *testing.T) {
  1931  		require.NotNil(t, createdCategory)
  1932  		createdCategory.Channels = []string{th.BasicChannel.Id}
  1933  		updatedCat, err := th.App.UpdateSidebarCategories(user.Id, th.BasicTeam.Id, []*model.SidebarCategoryWithChannels{createdCategory})
  1934  		require.Nil(t, err, "Expected no error")
  1935  		require.NotNil(t, updatedCat, "Expected category object, got nil")
  1936  		require.Len(t, updatedCat, 1)
  1937  		require.Len(t, updatedCat[0].Channels, 1)
  1938  		require.Equal(t, updatedCat[0].Channels[0], th.BasicChannel.Id)
  1939  	})
  1940  
  1941  	t.Run("UpdateSidebarCategoryOrder", func(t *testing.T) {
  1942  		err := th.App.UpdateSidebarCategoryOrder(user.Id, th.BasicTeam.Id, []string{th.BasicChannel.Id, basicChannel2.Id})
  1943  		require.NotNil(t, err, "Should return error due to invalid order")
  1944  
  1945  		actualOrder, err := th.App.GetSidebarCategoryOrder(user.Id, th.BasicTeam.Id)
  1946  		require.Nil(t, err, "Should fetch order successfully")
  1947  
  1948  		actualOrder[2], actualOrder[3] = actualOrder[3], actualOrder[2]
  1949  		err = th.App.UpdateSidebarCategoryOrder(user.Id, th.BasicTeam.Id, actualOrder)
  1950  		require.Nil(t, err, "Should update order successfully")
  1951  
  1952  		actualOrder[2] = "asd"
  1953  		err = th.App.UpdateSidebarCategoryOrder(user.Id, th.BasicTeam.Id, actualOrder)
  1954  		require.NotNil(t, err, "Should return error due to invalid id")
  1955  	})
  1956  
  1957  	t.Run("GetSidebarCategoryOrder", func(t *testing.T) {
  1958  		catOrder, err := th.App.GetSidebarCategoryOrder(user.Id, th.BasicTeam.Id)
  1959  		require.Nil(t, err, "Expected no error")
  1960  		require.Len(t, catOrder, 4)
  1961  		require.Equal(t, catOrder[1], createdCategory.Id, "the newly created category should be after favorites")
  1962  	})
  1963  }
  1964  
  1965  func TestGetSidebarCategories(t *testing.T) {
  1966  	t.Run("should return the sidebar categories for the given user/team", func(t *testing.T) {
  1967  		th := Setup(t).InitBasic()
  1968  		defer th.TearDown()
  1969  
  1970  		_, err := th.App.CreateSidebarCategory(th.BasicUser.Id, th.BasicTeam.Id, &model.SidebarCategoryWithChannels{
  1971  			SidebarCategory: model.SidebarCategory{
  1972  				UserId:      th.BasicUser.Id,
  1973  				TeamId:      th.BasicTeam.Id,
  1974  				DisplayName: "new category",
  1975  			},
  1976  		})
  1977  		require.Nil(t, err)
  1978  
  1979  		categories, err := th.App.GetSidebarCategories(th.BasicUser.Id, th.BasicTeam.Id)
  1980  		assert.Nil(t, err)
  1981  		assert.Len(t, categories.Categories, 4)
  1982  	})
  1983  
  1984  	t.Run("should create the initial categories even if migration hasn't ran yet", func(t *testing.T) {
  1985  		th := Setup(t).InitBasic()
  1986  		defer th.TearDown()
  1987  
  1988  		// Manually add the user to the team without going through the app layer to simulate a pre-existing user/team
  1989  		// relationship that hasn't been migrated yet
  1990  		team := th.CreateTeam()
  1991  		_, err := th.App.Srv().Store.Team().SaveMember(&model.TeamMember{
  1992  			TeamId:     team.Id,
  1993  			UserId:     th.BasicUser.Id,
  1994  			SchemeUser: true,
  1995  		}, 100)
  1996  		require.Nil(t, err)
  1997  
  1998  		categories, err := th.App.GetSidebarCategories(th.BasicUser.Id, team.Id)
  1999  		assert.Nil(t, err)
  2000  		assert.Len(t, categories.Categories, 3)
  2001  	})
  2002  }