github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/store/storetest/channel_store_categories.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package storetest
     5  
     6  import (
     7  	"database/sql"
     8  	"errors"
     9  	"sync"
    10  	"testing"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"github.com/mattermost/mattermost-server/v5/model"
    16  	"github.com/mattermost/mattermost-server/v5/store"
    17  )
    18  
    19  func TestChannelStoreCategories(t *testing.T, ss store.Store, s SqlStore) {
    20  	t.Run("CreateInitialSidebarCategories", func(t *testing.T) { testCreateInitialSidebarCategories(t, ss) })
    21  	t.Run("CreateSidebarCategory", func(t *testing.T) { testCreateSidebarCategory(t, ss) })
    22  	t.Run("GetSidebarCategory", func(t *testing.T) { testGetSidebarCategory(t, ss, s) })
    23  	t.Run("GetSidebarCategories", func(t *testing.T) { testGetSidebarCategories(t, ss) })
    24  	t.Run("UpdateSidebarCategories", func(t *testing.T) { testUpdateSidebarCategories(t, ss) })
    25  	t.Run("ClearSidebarOnTeamLeave", func(t *testing.T) { testClearSidebarOnTeamLeave(t, ss, s) })
    26  	t.Run("UpdateSidebarCategories", func(t *testing.T) { testUpdateSidebarCategories(t, ss) })
    27  	t.Run("DeleteSidebarCategory", func(t *testing.T) { testDeleteSidebarCategory(t, ss, s) })
    28  	t.Run("UpdateSidebarChannelsByPreferences", func(t *testing.T) { testUpdateSidebarChannelsByPreferences(t, ss) })
    29  }
    30  
    31  func testCreateInitialSidebarCategories(t *testing.T, ss store.Store) {
    32  	t.Run("should create initial favorites/channels/DMs categories", func(t *testing.T) {
    33  		userId := model.NewId()
    34  		teamId := model.NewId()
    35  
    36  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
    37  		assert.NoError(t, nErr)
    38  
    39  		res, err := ss.Channel().GetSidebarCategories(userId, teamId)
    40  		assert.NoError(t, err)
    41  		assert.Len(t, res.Categories, 3)
    42  		assert.Equal(t, model.SidebarCategoryFavorites, res.Categories[0].Type)
    43  		assert.Equal(t, model.SidebarCategoryChannels, res.Categories[1].Type)
    44  		assert.Equal(t, model.SidebarCategoryDirectMessages, res.Categories[2].Type)
    45  	})
    46  
    47  	t.Run("should create initial favorites/channels/DMs categories for multiple users", func(t *testing.T) {
    48  		userId := model.NewId()
    49  		teamId := model.NewId()
    50  
    51  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
    52  		require.NoError(t, nErr)
    53  
    54  		userId2 := model.NewId()
    55  
    56  		nErr = ss.Channel().CreateInitialSidebarCategories(userId2, teamId)
    57  		assert.NoError(t, nErr)
    58  
    59  		res, err := ss.Channel().GetSidebarCategories(userId2, teamId)
    60  		assert.NoError(t, err)
    61  		assert.Len(t, res.Categories, 3)
    62  		assert.Equal(t, model.SidebarCategoryFavorites, res.Categories[0].Type)
    63  		assert.Equal(t, model.SidebarCategoryChannels, res.Categories[1].Type)
    64  		assert.Equal(t, model.SidebarCategoryDirectMessages, res.Categories[2].Type)
    65  	})
    66  
    67  	t.Run("should create initial favorites/channels/DMs categories on different teams", func(t *testing.T) {
    68  		userId := model.NewId()
    69  		teamId := model.NewId()
    70  
    71  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
    72  		require.NoError(t, nErr)
    73  
    74  		teamId2 := model.NewId()
    75  
    76  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId2)
    77  		assert.NoError(t, nErr)
    78  
    79  		res, err := ss.Channel().GetSidebarCategories(userId, teamId2)
    80  		assert.NoError(t, err)
    81  		assert.Len(t, res.Categories, 3)
    82  		assert.Equal(t, model.SidebarCategoryFavorites, res.Categories[0].Type)
    83  		assert.Equal(t, model.SidebarCategoryChannels, res.Categories[1].Type)
    84  		assert.Equal(t, model.SidebarCategoryDirectMessages, res.Categories[2].Type)
    85  	})
    86  
    87  	t.Run("shouldn't create additional categories when ones already exist", func(t *testing.T) {
    88  		userId := model.NewId()
    89  		teamId := model.NewId()
    90  
    91  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
    92  		require.NoError(t, nErr)
    93  
    94  		initialCategories, err := ss.Channel().GetSidebarCategories(userId, teamId)
    95  		require.NoError(t, err)
    96  
    97  		// Calling CreateInitialSidebarCategories a second time shouldn't create any new categories
    98  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId)
    99  		assert.NoError(t, nErr)
   100  
   101  		res, err := ss.Channel().GetSidebarCategories(userId, teamId)
   102  		assert.NoError(t, err)
   103  		assert.Equal(t, initialCategories.Categories, res.Categories)
   104  	})
   105  
   106  	t.Run("shouldn't create additional categories when ones already exist even when ran simultaneously", func(t *testing.T) {
   107  		userId := model.NewId()
   108  		teamId := model.NewId()
   109  
   110  		var wg sync.WaitGroup
   111  
   112  		for i := 0; i < 10; i++ {
   113  			wg.Add(1)
   114  
   115  			go func() {
   116  				defer wg.Done()
   117  
   118  				_ = ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   119  			}()
   120  		}
   121  
   122  		wg.Wait()
   123  
   124  		res, err := ss.Channel().GetSidebarCategories(userId, teamId)
   125  		assert.NoError(t, err)
   126  		assert.Len(t, res.Categories, 3)
   127  	})
   128  
   129  	t.Run("should populate the Favorites category with regular channels", func(t *testing.T) {
   130  		userId := model.NewId()
   131  		teamId := model.NewId()
   132  
   133  		// Set up two channels, one favorited and one not
   134  		channel1, nErr := ss.Channel().Save(&model.Channel{
   135  			TeamId: teamId,
   136  			Type:   model.CHANNEL_OPEN,
   137  			Name:   "channel1",
   138  		}, 1000)
   139  		require.NoError(t, nErr)
   140  		_, err := ss.Channel().SaveMember(&model.ChannelMember{
   141  			ChannelId:   channel1.Id,
   142  			UserId:      userId,
   143  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   144  		})
   145  		require.NoError(t, err)
   146  
   147  		channel2, nErr := ss.Channel().Save(&model.Channel{
   148  			TeamId: teamId,
   149  			Type:   model.CHANNEL_OPEN,
   150  			Name:   "channel2",
   151  		}, 1000)
   152  		require.NoError(t, nErr)
   153  		_, err = ss.Channel().SaveMember(&model.ChannelMember{
   154  			ChannelId:   channel2.Id,
   155  			UserId:      userId,
   156  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   157  		})
   158  		require.NoError(t, err)
   159  
   160  		nErr = ss.Preference().Save(&model.Preferences{
   161  			{
   162  				UserId:   userId,
   163  				Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL,
   164  				Name:     channel1.Id,
   165  				Value:    "true",
   166  			},
   167  		})
   168  		require.NoError(t, nErr)
   169  
   170  		// Create the categories
   171  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   172  		require.NoError(t, nErr)
   173  
   174  		// Get and check the categories for channels
   175  		categories, nErr := ss.Channel().GetSidebarCategories(userId, teamId)
   176  		require.NoError(t, nErr)
   177  		require.Len(t, categories.Categories, 3)
   178  		assert.Equal(t, model.SidebarCategoryFavorites, categories.Categories[0].Type)
   179  		assert.Equal(t, []string{channel1.Id}, categories.Categories[0].Channels)
   180  		assert.Equal(t, model.SidebarCategoryChannels, categories.Categories[1].Type)
   181  		assert.Equal(t, []string{channel2.Id}, categories.Categories[1].Channels)
   182  	})
   183  
   184  	t.Run("should populate the Favorites category in alphabetical order", func(t *testing.T) {
   185  		userId := model.NewId()
   186  		teamId := model.NewId()
   187  
   188  		// Set up two channels
   189  		channel1, nErr := ss.Channel().Save(&model.Channel{
   190  			TeamId:      teamId,
   191  			Type:        model.CHANNEL_OPEN,
   192  			Name:        "channel1",
   193  			DisplayName: "zebra",
   194  		}, 1000)
   195  		require.NoError(t, nErr)
   196  		_, err := ss.Channel().SaveMember(&model.ChannelMember{
   197  			ChannelId:   channel1.Id,
   198  			UserId:      userId,
   199  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   200  		})
   201  		require.NoError(t, err)
   202  
   203  		channel2, nErr := ss.Channel().Save(&model.Channel{
   204  			TeamId:      teamId,
   205  			Type:        model.CHANNEL_OPEN,
   206  			Name:        "channel2",
   207  			DisplayName: "aardvark",
   208  		}, 1000)
   209  		require.NoError(t, nErr)
   210  		_, err = ss.Channel().SaveMember(&model.ChannelMember{
   211  			ChannelId:   channel2.Id,
   212  			UserId:      userId,
   213  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   214  		})
   215  		require.NoError(t, err)
   216  
   217  		nErr = ss.Preference().Save(&model.Preferences{
   218  			{
   219  				UserId:   userId,
   220  				Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL,
   221  				Name:     channel1.Id,
   222  				Value:    "true",
   223  			},
   224  			{
   225  				UserId:   userId,
   226  				Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL,
   227  				Name:     channel2.Id,
   228  				Value:    "true",
   229  			},
   230  		})
   231  		require.NoError(t, nErr)
   232  
   233  		// Create the categories
   234  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   235  		require.NoError(t, nErr)
   236  
   237  		// Get and check the categories for channels
   238  		categories, nErr := ss.Channel().GetSidebarCategories(userId, teamId)
   239  		require.NoError(t, nErr)
   240  		require.Len(t, categories.Categories, 3)
   241  		assert.Equal(t, model.SidebarCategoryFavorites, categories.Categories[0].Type)
   242  		assert.Equal(t, []string{channel2.Id, channel1.Id}, categories.Categories[0].Channels)
   243  	})
   244  
   245  	t.Run("should populate the Favorites category with DMs and GMs", func(t *testing.T) {
   246  		userId := model.NewId()
   247  		teamId := model.NewId()
   248  
   249  		otherUserId1 := model.NewId()
   250  		otherUserId2 := model.NewId()
   251  
   252  		// Set up two direct channels, one favorited and one not
   253  		dmChannel1, err := ss.Channel().SaveDirectChannel(
   254  			&model.Channel{
   255  				Name: model.GetDMNameFromIds(userId, otherUserId1),
   256  				Type: model.CHANNEL_DIRECT,
   257  			},
   258  			&model.ChannelMember{
   259  				UserId:      userId,
   260  				NotifyProps: model.GetDefaultChannelNotifyProps(),
   261  			},
   262  			&model.ChannelMember{
   263  				UserId:      otherUserId1,
   264  				NotifyProps: model.GetDefaultChannelNotifyProps(),
   265  			},
   266  		)
   267  		require.NoError(t, err)
   268  
   269  		dmChannel2, err := ss.Channel().SaveDirectChannel(
   270  			&model.Channel{
   271  				Name: model.GetDMNameFromIds(userId, otherUserId2),
   272  				Type: model.CHANNEL_DIRECT,
   273  			},
   274  			&model.ChannelMember{
   275  				UserId:      userId,
   276  				NotifyProps: model.GetDefaultChannelNotifyProps(),
   277  			},
   278  			&model.ChannelMember{
   279  				UserId:      otherUserId2,
   280  				NotifyProps: model.GetDefaultChannelNotifyProps(),
   281  			},
   282  		)
   283  		require.NoError(t, err)
   284  
   285  		err = ss.Preference().Save(&model.Preferences{
   286  			{
   287  				UserId:   userId,
   288  				Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL,
   289  				Name:     dmChannel1.Id,
   290  				Value:    "true",
   291  			},
   292  		})
   293  		require.NoError(t, err)
   294  
   295  		// Create the categories
   296  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   297  		require.NoError(t, nErr)
   298  
   299  		// Get and check the categories for channels
   300  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   301  		require.NoError(t, err)
   302  		require.Len(t, categories.Categories, 3)
   303  		assert.Equal(t, model.SidebarCategoryFavorites, categories.Categories[0].Type)
   304  		assert.Equal(t, []string{dmChannel1.Id}, categories.Categories[0].Channels)
   305  		assert.Equal(t, model.SidebarCategoryDirectMessages, categories.Categories[2].Type)
   306  		assert.Equal(t, []string{dmChannel2.Id}, categories.Categories[2].Channels)
   307  	})
   308  
   309  	t.Run("should not populate the Favorites category with channels from other teams", func(t *testing.T) {
   310  		userId := model.NewId()
   311  		teamId := model.NewId()
   312  		teamId2 := model.NewId()
   313  
   314  		// Set up a channel on another team and favorite it
   315  		channel1, nErr := ss.Channel().Save(&model.Channel{
   316  			TeamId: teamId2,
   317  			Type:   model.CHANNEL_OPEN,
   318  			Name:   "channel1",
   319  		}, 1000)
   320  		require.NoError(t, nErr)
   321  		_, err := ss.Channel().SaveMember(&model.ChannelMember{
   322  			ChannelId:   channel1.Id,
   323  			UserId:      userId,
   324  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   325  		})
   326  		require.NoError(t, err)
   327  
   328  		nErr = ss.Preference().Save(&model.Preferences{
   329  			{
   330  				UserId:   userId,
   331  				Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL,
   332  				Name:     channel1.Id,
   333  				Value:    "true",
   334  			},
   335  		})
   336  		require.NoError(t, nErr)
   337  
   338  		// Create the categories
   339  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   340  		require.NoError(t, nErr)
   341  
   342  		// Get and check the categories for channels
   343  		categories, nErr := ss.Channel().GetSidebarCategories(userId, teamId)
   344  		require.NoError(t, nErr)
   345  		require.Len(t, categories.Categories, 3)
   346  		assert.Equal(t, model.SidebarCategoryFavorites, categories.Categories[0].Type)
   347  		assert.Equal(t, []string{}, categories.Categories[0].Channels)
   348  		assert.Equal(t, model.SidebarCategoryChannels, categories.Categories[1].Type)
   349  		assert.Equal(t, []string{}, categories.Categories[1].Channels)
   350  	})
   351  }
   352  
   353  func testCreateSidebarCategory(t *testing.T, ss store.Store) {
   354  	t.Run("should place the new category second if Favorites comes first", func(t *testing.T) {
   355  		userId := model.NewId()
   356  		teamId := model.NewId()
   357  
   358  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   359  		require.NoError(t, nErr)
   360  
   361  		// Create the category
   362  		created, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
   363  			SidebarCategory: model.SidebarCategory{
   364  				DisplayName: model.NewId(),
   365  			},
   366  		})
   367  		require.NoError(t, err)
   368  
   369  		// Confirm that it comes second
   370  		res, err := ss.Channel().GetSidebarCategories(userId, teamId)
   371  		require.NoError(t, err)
   372  		require.Len(t, res.Categories, 4)
   373  		assert.Equal(t, model.SidebarCategoryFavorites, res.Categories[0].Type)
   374  		assert.Equal(t, model.SidebarCategoryCustom, res.Categories[1].Type)
   375  		assert.Equal(t, created.Id, res.Categories[1].Id)
   376  	})
   377  
   378  	t.Run("should place the new category first if Favorites is not first", func(t *testing.T) {
   379  		userId := model.NewId()
   380  		teamId := model.NewId()
   381  
   382  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   383  		require.NoError(t, nErr)
   384  
   385  		// Re-arrange the categories so that Favorites comes last
   386  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   387  		require.NoError(t, err)
   388  		require.Len(t, categories.Categories, 3)
   389  		require.Equal(t, model.SidebarCategoryFavorites, categories.Categories[0].Type)
   390  
   391  		err = ss.Channel().UpdateSidebarCategoryOrder(userId, teamId, []string{
   392  			categories.Categories[1].Id,
   393  			categories.Categories[2].Id,
   394  			categories.Categories[0].Id,
   395  		})
   396  		require.NoError(t, err)
   397  
   398  		// Create the category
   399  		created, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
   400  			SidebarCategory: model.SidebarCategory{
   401  				DisplayName: model.NewId(),
   402  			},
   403  		})
   404  		require.NoError(t, err)
   405  
   406  		// Confirm that it comes first
   407  		res, err := ss.Channel().GetSidebarCategories(userId, teamId)
   408  		require.NoError(t, err)
   409  		require.Len(t, res.Categories, 4)
   410  		assert.Equal(t, model.SidebarCategoryCustom, res.Categories[0].Type)
   411  		assert.Equal(t, created.Id, res.Categories[0].Id)
   412  	})
   413  
   414  	t.Run("should create the category with its channels", func(t *testing.T) {
   415  		userId := model.NewId()
   416  		teamId := model.NewId()
   417  
   418  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   419  		require.NoError(t, nErr)
   420  
   421  		// Create some channels
   422  		channel1, err := ss.Channel().Save(&model.Channel{
   423  			Type:   model.CHANNEL_OPEN,
   424  			TeamId: teamId,
   425  			Name:   model.NewId(),
   426  		}, 100)
   427  		require.NoError(t, err)
   428  		channel2, err := ss.Channel().Save(&model.Channel{
   429  			Type:   model.CHANNEL_OPEN,
   430  			TeamId: teamId,
   431  			Name:   model.NewId(),
   432  		}, 100)
   433  		require.NoError(t, err)
   434  
   435  		// Create the category
   436  		created, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
   437  			SidebarCategory: model.SidebarCategory{
   438  				DisplayName: model.NewId(),
   439  			},
   440  			Channels: []string{channel2.Id, channel1.Id},
   441  		})
   442  		require.NoError(t, err)
   443  		assert.Equal(t, []string{channel2.Id, channel1.Id}, created.Channels)
   444  
   445  		// Get the channel again to ensure that the SidebarChannels were saved correctly
   446  		res, err := ss.Channel().GetSidebarCategory(created.Id)
   447  		require.NoError(t, err)
   448  		assert.Equal(t, []string{channel2.Id, channel1.Id}, res.Channels)
   449  	})
   450  
   451  	t.Run("should remove any channels from their previous categories", func(t *testing.T) {
   452  		userId := model.NewId()
   453  		teamId := model.NewId()
   454  
   455  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   456  		require.NoError(t, nErr)
   457  
   458  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   459  		require.NoError(t, err)
   460  		require.Len(t, categories.Categories, 3)
   461  
   462  		favoritesCategory := categories.Categories[0]
   463  		require.Equal(t, model.SidebarCategoryFavorites, favoritesCategory.Type)
   464  		channelsCategory := categories.Categories[1]
   465  		require.Equal(t, model.SidebarCategoryChannels, channelsCategory.Type)
   466  
   467  		// Create some channels
   468  		channel1, nErr := ss.Channel().Save(&model.Channel{
   469  			Type:   model.CHANNEL_OPEN,
   470  			TeamId: teamId,
   471  			Name:   model.NewId(),
   472  		}, 100)
   473  		require.NoError(t, nErr)
   474  		channel2, nErr := ss.Channel().Save(&model.Channel{
   475  			Type:   model.CHANNEL_OPEN,
   476  			TeamId: teamId,
   477  			Name:   model.NewId(),
   478  		}, 100)
   479  		require.NoError(t, nErr)
   480  
   481  		// Assign them to categories
   482  		favoritesCategory.Channels = []string{channel1.Id}
   483  		channelsCategory.Channels = []string{channel2.Id}
   484  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
   485  			favoritesCategory,
   486  			channelsCategory,
   487  		})
   488  		require.NoError(t, err)
   489  
   490  		// Create the category
   491  		created, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
   492  			SidebarCategory: model.SidebarCategory{
   493  				DisplayName: model.NewId(),
   494  			},
   495  			Channels: []string{channel2.Id, channel1.Id},
   496  		})
   497  		require.NoError(t, err)
   498  		assert.Equal(t, []string{channel2.Id, channel1.Id}, created.Channels)
   499  
   500  		// Confirm that the channels were removed from their original categories
   501  		res, err := ss.Channel().GetSidebarCategory(favoritesCategory.Id)
   502  		require.NoError(t, err)
   503  		assert.Equal(t, []string{}, res.Channels)
   504  
   505  		res, err = ss.Channel().GetSidebarCategory(channelsCategory.Id)
   506  		require.NoError(t, err)
   507  		assert.Equal(t, []string{}, res.Channels)
   508  	})
   509  }
   510  
   511  func testGetSidebarCategory(t *testing.T, ss store.Store, s SqlStore) {
   512  	t.Run("should return a custom category with its Channels field set", func(t *testing.T) {
   513  		userId := model.NewId()
   514  		teamId := model.NewId()
   515  
   516  		channelId1 := model.NewId()
   517  		channelId2 := model.NewId()
   518  		channelId3 := model.NewId()
   519  
   520  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   521  		require.NoError(t, nErr)
   522  
   523  		// Create a category and assign some channels to it
   524  		created, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
   525  			SidebarCategory: model.SidebarCategory{
   526  				UserId:      userId,
   527  				TeamId:      teamId,
   528  				DisplayName: model.NewId(),
   529  			},
   530  			Channels: []string{channelId1, channelId2, channelId3},
   531  		})
   532  		require.NoError(t, err)
   533  		require.NotNil(t, created)
   534  
   535  		// Ensure that they're returned in order
   536  		res, err := ss.Channel().GetSidebarCategory(created.Id)
   537  		assert.NoError(t, err)
   538  		assert.Equal(t, created.Id, res.Id)
   539  		assert.Equal(t, model.SidebarCategoryCustom, res.Type)
   540  		assert.Equal(t, created.DisplayName, res.DisplayName)
   541  		assert.Equal(t, []string{channelId1, channelId2, channelId3}, res.Channels)
   542  	})
   543  
   544  	t.Run("should return any orphaned channels with the Channels category", func(t *testing.T) {
   545  		userId := model.NewId()
   546  		teamId := model.NewId()
   547  
   548  		// Create the initial categories and find the channels category
   549  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   550  		require.NoError(t, nErr)
   551  
   552  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   553  		require.NoError(t, err)
   554  
   555  		channelsCategory := categories.Categories[1]
   556  		require.Equal(t, model.SidebarCategoryChannels, channelsCategory.Type)
   557  
   558  		// Join some channels
   559  		channel1, nErr := ss.Channel().Save(&model.Channel{
   560  			Name:        "channel1",
   561  			DisplayName: "DEF",
   562  			TeamId:      teamId,
   563  			Type:        model.CHANNEL_PRIVATE,
   564  		}, 10)
   565  		require.NoError(t, nErr)
   566  		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
   567  			UserId:      userId,
   568  			ChannelId:   channel1.Id,
   569  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   570  		})
   571  		require.NoError(t, nErr)
   572  
   573  		channel2, nErr := ss.Channel().Save(&model.Channel{
   574  			Name:        "channel2",
   575  			DisplayName: "ABC",
   576  			TeamId:      teamId,
   577  			Type:        model.CHANNEL_OPEN,
   578  		}, 10)
   579  		require.NoError(t, nErr)
   580  		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
   581  			UserId:      userId,
   582  			ChannelId:   channel2.Id,
   583  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   584  		})
   585  		require.NoError(t, nErr)
   586  
   587  		// Confirm that they're not in the Channels category in the DB
   588  		count, countErr := s.GetMaster().SelectInt(`
   589  			SELECT
   590  				COUNT(*)
   591  			FROM
   592  				SidebarChannels
   593  			WHERE
   594  				CategoryId = :CategoryId`, map[string]interface{}{"CategoryId": channelsCategory.Id})
   595  		require.NoError(t, countErr)
   596  		assert.Equal(t, int64(0), count)
   597  
   598  		// Ensure that the Channels are returned in alphabetical order
   599  		res, err := ss.Channel().GetSidebarCategory(channelsCategory.Id)
   600  		assert.NoError(t, err)
   601  		assert.Equal(t, channelsCategory.Id, res.Id)
   602  		assert.Equal(t, model.SidebarCategoryChannels, channelsCategory.Type)
   603  		assert.Equal(t, []string{channel2.Id, channel1.Id}, res.Channels)
   604  	})
   605  
   606  	t.Run("shouldn't return orphaned channels on another team with the Channels category", func(t *testing.T) {
   607  		userId := model.NewId()
   608  		teamId := model.NewId()
   609  
   610  		// Create the initial categories and find the channels category
   611  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   612  		require.NoError(t, nErr)
   613  
   614  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   615  		require.NoError(t, err)
   616  		require.Equal(t, model.SidebarCategoryChannels, categories.Categories[1].Type)
   617  
   618  		channelsCategory := categories.Categories[1]
   619  
   620  		// Join a channel on another team
   621  		channel1, nErr := ss.Channel().Save(&model.Channel{
   622  			Name:   "abc",
   623  			TeamId: model.NewId(),
   624  			Type:   model.CHANNEL_OPEN,
   625  		}, 10)
   626  		require.NoError(t, nErr)
   627  
   628  		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
   629  			UserId:      userId,
   630  			ChannelId:   channel1.Id,
   631  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   632  		})
   633  		require.NoError(t, nErr)
   634  
   635  		// Ensure that no channels are returned
   636  		res, err := ss.Channel().GetSidebarCategory(channelsCategory.Id)
   637  		assert.NoError(t, err)
   638  		assert.Equal(t, channelsCategory.Id, res.Id)
   639  		assert.Equal(t, model.SidebarCategoryChannels, channelsCategory.Type)
   640  		assert.Len(t, res.Channels, 0)
   641  	})
   642  
   643  	t.Run("shouldn't return non-orphaned channels with the Channels category", func(t *testing.T) {
   644  		userId := model.NewId()
   645  		teamId := model.NewId()
   646  
   647  		// Create the initial categories and find the channels category
   648  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   649  		require.NoError(t, nErr)
   650  
   651  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   652  		require.NoError(t, err)
   653  
   654  		favoritesCategory := categories.Categories[0]
   655  		require.Equal(t, model.SidebarCategoryFavorites, favoritesCategory.Type)
   656  		channelsCategory := categories.Categories[1]
   657  		require.Equal(t, model.SidebarCategoryChannels, channelsCategory.Type)
   658  
   659  		// Join some channels
   660  		channel1, nErr := ss.Channel().Save(&model.Channel{
   661  			Name:        "channel1",
   662  			DisplayName: "DEF",
   663  			TeamId:      teamId,
   664  			Type:        model.CHANNEL_PRIVATE,
   665  		}, 10)
   666  		require.NoError(t, nErr)
   667  		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
   668  			UserId:      userId,
   669  			ChannelId:   channel1.Id,
   670  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   671  		})
   672  		require.NoError(t, nErr)
   673  
   674  		channel2, nErr := ss.Channel().Save(&model.Channel{
   675  			Name:        "channel2",
   676  			DisplayName: "ABC",
   677  			TeamId:      teamId,
   678  			Type:        model.CHANNEL_OPEN,
   679  		}, 10)
   680  		require.NoError(t, nErr)
   681  		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
   682  			UserId:      userId,
   683  			ChannelId:   channel2.Id,
   684  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   685  		})
   686  		require.NoError(t, nErr)
   687  
   688  		// And assign one to another category
   689  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
   690  			{
   691  				SidebarCategory: favoritesCategory.SidebarCategory,
   692  				Channels:        []string{channel2.Id},
   693  			},
   694  		})
   695  		require.NoError(t, err)
   696  
   697  		// Ensure that the correct channel is returned in the Channels category
   698  		res, err := ss.Channel().GetSidebarCategory(channelsCategory.Id)
   699  		assert.NoError(t, err)
   700  		assert.Equal(t, channelsCategory.Id, res.Id)
   701  		assert.Equal(t, model.SidebarCategoryChannels, channelsCategory.Type)
   702  		assert.Equal(t, []string{channel1.Id}, res.Channels)
   703  	})
   704  
   705  	t.Run("should return any orphaned DM channels with the Direct Messages category", func(t *testing.T) {
   706  		userId := model.NewId()
   707  		teamId := model.NewId()
   708  
   709  		// Create the initial categories and find the DMs category
   710  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   711  		require.NoError(t, nErr)
   712  
   713  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   714  		require.NoError(t, err)
   715  		require.Equal(t, model.SidebarCategoryDirectMessages, categories.Categories[2].Type)
   716  
   717  		dmsCategory := categories.Categories[2]
   718  
   719  		// Create a DM
   720  		otherUserId := model.NewId()
   721  		dmChannel, nErr := ss.Channel().SaveDirectChannel(
   722  			&model.Channel{
   723  				Name: model.GetDMNameFromIds(userId, otherUserId),
   724  				Type: model.CHANNEL_DIRECT,
   725  			},
   726  			&model.ChannelMember{
   727  				UserId:      userId,
   728  				NotifyProps: model.GetDefaultChannelNotifyProps(),
   729  			},
   730  			&model.ChannelMember{
   731  				UserId:      otherUserId,
   732  				NotifyProps: model.GetDefaultChannelNotifyProps(),
   733  			},
   734  		)
   735  		require.NoError(t, nErr)
   736  
   737  		// Ensure that the DM is returned
   738  		res, err := ss.Channel().GetSidebarCategory(dmsCategory.Id)
   739  		assert.NoError(t, err)
   740  		assert.Equal(t, dmsCategory.Id, res.Id)
   741  		assert.Equal(t, model.SidebarCategoryDirectMessages, res.Type)
   742  		assert.Equal(t, []string{dmChannel.Id}, res.Channels)
   743  	})
   744  
   745  	t.Run("should return any orphaned GM channels with the Direct Messages category", func(t *testing.T) {
   746  		userId := model.NewId()
   747  		teamId := model.NewId()
   748  
   749  		// Create the initial categories and find the DMs category
   750  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   751  		require.NoError(t, nErr)
   752  
   753  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   754  		require.NoError(t, err)
   755  		require.Equal(t, model.SidebarCategoryDirectMessages, categories.Categories[2].Type)
   756  
   757  		dmsCategory := categories.Categories[2]
   758  
   759  		// Create a GM
   760  		gmChannel, nErr := ss.Channel().Save(&model.Channel{
   761  			Name:   "abc",
   762  			TeamId: "",
   763  			Type:   model.CHANNEL_GROUP,
   764  		}, 10)
   765  		require.NoError(t, nErr)
   766  		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
   767  			UserId:      userId,
   768  			ChannelId:   gmChannel.Id,
   769  			NotifyProps: model.GetDefaultChannelNotifyProps(),
   770  		})
   771  		require.NoError(t, nErr)
   772  
   773  		// Ensure that the DM is returned
   774  		res, err := ss.Channel().GetSidebarCategory(dmsCategory.Id)
   775  		assert.NoError(t, err)
   776  		assert.Equal(t, dmsCategory.Id, res.Id)
   777  		assert.Equal(t, model.SidebarCategoryDirectMessages, res.Type)
   778  		assert.Equal(t, []string{gmChannel.Id}, res.Channels)
   779  	})
   780  
   781  	t.Run("should return orphaned DM channels in the DMs categorywhich are in a custom category on another team", func(t *testing.T) {
   782  		userId := model.NewId()
   783  		teamId := model.NewId()
   784  
   785  		// Create the initial categories and find the DMs category
   786  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   787  		require.NoError(t, nErr)
   788  
   789  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   790  		require.NoError(t, err)
   791  		require.Equal(t, model.SidebarCategoryDirectMessages, categories.Categories[2].Type)
   792  
   793  		dmsCategory := categories.Categories[2]
   794  
   795  		// Create a DM
   796  		otherUserId := model.NewId()
   797  		dmChannel, nErr := ss.Channel().SaveDirectChannel(
   798  			&model.Channel{
   799  				Name: model.GetDMNameFromIds(userId, otherUserId),
   800  				Type: model.CHANNEL_DIRECT,
   801  			},
   802  			&model.ChannelMember{
   803  				UserId:      userId,
   804  				NotifyProps: model.GetDefaultChannelNotifyProps(),
   805  			},
   806  			&model.ChannelMember{
   807  				UserId:      otherUserId,
   808  				NotifyProps: model.GetDefaultChannelNotifyProps(),
   809  			},
   810  		)
   811  		require.NoError(t, nErr)
   812  
   813  		// Create another team and assign the DM to a custom category on that team
   814  		otherTeamId := model.NewId()
   815  
   816  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, otherTeamId)
   817  		require.NoError(t, nErr)
   818  
   819  		_, err = ss.Channel().CreateSidebarCategory(userId, otherTeamId, &model.SidebarCategoryWithChannels{
   820  			SidebarCategory: model.SidebarCategory{
   821  				UserId: userId,
   822  				TeamId: teamId,
   823  			},
   824  			Channels: []string{dmChannel.Id},
   825  		})
   826  		require.NoError(t, err)
   827  
   828  		// Ensure that the DM is returned with the DMs category on the original team
   829  		res, err := ss.Channel().GetSidebarCategory(dmsCategory.Id)
   830  		assert.NoError(t, err)
   831  		assert.Equal(t, dmsCategory.Id, res.Id)
   832  		assert.Equal(t, model.SidebarCategoryDirectMessages, res.Type)
   833  		assert.Equal(t, []string{dmChannel.Id}, res.Channels)
   834  	})
   835  }
   836  
   837  func testGetSidebarCategories(t *testing.T, ss store.Store) {
   838  	t.Run("should return channels in the same order between different ways of getting categories", func(t *testing.T) {
   839  		userId := model.NewId()
   840  		teamId := model.NewId()
   841  
   842  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   843  		require.NoError(t, nErr)
   844  
   845  		channelIds := []string{
   846  			model.NewId(),
   847  			model.NewId(),
   848  			model.NewId(),
   849  		}
   850  
   851  		newCategory, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
   852  			Channels: channelIds,
   853  		})
   854  		require.NoError(t, err)
   855  		require.NotNil(t, newCategory)
   856  
   857  		gotCategory, err := ss.Channel().GetSidebarCategory(newCategory.Id)
   858  		require.NoError(t, err)
   859  
   860  		res, err := ss.Channel().GetSidebarCategories(userId, teamId)
   861  		require.NoError(t, err)
   862  		require.Len(t, res.Categories, 4)
   863  
   864  		require.Equal(t, model.SidebarCategoryCustom, res.Categories[1].Type)
   865  
   866  		// This looks unnecessary, but I was getting different results from some of these before
   867  		assert.Equal(t, newCategory.Channels, res.Categories[1].Channels)
   868  		assert.Equal(t, gotCategory.Channels, res.Categories[1].Channels)
   869  		assert.Equal(t, channelIds, res.Categories[1].Channels)
   870  	})
   871  }
   872  
   873  func testUpdateSidebarCategories(t *testing.T, ss store.Store) {
   874  	t.Run("ensure the query to update SidebarCategories hasn't been polluted by UpdateSidebarCategoryOrder", func(t *testing.T) {
   875  		userId := model.NewId()
   876  		teamId := model.NewId()
   877  
   878  		// Create the initial categories
   879  		err := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   880  		require.NoError(t, err)
   881  
   882  		initialCategories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   883  		require.NoError(t, err)
   884  
   885  		favoritesCategory := initialCategories.Categories[0]
   886  		channelsCategory := initialCategories.Categories[1]
   887  		dmsCategory := initialCategories.Categories[2]
   888  
   889  		// And then update one of them
   890  		updated, _, err := ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
   891  			channelsCategory,
   892  		})
   893  		require.NoError(t, err)
   894  		assert.Equal(t, channelsCategory, updated[0])
   895  		assert.Equal(t, "Channels", updated[0].DisplayName)
   896  
   897  		// And then reorder the categories
   898  		err = ss.Channel().UpdateSidebarCategoryOrder(userId, teamId, []string{dmsCategory.Id, favoritesCategory.Id, channelsCategory.Id})
   899  		require.NoError(t, err)
   900  
   901  		// Which somehow blanks out stuff because ???
   902  		got, err := ss.Channel().GetSidebarCategory(favoritesCategory.Id)
   903  		require.NoError(t, err)
   904  		assert.Equal(t, "Favorites", got.DisplayName)
   905  	})
   906  
   907  	t.Run("categories should be returned in their original order", func(t *testing.T) {
   908  		userId := model.NewId()
   909  		teamId := model.NewId()
   910  
   911  		// Create the initial categories
   912  		err := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   913  		require.NoError(t, err)
   914  
   915  		initialCategories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   916  		require.NoError(t, err)
   917  
   918  		favoritesCategory := initialCategories.Categories[0]
   919  		channelsCategory := initialCategories.Categories[1]
   920  		dmsCategory := initialCategories.Categories[2]
   921  
   922  		// And then update them
   923  		updatedCategories, _, err := ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
   924  			favoritesCategory,
   925  			channelsCategory,
   926  			dmsCategory,
   927  		})
   928  		assert.NoError(t, err)
   929  		assert.Equal(t, favoritesCategory.Id, updatedCategories[0].Id)
   930  		assert.Equal(t, channelsCategory.Id, updatedCategories[1].Id)
   931  		assert.Equal(t, dmsCategory.Id, updatedCategories[2].Id)
   932  	})
   933  
   934  	t.Run("should silently fail to update read only fields", func(t *testing.T) {
   935  		userId := model.NewId()
   936  		teamId := model.NewId()
   937  
   938  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
   939  		require.NoError(t, nErr)
   940  
   941  		initialCategories, err := ss.Channel().GetSidebarCategories(userId, teamId)
   942  		require.NoError(t, err)
   943  
   944  		favoritesCategory := initialCategories.Categories[0]
   945  		channelsCategory := initialCategories.Categories[1]
   946  		dmsCategory := initialCategories.Categories[2]
   947  
   948  		customCategory, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{})
   949  		require.NoError(t, err)
   950  
   951  		categoriesToUpdate := []*model.SidebarCategoryWithChannels{
   952  			// Try to change the type of Favorites
   953  			{
   954  				SidebarCategory: model.SidebarCategory{
   955  					Id:          favoritesCategory.Id,
   956  					DisplayName: "something else",
   957  				},
   958  				Channels: favoritesCategory.Channels,
   959  			},
   960  			// Try to change the type of Channels
   961  			{
   962  				SidebarCategory: model.SidebarCategory{
   963  					Id:   channelsCategory.Id,
   964  					Type: model.SidebarCategoryDirectMessages,
   965  				},
   966  				Channels: channelsCategory.Channels,
   967  			},
   968  			// Try to change the Channels of DMs
   969  			{
   970  				SidebarCategory: dmsCategory.SidebarCategory,
   971  				Channels:        []string{"fakechannel"},
   972  			},
   973  			// Try to change the UserId/TeamId of a custom category
   974  			{
   975  				SidebarCategory: model.SidebarCategory{
   976  					Id:          customCategory.Id,
   977  					UserId:      model.NewId(),
   978  					TeamId:      model.NewId(),
   979  					Sorting:     customCategory.Sorting,
   980  					DisplayName: customCategory.DisplayName,
   981  				},
   982  				Channels: customCategory.Channels,
   983  			},
   984  		}
   985  
   986  		updatedCategories, _, err := ss.Channel().UpdateSidebarCategories(userId, teamId, categoriesToUpdate)
   987  		assert.NoError(t, err)
   988  
   989  		assert.NotEqual(t, "Favorites", categoriesToUpdate[0].DisplayName)
   990  		assert.Equal(t, "Favorites", updatedCategories[0].DisplayName)
   991  		assert.NotEqual(t, model.SidebarCategoryChannels, categoriesToUpdate[1].Type)
   992  		assert.Equal(t, model.SidebarCategoryChannels, updatedCategories[1].Type)
   993  		assert.NotEqual(t, []string{}, categoriesToUpdate[2].Channels)
   994  		assert.Equal(t, []string{}, updatedCategories[2].Channels)
   995  		assert.NotEqual(t, userId, categoriesToUpdate[3].UserId)
   996  		assert.Equal(t, userId, updatedCategories[3].UserId)
   997  	})
   998  
   999  	t.Run("should add and remove favorites preferences based on the Favorites category", func(t *testing.T) {
  1000  		userId := model.NewId()
  1001  		teamId := model.NewId()
  1002  
  1003  		// Create the initial categories and find the favorites category
  1004  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1005  		require.NoError(t, nErr)
  1006  
  1007  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
  1008  		require.NoError(t, err)
  1009  
  1010  		favoritesCategory := categories.Categories[0]
  1011  		require.Equal(t, model.SidebarCategoryFavorites, favoritesCategory.Type)
  1012  
  1013  		// Join a channel
  1014  		channel, nErr := ss.Channel().Save(&model.Channel{
  1015  			Name:   "channel",
  1016  			Type:   model.CHANNEL_OPEN,
  1017  			TeamId: teamId,
  1018  		}, 10)
  1019  		require.NoError(t, nErr)
  1020  		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
  1021  			UserId:      userId,
  1022  			ChannelId:   channel.Id,
  1023  			NotifyProps: model.GetDefaultChannelNotifyProps(),
  1024  		})
  1025  		require.NoError(t, nErr)
  1026  
  1027  		// Assign it to favorites
  1028  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1029  			{
  1030  				SidebarCategory: favoritesCategory.SidebarCategory,
  1031  				Channels:        []string{channel.Id},
  1032  			},
  1033  		})
  1034  		assert.NoError(t, err)
  1035  
  1036  		res, nErr := ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1037  		assert.NoError(t, nErr)
  1038  		assert.NotNil(t, res)
  1039  		assert.Equal(t, "true", res.Value)
  1040  
  1041  		// And then remove it
  1042  		channelsCategory := categories.Categories[1]
  1043  		require.Equal(t, model.SidebarCategoryChannels, channelsCategory.Type)
  1044  
  1045  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1046  			{
  1047  				SidebarCategory: channelsCategory.SidebarCategory,
  1048  				Channels:        []string{channel.Id},
  1049  			},
  1050  		})
  1051  		assert.NoError(t, err)
  1052  
  1053  		res, nErr = ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1054  		assert.Error(t, nErr)
  1055  		assert.True(t, errors.Is(nErr, sql.ErrNoRows))
  1056  		assert.Nil(t, res)
  1057  	})
  1058  
  1059  	t.Run("should add and remove favorites preferences for DMs", func(t *testing.T) {
  1060  		userId := model.NewId()
  1061  		teamId := model.NewId()
  1062  
  1063  		// Create the initial categories and find the favorites category
  1064  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1065  		require.NoError(t, nErr)
  1066  
  1067  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
  1068  		require.NoError(t, err)
  1069  
  1070  		favoritesCategory := categories.Categories[0]
  1071  		require.Equal(t, model.SidebarCategoryFavorites, favoritesCategory.Type)
  1072  
  1073  		// Create a direct channel
  1074  		otherUserId := model.NewId()
  1075  
  1076  		dmChannel, nErr := ss.Channel().SaveDirectChannel(
  1077  			&model.Channel{
  1078  				Name: model.GetDMNameFromIds(userId, otherUserId),
  1079  				Type: model.CHANNEL_DIRECT,
  1080  			},
  1081  			&model.ChannelMember{
  1082  				UserId:      userId,
  1083  				NotifyProps: model.GetDefaultChannelNotifyProps(),
  1084  			},
  1085  			&model.ChannelMember{
  1086  				UserId:      otherUserId,
  1087  				NotifyProps: model.GetDefaultChannelNotifyProps(),
  1088  			},
  1089  		)
  1090  		assert.NoError(t, nErr)
  1091  
  1092  		// Assign it to favorites
  1093  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1094  			{
  1095  				SidebarCategory: favoritesCategory.SidebarCategory,
  1096  				Channels:        []string{dmChannel.Id},
  1097  			},
  1098  		})
  1099  		assert.NoError(t, err)
  1100  
  1101  		res, nErr := ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, dmChannel.Id)
  1102  		assert.NoError(t, nErr)
  1103  		assert.NotNil(t, res)
  1104  		assert.Equal(t, "true", res.Value)
  1105  
  1106  		// And then remove it
  1107  		dmsCategory := categories.Categories[2]
  1108  		require.Equal(t, model.SidebarCategoryDirectMessages, dmsCategory.Type)
  1109  
  1110  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1111  			{
  1112  				SidebarCategory: dmsCategory.SidebarCategory,
  1113  				Channels:        []string{dmChannel.Id},
  1114  			},
  1115  		})
  1116  		assert.NoError(t, err)
  1117  
  1118  		res, nErr = ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, dmChannel.Id)
  1119  		assert.Error(t, nErr)
  1120  		assert.True(t, errors.Is(nErr, sql.ErrNoRows))
  1121  		assert.Nil(t, res)
  1122  	})
  1123  
  1124  	t.Run("should add and remove favorites preferences, even if the channel is already favorited in preferences", func(t *testing.T) {
  1125  		userId := model.NewId()
  1126  		teamId := model.NewId()
  1127  		teamId2 := model.NewId()
  1128  
  1129  		// Create the initial categories and find the favorites categories in each team
  1130  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1131  		require.NoError(t, nErr)
  1132  
  1133  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
  1134  		require.NoError(t, err)
  1135  
  1136  		favoritesCategory := categories.Categories[0]
  1137  		require.Equal(t, model.SidebarCategoryFavorites, favoritesCategory.Type)
  1138  
  1139  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId2)
  1140  		require.NoError(t, nErr)
  1141  
  1142  		categories2, err := ss.Channel().GetSidebarCategories(userId, teamId2)
  1143  		require.NoError(t, err)
  1144  
  1145  		favoritesCategory2 := categories2.Categories[0]
  1146  		require.Equal(t, model.SidebarCategoryFavorites, favoritesCategory2.Type)
  1147  
  1148  		// Create a direct channel
  1149  		otherUserId := model.NewId()
  1150  
  1151  		dmChannel, nErr := ss.Channel().SaveDirectChannel(
  1152  			&model.Channel{
  1153  				Name: model.GetDMNameFromIds(userId, otherUserId),
  1154  				Type: model.CHANNEL_DIRECT,
  1155  			},
  1156  			&model.ChannelMember{
  1157  				UserId:      userId,
  1158  				NotifyProps: model.GetDefaultChannelNotifyProps(),
  1159  			},
  1160  			&model.ChannelMember{
  1161  				UserId:      otherUserId,
  1162  				NotifyProps: model.GetDefaultChannelNotifyProps(),
  1163  			},
  1164  		)
  1165  		assert.NoError(t, nErr)
  1166  
  1167  		// Assign it to favorites on the first team. The favorites preference gets set for all teams.
  1168  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1169  			{
  1170  				SidebarCategory: favoritesCategory.SidebarCategory,
  1171  				Channels:        []string{dmChannel.Id},
  1172  			},
  1173  		})
  1174  		assert.NoError(t, err)
  1175  
  1176  		res, nErr := ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, dmChannel.Id)
  1177  		assert.NoError(t, nErr)
  1178  		assert.NotNil(t, res)
  1179  		assert.Equal(t, "true", res.Value)
  1180  
  1181  		// Assign it to favorites on the second team. The favorites preference is already set.
  1182  		updated, _, err := ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1183  			{
  1184  				SidebarCategory: favoritesCategory2.SidebarCategory,
  1185  				Channels:        []string{dmChannel.Id},
  1186  			},
  1187  		})
  1188  		assert.NoError(t, err)
  1189  		assert.Equal(t, []string{dmChannel.Id}, updated[0].Channels)
  1190  
  1191  		res, nErr = ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, dmChannel.Id)
  1192  		assert.NoError(t, nErr)
  1193  		assert.NotNil(t, res)
  1194  		assert.Equal(t, "true", res.Value)
  1195  
  1196  		// Remove it from favorites on the first team. This clears the favorites preference for all teams.
  1197  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1198  			{
  1199  				SidebarCategory: favoritesCategory.SidebarCategory,
  1200  				Channels:        []string{},
  1201  			},
  1202  		})
  1203  		assert.NoError(t, err)
  1204  
  1205  		res, nErr = ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, dmChannel.Id)
  1206  		require.Error(t, nErr)
  1207  		assert.Nil(t, res)
  1208  
  1209  		// Remove it from favorites on the second team. The favorites preference was already deleted.
  1210  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId2, []*model.SidebarCategoryWithChannels{
  1211  			{
  1212  				SidebarCategory: favoritesCategory2.SidebarCategory,
  1213  				Channels:        []string{},
  1214  			},
  1215  		})
  1216  		assert.NoError(t, err)
  1217  
  1218  		res, nErr = ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, dmChannel.Id)
  1219  		require.Error(t, nErr)
  1220  		assert.Nil(t, res)
  1221  	})
  1222  
  1223  	t.Run("should not affect other users' favorites preferences", func(t *testing.T) {
  1224  		userId := model.NewId()
  1225  		teamId := model.NewId()
  1226  
  1227  		// Create the initial categories and find the favorites category
  1228  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1229  		require.NoError(t, nErr)
  1230  
  1231  		categories, err := ss.Channel().GetSidebarCategories(userId, teamId)
  1232  		require.NoError(t, err)
  1233  
  1234  		favoritesCategory := categories.Categories[0]
  1235  		require.Equal(t, model.SidebarCategoryFavorites, favoritesCategory.Type)
  1236  		channelsCategory := categories.Categories[1]
  1237  		require.Equal(t, model.SidebarCategoryChannels, channelsCategory.Type)
  1238  
  1239  		// Create the other users' categories
  1240  		userId2 := model.NewId()
  1241  
  1242  		nErr = ss.Channel().CreateInitialSidebarCategories(userId2, teamId)
  1243  		require.NoError(t, nErr)
  1244  
  1245  		categories2, err := ss.Channel().GetSidebarCategories(userId2, teamId)
  1246  		require.NoError(t, err)
  1247  
  1248  		favoritesCategory2 := categories2.Categories[0]
  1249  		require.Equal(t, model.SidebarCategoryFavorites, favoritesCategory2.Type)
  1250  		channelsCategory2 := categories2.Categories[1]
  1251  		require.Equal(t, model.SidebarCategoryChannels, channelsCategory2.Type)
  1252  
  1253  		// Have both users join a channel
  1254  		channel, nErr := ss.Channel().Save(&model.Channel{
  1255  			Name:   "channel",
  1256  			Type:   model.CHANNEL_OPEN,
  1257  			TeamId: teamId,
  1258  		}, 10)
  1259  		require.NoError(t, nErr)
  1260  		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
  1261  			UserId:      userId,
  1262  			ChannelId:   channel.Id,
  1263  			NotifyProps: model.GetDefaultChannelNotifyProps(),
  1264  		})
  1265  		require.NoError(t, nErr)
  1266  		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
  1267  			UserId:      userId2,
  1268  			ChannelId:   channel.Id,
  1269  			NotifyProps: model.GetDefaultChannelNotifyProps(),
  1270  		})
  1271  		require.NoError(t, nErr)
  1272  
  1273  		// Have user1 favorite it
  1274  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1275  			{
  1276  				SidebarCategory: favoritesCategory.SidebarCategory,
  1277  				Channels:        []string{channel.Id},
  1278  			},
  1279  			{
  1280  				SidebarCategory: channelsCategory.SidebarCategory,
  1281  				Channels:        []string{},
  1282  			},
  1283  		})
  1284  		assert.NoError(t, err)
  1285  
  1286  		res, nErr := ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1287  		assert.NoError(t, nErr)
  1288  		assert.NotNil(t, res)
  1289  		assert.Equal(t, "true", res.Value)
  1290  
  1291  		res, nErr = ss.Preference().Get(userId2, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1292  		assert.True(t, errors.Is(nErr, sql.ErrNoRows))
  1293  		assert.Nil(t, res)
  1294  
  1295  		// And user2 favorite it
  1296  		_, _, err = ss.Channel().UpdateSidebarCategories(userId2, teamId, []*model.SidebarCategoryWithChannels{
  1297  			{
  1298  				SidebarCategory: favoritesCategory2.SidebarCategory,
  1299  				Channels:        []string{channel.Id},
  1300  			},
  1301  			{
  1302  				SidebarCategory: channelsCategory2.SidebarCategory,
  1303  				Channels:        []string{},
  1304  			},
  1305  		})
  1306  		assert.NoError(t, err)
  1307  
  1308  		res, nErr = ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1309  		assert.NoError(t, nErr)
  1310  		assert.NotNil(t, res)
  1311  		assert.Equal(t, "true", res.Value)
  1312  
  1313  		res, nErr = ss.Preference().Get(userId2, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1314  		assert.NoError(t, nErr)
  1315  		assert.NotNil(t, res)
  1316  		assert.Equal(t, "true", res.Value)
  1317  
  1318  		// And then user1 unfavorite it
  1319  		_, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1320  			{
  1321  				SidebarCategory: channelsCategory.SidebarCategory,
  1322  				Channels:        []string{channel.Id},
  1323  			},
  1324  			{
  1325  				SidebarCategory: favoritesCategory.SidebarCategory,
  1326  				Channels:        []string{},
  1327  			},
  1328  		})
  1329  		assert.NoError(t, err)
  1330  
  1331  		res, nErr = ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1332  		assert.True(t, errors.Is(nErr, sql.ErrNoRows))
  1333  		assert.Nil(t, res)
  1334  
  1335  		res, nErr = ss.Preference().Get(userId2, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1336  		assert.NoError(t, nErr)
  1337  		assert.NotNil(t, res)
  1338  		assert.Equal(t, "true", res.Value)
  1339  
  1340  		// And finally user2 favorite it
  1341  		_, _, err = ss.Channel().UpdateSidebarCategories(userId2, teamId, []*model.SidebarCategoryWithChannels{
  1342  			{
  1343  				SidebarCategory: channelsCategory2.SidebarCategory,
  1344  				Channels:        []string{channel.Id},
  1345  			},
  1346  			{
  1347  				SidebarCategory: favoritesCategory2.SidebarCategory,
  1348  				Channels:        []string{},
  1349  			},
  1350  		})
  1351  		assert.NoError(t, err)
  1352  
  1353  		res, nErr = ss.Preference().Get(userId, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1354  		assert.True(t, errors.Is(nErr, sql.ErrNoRows))
  1355  		assert.Nil(t, res)
  1356  
  1357  		res, nErr = ss.Preference().Get(userId2, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id)
  1358  		assert.True(t, errors.Is(nErr, sql.ErrNoRows))
  1359  		assert.Nil(t, res)
  1360  	})
  1361  
  1362  	t.Run("channels removed from Channels or DMs categories should be re-added", func(t *testing.T) {
  1363  		userId := model.NewId()
  1364  		teamId := model.NewId()
  1365  
  1366  		// Create some channels
  1367  		channel, nErr := ss.Channel().Save(&model.Channel{
  1368  			Name:   "channel",
  1369  			Type:   model.CHANNEL_OPEN,
  1370  			TeamId: teamId,
  1371  		}, 10)
  1372  		require.NoError(t, nErr)
  1373  		_, err := ss.Channel().SaveMember(&model.ChannelMember{
  1374  			UserId:      userId,
  1375  			ChannelId:   channel.Id,
  1376  			NotifyProps: model.GetDefaultChannelNotifyProps(),
  1377  		})
  1378  		require.NoError(t, err)
  1379  
  1380  		otherUserId := model.NewId()
  1381  		dmChannel, nErr := ss.Channel().SaveDirectChannel(
  1382  			&model.Channel{
  1383  				Name: model.GetDMNameFromIds(userId, otherUserId),
  1384  				Type: model.CHANNEL_DIRECT,
  1385  			},
  1386  			&model.ChannelMember{
  1387  				UserId:      userId,
  1388  				NotifyProps: model.GetDefaultChannelNotifyProps(),
  1389  			},
  1390  			&model.ChannelMember{
  1391  				UserId:      otherUserId,
  1392  				NotifyProps: model.GetDefaultChannelNotifyProps(),
  1393  			},
  1394  		)
  1395  		require.NoError(t, nErr)
  1396  
  1397  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1398  		require.NoError(t, nErr)
  1399  
  1400  		// And some categories
  1401  		initialCategories, nErr := ss.Channel().GetSidebarCategories(userId, teamId)
  1402  		require.NoError(t, nErr)
  1403  
  1404  		channelsCategory := initialCategories.Categories[1]
  1405  		dmsCategory := initialCategories.Categories[2]
  1406  
  1407  		require.Equal(t, []string{channel.Id}, channelsCategory.Channels)
  1408  		require.Equal(t, []string{dmChannel.Id}, dmsCategory.Channels)
  1409  
  1410  		// Try to save the categories with no channels in them
  1411  		categoriesToUpdate := []*model.SidebarCategoryWithChannels{
  1412  			{
  1413  				SidebarCategory: channelsCategory.SidebarCategory,
  1414  				Channels:        []string{},
  1415  			},
  1416  			{
  1417  				SidebarCategory: dmsCategory.SidebarCategory,
  1418  				Channels:        []string{},
  1419  			},
  1420  		}
  1421  
  1422  		updatedCategories, _, nErr := ss.Channel().UpdateSidebarCategories(userId, teamId, categoriesToUpdate)
  1423  		assert.NoError(t, nErr)
  1424  
  1425  		// The channels should still exist in the category because they would otherwise be orphaned
  1426  		assert.Equal(t, []string{channel.Id}, updatedCategories[0].Channels)
  1427  		assert.Equal(t, []string{dmChannel.Id}, updatedCategories[1].Channels)
  1428  	})
  1429  
  1430  	t.Run("should be able to move DMs into and out of custom categories", func(t *testing.T) {
  1431  		userId := model.NewId()
  1432  		teamId := model.NewId()
  1433  
  1434  		otherUserId := model.NewId()
  1435  		dmChannel, nErr := ss.Channel().SaveDirectChannel(
  1436  			&model.Channel{
  1437  				Name: model.GetDMNameFromIds(userId, otherUserId),
  1438  				Type: model.CHANNEL_DIRECT,
  1439  			},
  1440  			&model.ChannelMember{
  1441  				UserId:      userId,
  1442  				NotifyProps: model.GetDefaultChannelNotifyProps(),
  1443  			},
  1444  			&model.ChannelMember{
  1445  				UserId:      otherUserId,
  1446  				NotifyProps: model.GetDefaultChannelNotifyProps(),
  1447  			},
  1448  		)
  1449  		require.NoError(t, nErr)
  1450  
  1451  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1452  		require.NoError(t, nErr)
  1453  
  1454  		// The DM should start in the DMs category
  1455  		initialCategories, err := ss.Channel().GetSidebarCategories(userId, teamId)
  1456  		require.NoError(t, err)
  1457  
  1458  		dmsCategory := initialCategories.Categories[2]
  1459  		require.Equal(t, []string{dmChannel.Id}, dmsCategory.Channels)
  1460  
  1461  		// Now move the DM into a custom category
  1462  		customCategory, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{})
  1463  		require.NoError(t, err)
  1464  
  1465  		categoriesToUpdate := []*model.SidebarCategoryWithChannels{
  1466  			{
  1467  				SidebarCategory: dmsCategory.SidebarCategory,
  1468  				Channels:        []string{},
  1469  			},
  1470  			{
  1471  				SidebarCategory: customCategory.SidebarCategory,
  1472  				Channels:        []string{dmChannel.Id},
  1473  			},
  1474  		}
  1475  
  1476  		updatedCategories, _, err := ss.Channel().UpdateSidebarCategories(userId, teamId, categoriesToUpdate)
  1477  		assert.NoError(t, err)
  1478  		assert.Equal(t, dmsCategory.Id, updatedCategories[0].Id)
  1479  		assert.Equal(t, []string{}, updatedCategories[0].Channels)
  1480  		assert.Equal(t, customCategory.Id, updatedCategories[1].Id)
  1481  		assert.Equal(t, []string{dmChannel.Id}, updatedCategories[1].Channels)
  1482  
  1483  		updatedDmsCategory, err := ss.Channel().GetSidebarCategory(dmsCategory.Id)
  1484  		require.NoError(t, err)
  1485  		assert.Equal(t, []string{}, updatedDmsCategory.Channels)
  1486  
  1487  		updatedCustomCategory, err := ss.Channel().GetSidebarCategory(customCategory.Id)
  1488  		require.NoError(t, err)
  1489  		assert.Equal(t, []string{dmChannel.Id}, updatedCustomCategory.Channels)
  1490  
  1491  		// And move it back out of the custom category
  1492  		categoriesToUpdate = []*model.SidebarCategoryWithChannels{
  1493  			{
  1494  				SidebarCategory: dmsCategory.SidebarCategory,
  1495  				Channels:        []string{dmChannel.Id},
  1496  			},
  1497  			{
  1498  				SidebarCategory: customCategory.SidebarCategory,
  1499  				Channels:        []string{},
  1500  			},
  1501  		}
  1502  
  1503  		updatedCategories, _, err = ss.Channel().UpdateSidebarCategories(userId, teamId, categoriesToUpdate)
  1504  		assert.NoError(t, err)
  1505  		assert.Equal(t, dmsCategory.Id, updatedCategories[0].Id)
  1506  		assert.Equal(t, []string{dmChannel.Id}, updatedCategories[0].Channels)
  1507  		assert.Equal(t, customCategory.Id, updatedCategories[1].Id)
  1508  		assert.Equal(t, []string{}, updatedCategories[1].Channels)
  1509  
  1510  		updatedDmsCategory, err = ss.Channel().GetSidebarCategory(dmsCategory.Id)
  1511  		require.NoError(t, err)
  1512  		assert.Equal(t, []string{dmChannel.Id}, updatedDmsCategory.Channels)
  1513  
  1514  		updatedCustomCategory, err = ss.Channel().GetSidebarCategory(customCategory.Id)
  1515  		require.NoError(t, err)
  1516  		assert.Equal(t, []string{}, updatedCustomCategory.Channels)
  1517  	})
  1518  
  1519  	t.Run("should successfully move channels between categories", func(t *testing.T) {
  1520  		userId := model.NewId()
  1521  		teamId := model.NewId()
  1522  
  1523  		// Join a channel
  1524  		channel, nErr := ss.Channel().Save(&model.Channel{
  1525  			Name:   "channel",
  1526  			Type:   model.CHANNEL_OPEN,
  1527  			TeamId: teamId,
  1528  		}, 10)
  1529  		require.NoError(t, nErr)
  1530  		_, err := ss.Channel().SaveMember(&model.ChannelMember{
  1531  			UserId:      userId,
  1532  			ChannelId:   channel.Id,
  1533  			NotifyProps: model.GetDefaultChannelNotifyProps(),
  1534  		})
  1535  		require.NoError(t, err)
  1536  
  1537  		// And then create the initial categories so that it includes the channel
  1538  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1539  		require.NoError(t, nErr)
  1540  
  1541  		initialCategories, nErr := ss.Channel().GetSidebarCategories(userId, teamId)
  1542  		require.NoError(t, nErr)
  1543  
  1544  		channelsCategory := initialCategories.Categories[1]
  1545  		require.Equal(t, []string{channel.Id}, channelsCategory.Channels)
  1546  
  1547  		customCategory, nErr := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{})
  1548  		require.NoError(t, nErr)
  1549  
  1550  		// Move the channel one way
  1551  		updatedCategories, _, nErr := ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1552  			{
  1553  				SidebarCategory: channelsCategory.SidebarCategory,
  1554  				Channels:        []string{},
  1555  			},
  1556  			{
  1557  				SidebarCategory: customCategory.SidebarCategory,
  1558  				Channels:        []string{channel.Id},
  1559  			},
  1560  		})
  1561  		assert.NoError(t, nErr)
  1562  
  1563  		assert.Equal(t, []string{}, updatedCategories[0].Channels)
  1564  		assert.Equal(t, []string{channel.Id}, updatedCategories[1].Channels)
  1565  
  1566  		// And then the other
  1567  		updatedCategories, _, nErr = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1568  			{
  1569  				SidebarCategory: channelsCategory.SidebarCategory,
  1570  				Channels:        []string{channel.Id},
  1571  			},
  1572  			{
  1573  				SidebarCategory: customCategory.SidebarCategory,
  1574  				Channels:        []string{},
  1575  			},
  1576  		})
  1577  		assert.NoError(t, nErr)
  1578  		assert.Equal(t, []string{channel.Id}, updatedCategories[0].Channels)
  1579  		assert.Equal(t, []string{}, updatedCategories[1].Channels)
  1580  	})
  1581  
  1582  	t.Run("should correctly return the original categories that were modified", func(t *testing.T) {
  1583  		userId := model.NewId()
  1584  		teamId := model.NewId()
  1585  
  1586  		// Join a channel
  1587  		channel, nErr := ss.Channel().Save(&model.Channel{
  1588  			Name:   "channel",
  1589  			Type:   model.CHANNEL_OPEN,
  1590  			TeamId: teamId,
  1591  		}, 10)
  1592  		require.NoError(t, nErr)
  1593  		_, err := ss.Channel().SaveMember(&model.ChannelMember{
  1594  			UserId:      userId,
  1595  			ChannelId:   channel.Id,
  1596  			NotifyProps: model.GetDefaultChannelNotifyProps(),
  1597  		})
  1598  		require.NoError(t, err)
  1599  
  1600  		// And then create the initial categories so that Channels includes the channel
  1601  		nErr = ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1602  		require.NoError(t, nErr)
  1603  
  1604  		initialCategories, nErr := ss.Channel().GetSidebarCategories(userId, teamId)
  1605  		require.NoError(t, nErr)
  1606  
  1607  		channelsCategory := initialCategories.Categories[1]
  1608  		require.Equal(t, []string{channel.Id}, channelsCategory.Channels)
  1609  
  1610  		customCategory, nErr := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
  1611  			SidebarCategory: model.SidebarCategory{
  1612  				DisplayName: "originalName",
  1613  			},
  1614  		})
  1615  		require.NoError(t, nErr)
  1616  
  1617  		// Rename the custom category
  1618  		updatedCategories, originalCategories, nErr := ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1619  			{
  1620  				SidebarCategory: model.SidebarCategory{
  1621  					Id:          customCategory.Id,
  1622  					DisplayName: "updatedName",
  1623  				},
  1624  			},
  1625  		})
  1626  		require.NoError(t, nErr)
  1627  		require.Equal(t, len(updatedCategories), len(originalCategories))
  1628  		assert.Equal(t, "originalName", originalCategories[0].DisplayName)
  1629  		assert.Equal(t, "updatedName", updatedCategories[0].DisplayName)
  1630  
  1631  		// Move a channel
  1632  		updatedCategories, originalCategories, nErr = ss.Channel().UpdateSidebarCategories(userId, teamId, []*model.SidebarCategoryWithChannels{
  1633  			{
  1634  				SidebarCategory: channelsCategory.SidebarCategory,
  1635  				Channels:        []string{},
  1636  			},
  1637  			{
  1638  				SidebarCategory: customCategory.SidebarCategory,
  1639  				Channels:        []string{channel.Id},
  1640  			},
  1641  		})
  1642  		require.NoError(t, nErr)
  1643  		require.Equal(t, len(updatedCategories), len(originalCategories))
  1644  		require.Equal(t, updatedCategories[0].Id, originalCategories[0].Id)
  1645  		require.Equal(t, updatedCategories[1].Id, originalCategories[1].Id)
  1646  
  1647  		assert.Equal(t, []string{channel.Id}, originalCategories[0].Channels)
  1648  		assert.Equal(t, []string{}, updatedCategories[0].Channels)
  1649  		assert.Equal(t, []string{}, originalCategories[1].Channels)
  1650  		assert.Equal(t, []string{channel.Id}, updatedCategories[1].Channels)
  1651  	})
  1652  }
  1653  
  1654  func setupInitialSidebarCategories(t *testing.T, ss store.Store) (string, string) {
  1655  	userId := model.NewId()
  1656  	teamId := model.NewId()
  1657  
  1658  	nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1659  	require.NoError(t, nErr)
  1660  
  1661  	res, err := ss.Channel().GetSidebarCategories(userId, teamId)
  1662  	require.NoError(t, err)
  1663  	require.Len(t, res.Categories, 3)
  1664  
  1665  	return userId, teamId
  1666  }
  1667  
  1668  func testClearSidebarOnTeamLeave(t *testing.T, ss store.Store, s SqlStore) {
  1669  	t.Run("should delete all sidebar categories and channels on the team", func(t *testing.T) {
  1670  		userId, teamId := setupInitialSidebarCategories(t, ss)
  1671  
  1672  		user := &model.User{
  1673  			Id: userId,
  1674  		}
  1675  
  1676  		// Create some channels and assign them to a custom category
  1677  		channel1, nErr := ss.Channel().Save(&model.Channel{
  1678  			Name:   model.NewId(),
  1679  			TeamId: teamId,
  1680  			Type:   model.CHANNEL_OPEN,
  1681  		}, 1000)
  1682  		require.NoError(t, nErr)
  1683  
  1684  		dmChannel1, nErr := ss.Channel().CreateDirectChannel(user, &model.User{
  1685  			Id: model.NewId(),
  1686  		})
  1687  		require.NoError(t, nErr)
  1688  
  1689  		_, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
  1690  			Channels: []string{channel1.Id, dmChannel1.Id},
  1691  		})
  1692  		require.NoError(t, err)
  1693  
  1694  		// Confirm that we start with the right number of categories and SidebarChannels entries
  1695  		count, err := s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarCategories WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1696  		require.NoError(t, err)
  1697  		require.Equal(t, int64(4), count)
  1698  
  1699  		count, err = s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarChannels WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1700  		require.NoError(t, err)
  1701  		require.Equal(t, int64(2), count)
  1702  
  1703  		// Leave the team
  1704  		err = ss.Channel().ClearSidebarOnTeamLeave(userId, teamId)
  1705  		assert.NoError(t, err)
  1706  
  1707  		// Confirm that all the categories and SidebarChannel entries have been deleted
  1708  		count, err = s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarCategories WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1709  		require.NoError(t, err)
  1710  		assert.Equal(t, int64(0), count)
  1711  
  1712  		count, err = s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarChannels WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1713  		require.NoError(t, err)
  1714  		assert.Equal(t, int64(0), count)
  1715  	})
  1716  
  1717  	t.Run("should not delete sidebar categories and channels on another the team", func(t *testing.T) {
  1718  		userId, teamId := setupInitialSidebarCategories(t, ss)
  1719  
  1720  		user := &model.User{
  1721  			Id: userId,
  1722  		}
  1723  
  1724  		// Create some channels and assign them to a custom category
  1725  		channel1, nErr := ss.Channel().Save(&model.Channel{
  1726  			Name:   model.NewId(),
  1727  			TeamId: teamId,
  1728  			Type:   model.CHANNEL_OPEN,
  1729  		}, 1000)
  1730  		require.NoError(t, nErr)
  1731  
  1732  		dmChannel1, nErr := ss.Channel().CreateDirectChannel(user, &model.User{
  1733  			Id: model.NewId(),
  1734  		})
  1735  		require.NoError(t, nErr)
  1736  
  1737  		_, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
  1738  			Channels: []string{channel1.Id, dmChannel1.Id},
  1739  		})
  1740  		require.NoError(t, err)
  1741  
  1742  		// Confirm that we start with the right number of categories and SidebarChannels entries
  1743  		count, err := s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarCategories WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1744  		require.NoError(t, err)
  1745  		require.Equal(t, int64(4), count)
  1746  
  1747  		count, err = s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarChannels WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1748  		require.NoError(t, err)
  1749  		require.Equal(t, int64(2), count)
  1750  
  1751  		// Leave another team
  1752  		err = ss.Channel().ClearSidebarOnTeamLeave(userId, model.NewId())
  1753  		assert.NoError(t, err)
  1754  
  1755  		// Confirm that nothing has been deleted
  1756  		count, err = s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarCategories WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1757  		require.NoError(t, err)
  1758  		assert.Equal(t, int64(4), count)
  1759  
  1760  		count, err = s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarChannels WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1761  		require.NoError(t, err)
  1762  		assert.Equal(t, int64(2), count)
  1763  	})
  1764  
  1765  	t.Run("MM-30314 should not delete channels on another team under specific circumstances", func(t *testing.T) {
  1766  		userId, teamId := setupInitialSidebarCategories(t, ss)
  1767  
  1768  		user := &model.User{
  1769  			Id: userId,
  1770  		}
  1771  		user2 := &model.User{
  1772  			Id: model.NewId(),
  1773  		}
  1774  
  1775  		// Create a second team and set up the sidebar categories for it
  1776  		teamId2 := model.NewId()
  1777  
  1778  		err := ss.Channel().CreateInitialSidebarCategories(userId, teamId2)
  1779  		require.NoError(t, err)
  1780  
  1781  		res, err := ss.Channel().GetSidebarCategories(userId, teamId2)
  1782  		require.NoError(t, err)
  1783  		require.Len(t, res.Categories, 3)
  1784  
  1785  		// On the first team, create some channels and assign them to a custom category
  1786  		channel1, nErr := ss.Channel().Save(&model.Channel{
  1787  			Name:   model.NewId(),
  1788  			TeamId: teamId,
  1789  			Type:   model.CHANNEL_OPEN,
  1790  		}, 1000)
  1791  		require.NoError(t, nErr)
  1792  
  1793  		dmChannel1, nErr := ss.Channel().CreateDirectChannel(user, user2)
  1794  		require.NoError(t, nErr)
  1795  
  1796  		_, err = ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
  1797  			Channels: []string{channel1.Id, dmChannel1.Id},
  1798  		})
  1799  		require.NoError(t, err)
  1800  
  1801  		// Do the same on the second team
  1802  		channel2, nErr := ss.Channel().Save(&model.Channel{
  1803  			Name:   model.NewId(),
  1804  			TeamId: teamId2,
  1805  			Type:   model.CHANNEL_OPEN,
  1806  		}, 1000)
  1807  		require.NoError(t, nErr)
  1808  
  1809  		_, err = ss.Channel().CreateSidebarCategory(userId, teamId2, &model.SidebarCategoryWithChannels{
  1810  			Channels: []string{channel2.Id, dmChannel1.Id},
  1811  		})
  1812  		require.NoError(t, err)
  1813  
  1814  		// Confirm that we start with the right number of categories and SidebarChannels entries
  1815  		count, err := s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarCategories WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1816  		require.NoError(t, err)
  1817  		require.Equal(t, int64(8), count)
  1818  
  1819  		count, err = s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarChannels WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1820  		require.NoError(t, err)
  1821  		require.Equal(t, int64(4), count)
  1822  
  1823  		// Leave the first team
  1824  		err = ss.Channel().ClearSidebarOnTeamLeave(userId, teamId)
  1825  		assert.NoError(t, err)
  1826  
  1827  		// Confirm that we have the correct number of categories and SidebarChannels entries left over
  1828  		count, err = s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarCategories WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1829  		require.NoError(t, err)
  1830  		assert.Equal(t, int64(4), count)
  1831  
  1832  		count, err = s.GetMaster().SelectInt("SELECT COUNT(*) FROM SidebarChannels WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
  1833  		require.NoError(t, err)
  1834  		assert.Equal(t, int64(2), count)
  1835  
  1836  		// Confirm that the categories on the second team are unchanged
  1837  		res, err = ss.Channel().GetSidebarCategories(userId, teamId2)
  1838  		require.NoError(t, err)
  1839  		assert.Len(t, res.Categories, 4)
  1840  
  1841  		assert.Equal(t, model.SidebarCategoryCustom, res.Categories[1].Type)
  1842  		assert.Equal(t, []string{channel2.Id, dmChannel1.Id}, res.Categories[1].Channels)
  1843  	})
  1844  }
  1845  
  1846  func testDeleteSidebarCategory(t *testing.T, ss store.Store, s SqlStore) {
  1847  	t.Run("should correctly remove an empty category", func(t *testing.T) {
  1848  		userId, teamId := setupInitialSidebarCategories(t, ss)
  1849  		defer ss.User().PermanentDelete(userId)
  1850  
  1851  		newCategory, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{})
  1852  		require.NoError(t, err)
  1853  		require.NotNil(t, newCategory)
  1854  
  1855  		// Ensure that the category was created properly
  1856  		res, err := ss.Channel().GetSidebarCategories(userId, teamId)
  1857  		require.NoError(t, err)
  1858  		require.Len(t, res.Categories, 4)
  1859  
  1860  		// Then delete it and confirm that was done correctly
  1861  		err = ss.Channel().DeleteSidebarCategory(newCategory.Id)
  1862  		assert.NoError(t, err)
  1863  
  1864  		res, err = ss.Channel().GetSidebarCategories(userId, teamId)
  1865  		require.NoError(t, err)
  1866  		require.Len(t, res.Categories, 3)
  1867  	})
  1868  
  1869  	t.Run("should correctly remove a category and its channels", func(t *testing.T) {
  1870  		userId, teamId := setupInitialSidebarCategories(t, ss)
  1871  		defer ss.User().PermanentDelete(userId)
  1872  
  1873  		user := &model.User{
  1874  			Id: userId,
  1875  		}
  1876  
  1877  		// Create some channels
  1878  		channel1, nErr := ss.Channel().Save(&model.Channel{
  1879  			Name:   model.NewId(),
  1880  			TeamId: teamId,
  1881  			Type:   model.CHANNEL_OPEN,
  1882  		}, 1000)
  1883  		require.NoError(t, nErr)
  1884  		defer ss.Channel().PermanentDelete(channel1.Id)
  1885  
  1886  		channel2, nErr := ss.Channel().Save(&model.Channel{
  1887  			Name:   model.NewId(),
  1888  			TeamId: teamId,
  1889  			Type:   model.CHANNEL_PRIVATE,
  1890  		}, 1000)
  1891  		require.NoError(t, nErr)
  1892  		defer ss.Channel().PermanentDelete(channel2.Id)
  1893  
  1894  		dmChannel1, nErr := ss.Channel().CreateDirectChannel(user, &model.User{
  1895  			Id: model.NewId(),
  1896  		})
  1897  		require.NoError(t, nErr)
  1898  		defer ss.Channel().PermanentDelete(dmChannel1.Id)
  1899  
  1900  		// Assign some of those channels to a custom category
  1901  		newCategory, err := ss.Channel().CreateSidebarCategory(userId, teamId, &model.SidebarCategoryWithChannels{
  1902  			Channels: []string{channel1.Id, channel2.Id, dmChannel1.Id},
  1903  		})
  1904  		require.NoError(t, err)
  1905  		require.NotNil(t, newCategory)
  1906  
  1907  		// Ensure that the categories are set up correctly
  1908  		res, err := ss.Channel().GetSidebarCategories(userId, teamId)
  1909  		require.NoError(t, err)
  1910  		require.Len(t, res.Categories, 4)
  1911  
  1912  		require.Equal(t, model.SidebarCategoryCustom, res.Categories[1].Type)
  1913  		require.Equal(t, []string{channel1.Id, channel2.Id, dmChannel1.Id}, res.Categories[1].Channels)
  1914  
  1915  		// Actually delete the channel
  1916  		err = ss.Channel().DeleteSidebarCategory(newCategory.Id)
  1917  		assert.NoError(t, err)
  1918  
  1919  		// Confirm that the category was deleted...
  1920  		res, err = ss.Channel().GetSidebarCategories(userId, teamId)
  1921  		assert.NoError(t, err)
  1922  		assert.Len(t, res.Categories, 3)
  1923  
  1924  		// ...and that the corresponding SidebarChannel entries were deleted
  1925  		count, countErr := s.GetMaster().SelectInt(`
  1926  			SELECT
  1927  				COUNT(*)
  1928  			FROM
  1929  				SidebarChannels
  1930  			WHERE
  1931  				CategoryId = :CategoryId`, map[string]interface{}{"CategoryId": newCategory.Id})
  1932  		require.NoError(t, countErr)
  1933  		assert.Equal(t, int64(0), count)
  1934  	})
  1935  
  1936  	t.Run("should not allow you to remove non-custom categories", func(t *testing.T) {
  1937  		userId, teamId := setupInitialSidebarCategories(t, ss)
  1938  		defer ss.User().PermanentDelete(userId)
  1939  		res, err := ss.Channel().GetSidebarCategories(userId, teamId)
  1940  		require.NoError(t, err)
  1941  		require.Len(t, res.Categories, 3)
  1942  		require.Equal(t, model.SidebarCategoryFavorites, res.Categories[0].Type)
  1943  		require.Equal(t, model.SidebarCategoryChannels, res.Categories[1].Type)
  1944  		require.Equal(t, model.SidebarCategoryDirectMessages, res.Categories[2].Type)
  1945  
  1946  		err = ss.Channel().DeleteSidebarCategory(res.Categories[0].Id)
  1947  		assert.Error(t, err)
  1948  
  1949  		err = ss.Channel().DeleteSidebarCategory(res.Categories[1].Id)
  1950  		assert.Error(t, err)
  1951  
  1952  		err = ss.Channel().DeleteSidebarCategory(res.Categories[2].Id)
  1953  		assert.Error(t, err)
  1954  	})
  1955  }
  1956  
  1957  func testUpdateSidebarChannelsByPreferences(t *testing.T, ss store.Store) {
  1958  	t.Run("Should be able to update sidebar channels", func(t *testing.T) {
  1959  		userId := model.NewId()
  1960  		teamId := model.NewId()
  1961  
  1962  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1963  		require.NoError(t, nErr)
  1964  
  1965  		channel, nErr := ss.Channel().Save(&model.Channel{
  1966  			Name:   "channel",
  1967  			Type:   model.CHANNEL_OPEN,
  1968  			TeamId: teamId,
  1969  		}, 10)
  1970  		require.NoError(t, nErr)
  1971  
  1972  		err := ss.Channel().UpdateSidebarChannelsByPreferences(&model.Preferences{
  1973  			model.Preference{
  1974  				Name:     channel.Id,
  1975  				Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL,
  1976  				Value:    "true",
  1977  			},
  1978  		})
  1979  		assert.NoError(t, err)
  1980  	})
  1981  
  1982  	t.Run("Should not panic if channel is not found", func(t *testing.T) {
  1983  		userId := model.NewId()
  1984  		teamId := model.NewId()
  1985  
  1986  		nErr := ss.Channel().CreateInitialSidebarCategories(userId, teamId)
  1987  		assert.NoError(t, nErr)
  1988  
  1989  		require.NotPanics(t, func() {
  1990  			_ = ss.Channel().UpdateSidebarChannelsByPreferences(&model.Preferences{
  1991  				model.Preference{
  1992  					Name:     "fakeid",
  1993  					Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL,
  1994  					Value:    "true",
  1995  				},
  1996  			})
  1997  		})
  1998  	})
  1999  }