github.com/mattermost/mattermost-server/v5@v5.39.3/store/storetest/retention_policy_store.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  	"sort"
     8  	"strconv"
     9  	"testing"
    10  
    11  	"github.com/mattermost/mattermost-server/v5/model"
    12  	"github.com/mattermost/mattermost-server/v5/store"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestRetentionPolicyStore(t *testing.T, ss store.Store, s SqlStore) {
    17  	t.Run("Save", func(t *testing.T) { testRetentionPolicyStoreSave(t, ss, s) })
    18  	t.Run("Patch", func(t *testing.T) { testRetentionPolicyStorePatch(t, ss, s) })
    19  	t.Run("Get", func(t *testing.T) { testRetentionPolicyStoreGet(t, ss, s) })
    20  	t.Run("GetCount", func(t *testing.T) { testRetentionPolicyStoreGetCount(t, ss, s) })
    21  	t.Run("Delete", func(t *testing.T) { testRetentionPolicyStoreDelete(t, ss, s) })
    22  	t.Run("GetChannels", func(t *testing.T) { testRetentionPolicyStoreGetChannels(t, ss, s) })
    23  	t.Run("AddChannels", func(t *testing.T) { testRetentionPolicyStoreAddChannels(t, ss, s) })
    24  	t.Run("RemoveChannels", func(t *testing.T) { testRetentionPolicyStoreRemoveChannels(t, ss, s) })
    25  	t.Run("GetTeams", func(t *testing.T) { testRetentionPolicyStoreGetTeams(t, ss, s) })
    26  	t.Run("AddTeams", func(t *testing.T) { testRetentionPolicyStoreAddTeams(t, ss, s) })
    27  	t.Run("RemoveTeams", func(t *testing.T) { testRetentionPolicyStoreRemoveTeams(t, ss, s) })
    28  	t.Run("RemoveOrphanedRows", func(t *testing.T) { testRetentionPolicyStoreRemoveOrphanedRows(t, ss, s) })
    29  	t.Run("GetPoliciesForUser", func(t *testing.T) { testRetentionPolicyStoreGetPoliciesForUser(t, ss, s) })
    30  }
    31  
    32  func getRetentionPolicyWithTeamAndChannelIds(t *testing.T, ss store.Store, policyID string) *model.RetentionPolicyWithTeamAndChannelIDs {
    33  	policyWithCounts, err := ss.RetentionPolicy().Get(policyID)
    34  	require.NoError(t, err)
    35  	policyWithIds := model.RetentionPolicyWithTeamAndChannelIDs{
    36  		RetentionPolicy: model.RetentionPolicy{
    37  			ID:           policyID,
    38  			DisplayName:  policyWithCounts.DisplayName,
    39  			PostDuration: policyWithCounts.PostDuration,
    40  		},
    41  		ChannelIDs: make([]string, int(policyWithCounts.ChannelCount)),
    42  		TeamIDs:    make([]string, int(policyWithCounts.TeamCount)),
    43  	}
    44  	channels, err := ss.RetentionPolicy().GetChannels(policyID, 0, 1000)
    45  	require.NoError(t, err)
    46  	for i, channel := range channels {
    47  		policyWithIds.ChannelIDs[i] = channel.Id
    48  	}
    49  	teams, err := ss.RetentionPolicy().GetTeams(policyID, 0, 1000)
    50  	require.NoError(t, err)
    51  	for i, team := range teams {
    52  		policyWithIds.TeamIDs[i] = team.Id
    53  	}
    54  	return &policyWithIds
    55  }
    56  
    57  func CheckRetentionPolicyWithTeamAndChannelIdsAreEqual(t *testing.T, p1, p2 *model.RetentionPolicyWithTeamAndChannelIDs) {
    58  	require.Equal(t, p1.ID, p2.ID)
    59  	require.Equal(t, p1.DisplayName, p2.DisplayName)
    60  	require.Equal(t, p1.PostDuration, p2.PostDuration)
    61  	require.Equal(t, len(p1.ChannelIDs), len(p2.ChannelIDs))
    62  	if p1.ChannelIDs == nil || p2.ChannelIDs == nil {
    63  		require.Equal(t, p1.ChannelIDs, p2.ChannelIDs)
    64  	} else {
    65  		sort.Strings(p1.ChannelIDs)
    66  		sort.Strings(p2.ChannelIDs)
    67  	}
    68  	for i := range p1.ChannelIDs {
    69  		require.Equal(t, p1.ChannelIDs[i], p2.ChannelIDs[i])
    70  	}
    71  	if p1.TeamIDs == nil || p2.TeamIDs == nil {
    72  		require.Equal(t, p1.TeamIDs, p2.TeamIDs)
    73  	} else {
    74  		sort.Strings(p1.TeamIDs)
    75  		sort.Strings(p2.TeamIDs)
    76  	}
    77  	require.Equal(t, len(p1.TeamIDs), len(p2.TeamIDs))
    78  	for i := range p1.TeamIDs {
    79  		require.Equal(t, p1.TeamIDs[i], p2.TeamIDs[i])
    80  	}
    81  }
    82  
    83  func CheckRetentionPolicyWithTeamAndChannelCountsAreEqual(t *testing.T, p1, p2 *model.RetentionPolicyWithTeamAndChannelCounts) {
    84  	require.Equal(t, p1.ID, p2.ID)
    85  	require.Equal(t, p1.DisplayName, p2.DisplayName)
    86  	require.Equal(t, p1.PostDuration, p2.PostDuration)
    87  	require.Equal(t, p1.ChannelCount, p2.ChannelCount)
    88  	require.Equal(t, p1.TeamCount, p2.TeamCount)
    89  }
    90  
    91  func checkRetentionPolicyLikeThisExists(t *testing.T, ss store.Store, expected *model.RetentionPolicyWithTeamAndChannelIDs) {
    92  	retrieved := getRetentionPolicyWithTeamAndChannelIds(t, ss, expected.ID)
    93  	CheckRetentionPolicyWithTeamAndChannelIdsAreEqual(t, expected, retrieved)
    94  }
    95  
    96  func copyRetentionPolicyWithTeamAndChannelIds(policy *model.RetentionPolicyWithTeamAndChannelIDs) *model.RetentionPolicyWithTeamAndChannelIDs {
    97  	copy := &model.RetentionPolicyWithTeamAndChannelIDs{
    98  		RetentionPolicy: policy.RetentionPolicy,
    99  		ChannelIDs:      make([]string, len(policy.ChannelIDs)),
   100  		TeamIDs:         make([]string, len(policy.TeamIDs)),
   101  	}
   102  	for i, channelID := range policy.ChannelIDs {
   103  		copy.ChannelIDs[i] = channelID
   104  	}
   105  	for i, teamID := range policy.TeamIDs {
   106  		copy.TeamIDs[i] = teamID
   107  	}
   108  	return copy
   109  }
   110  
   111  func createChannelsForRetentionPolicy(t *testing.T, ss store.Store, teamId string, numChannels int) (channelIDs []string) {
   112  	channelIDs = make([]string, numChannels)
   113  	for i := range channelIDs {
   114  		name := "channel" + model.NewId()
   115  		channel := &model.Channel{
   116  			TeamId:      teamId,
   117  			DisplayName: "Channel " + name,
   118  			Name:        name,
   119  			Type:        model.CHANNEL_OPEN,
   120  		}
   121  		channel, err := ss.Channel().Save(channel, -1)
   122  		require.NoError(t, err)
   123  		channelIDs[i] = channel.Id
   124  	}
   125  	return
   126  }
   127  
   128  func createTeamsForRetentionPolicy(t *testing.T, ss store.Store, numTeams int) (teamIDs []string) {
   129  	teamIDs = make([]string, numTeams)
   130  	for i := range teamIDs {
   131  		name := "team" + model.NewId()
   132  		team := &model.Team{
   133  			DisplayName: "Team " + name,
   134  			Name:        name,
   135  			Type:        model.TEAM_OPEN,
   136  		}
   137  		team, err := ss.Team().Save(team)
   138  		require.NoError(t, err)
   139  		teamIDs[i] = team.Id
   140  	}
   141  	return
   142  }
   143  
   144  func createTeamsAndChannelsForRetentionPolicy(t *testing.T, ss store.Store) (teamIDs, channelIDs []string) {
   145  	teamIDs = createTeamsForRetentionPolicy(t, ss, 2)
   146  	channels1 := createChannelsForRetentionPolicy(t, ss, teamIDs[0], 1)
   147  	channels2 := createChannelsForRetentionPolicy(t, ss, teamIDs[1], 2)
   148  	channelIDs = append(channels1, channels2...)
   149  	return
   150  }
   151  
   152  func cleanupRetentionPolicyTest(s SqlStore) {
   153  	// Manually clear tables until testlib can handle cleanups
   154  	tables := []string{"RetentionPolicies", "RetentionPoliciesChannels", "RetentionPoliciesTeams"}
   155  	for _, table := range tables {
   156  		if _, err := s.GetMaster().Exec("DELETE FROM " + table); err != nil {
   157  			panic(err)
   158  		}
   159  	}
   160  }
   161  
   162  func deleteTeamsAndChannels(ss store.Store, teamIDs, channelIDs []string) {
   163  	for _, teamID := range teamIDs {
   164  		if err := ss.Team().PermanentDelete(teamID); err != nil {
   165  			panic(err)
   166  		}
   167  	}
   168  	for _, channelID := range channelIDs {
   169  		if err := ss.Channel().PermanentDelete(channelID); err != nil {
   170  			panic(err)
   171  		}
   172  	}
   173  }
   174  
   175  func createRetentionPolicyWithTeamAndChannelIds(displayName string, teamIDs, channelIDs []string) *model.RetentionPolicyWithTeamAndChannelIDs {
   176  	return &model.RetentionPolicyWithTeamAndChannelIDs{
   177  		RetentionPolicy: model.RetentionPolicy{
   178  			DisplayName:  displayName,
   179  			PostDuration: model.NewInt64(30),
   180  		},
   181  		TeamIDs:    teamIDs,
   182  		ChannelIDs: channelIDs,
   183  	}
   184  }
   185  
   186  // saveRetentionPolicyWithTeamAndChannelIds creates a model.RetentionPolicyWithTeamAndChannelIds struct using
   187  // the display name, team IDs, and channel IDs. The new policy ID will be assigned to the struct and returned.
   188  // The team IDs and channel IDs are kept the same.
   189  func saveRetentionPolicyWithTeamAndChannelIds(t *testing.T, ss store.Store, displayName string, teamIDs, channelIDs []string) *model.RetentionPolicyWithTeamAndChannelIDs {
   190  	proposal := createRetentionPolicyWithTeamAndChannelIds(displayName, teamIDs, channelIDs)
   191  	policyWithCounts, err := ss.RetentionPolicy().Save(proposal)
   192  	require.NoError(t, err)
   193  	proposal.ID = policyWithCounts.ID
   194  	return proposal
   195  }
   196  
   197  func restoreRetentionPolicy(t *testing.T, ss store.Store, policy *model.RetentionPolicyWithTeamAndChannelIDs) {
   198  	_, err := ss.RetentionPolicy().Patch(policy)
   199  	require.NoError(t, err)
   200  	checkRetentionPolicyLikeThisExists(t, ss, policy)
   201  }
   202  
   203  func testRetentionPolicyStoreSave(t *testing.T, ss store.Store, s SqlStore) {
   204  	defer cleanupRetentionPolicyTest(s)
   205  
   206  	t.Run("teams and channels are nil", func(t *testing.T) {
   207  		policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", nil, nil)
   208  		policy.ChannelIDs = []string{}
   209  		policy.TeamIDs = []string{}
   210  		checkRetentionPolicyLikeThisExists(t, ss, policy)
   211  	})
   212  	t.Run("teams and channels are empty", func(t *testing.T) {
   213  		policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 2", []string{}, []string{})
   214  		checkRetentionPolicyLikeThisExists(t, ss, policy)
   215  	})
   216  	t.Run("some teams and channels are specified", func(t *testing.T) {
   217  		teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   218  		defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   219  		policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 3", teamIDs, channelIDs)
   220  		checkRetentionPolicyLikeThisExists(t, ss, policy)
   221  	})
   222  	t.Run("team specified does not exist", func(t *testing.T) {
   223  		policy := createRetentionPolicyWithTeamAndChannelIds("Policy 4", []string{"no_such_team"}, []string{})
   224  		_, err := ss.RetentionPolicy().Save(policy)
   225  		require.Error(t, err)
   226  	})
   227  	t.Run("channel specified does not exist", func(t *testing.T) {
   228  		policy := createRetentionPolicyWithTeamAndChannelIds("Policy 5", []string{}, []string{"no_such_channel"})
   229  		_, err := ss.RetentionPolicy().Save(policy)
   230  		require.Error(t, err)
   231  	})
   232  }
   233  
   234  func testRetentionPolicyStorePatch(t *testing.T, ss store.Store, s SqlStore) {
   235  	teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   236  	policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", teamIDs, channelIDs)
   237  
   238  	defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   239  	defer cleanupRetentionPolicyTest(s)
   240  
   241  	t.Run("modify DisplayName", func(t *testing.T) {
   242  		patch := &model.RetentionPolicyWithTeamAndChannelIDs{
   243  			RetentionPolicy: model.RetentionPolicy{
   244  				ID:          policy.ID,
   245  				DisplayName: "something new",
   246  			},
   247  		}
   248  		_, err := ss.RetentionPolicy().Patch(patch)
   249  		require.NoError(t, err)
   250  		expected := copyRetentionPolicyWithTeamAndChannelIds(policy)
   251  		expected.DisplayName = patch.DisplayName
   252  		checkRetentionPolicyLikeThisExists(t, ss, expected)
   253  		restoreRetentionPolicy(t, ss, policy)
   254  	})
   255  	t.Run("modify PostDuration", func(t *testing.T) {
   256  		patch := &model.RetentionPolicyWithTeamAndChannelIDs{
   257  			RetentionPolicy: model.RetentionPolicy{
   258  				ID:           policy.ID,
   259  				PostDuration: model.NewInt64(10000),
   260  			},
   261  		}
   262  		_, err := ss.RetentionPolicy().Patch(patch)
   263  		require.NoError(t, err)
   264  		expected := copyRetentionPolicyWithTeamAndChannelIds(policy)
   265  		expected.PostDuration = patch.PostDuration
   266  		checkRetentionPolicyLikeThisExists(t, ss, expected)
   267  
   268  		// Store a negative value (= infinity)
   269  		patch.PostDuration = model.NewInt64(-1)
   270  		_, err = ss.RetentionPolicy().Patch(patch)
   271  		require.NoError(t, err)
   272  		expected = copyRetentionPolicyWithTeamAndChannelIds(policy)
   273  		expected.PostDuration = patch.PostDuration
   274  		checkRetentionPolicyLikeThisExists(t, ss, expected)
   275  
   276  		restoreRetentionPolicy(t, ss, policy)
   277  	})
   278  	t.Run("clear TeamIds", func(t *testing.T) {
   279  		patch := &model.RetentionPolicyWithTeamAndChannelIDs{
   280  			RetentionPolicy: model.RetentionPolicy{
   281  				ID: policy.ID,
   282  			},
   283  			TeamIDs: make([]string, 0),
   284  		}
   285  		_, err := ss.RetentionPolicy().Patch(patch)
   286  		require.NoError(t, err)
   287  		expected := copyRetentionPolicyWithTeamAndChannelIds(policy)
   288  		expected.TeamIDs = make([]string, 0)
   289  		checkRetentionPolicyLikeThisExists(t, ss, expected)
   290  		restoreRetentionPolicy(t, ss, policy)
   291  	})
   292  	t.Run("add team which does not exist", func(t *testing.T) {
   293  		patch := &model.RetentionPolicyWithTeamAndChannelIDs{
   294  			RetentionPolicy: model.RetentionPolicy{
   295  				ID: policy.ID,
   296  			},
   297  			TeamIDs: []string{"no_such_team"},
   298  		}
   299  		_, err := ss.RetentionPolicy().Patch(patch)
   300  		require.Error(t, err)
   301  	})
   302  	t.Run("clear ChannelIds", func(t *testing.T) {
   303  		patch := &model.RetentionPolicyWithTeamAndChannelIDs{
   304  			RetentionPolicy: model.RetentionPolicy{
   305  				ID: policy.ID,
   306  			},
   307  			ChannelIDs: make([]string, 0),
   308  		}
   309  		_, err := ss.RetentionPolicy().Patch(patch)
   310  		require.NoError(t, err)
   311  		expected := copyRetentionPolicyWithTeamAndChannelIds(policy)
   312  		expected.ChannelIDs = make([]string, 0)
   313  		checkRetentionPolicyLikeThisExists(t, ss, expected)
   314  		restoreRetentionPolicy(t, ss, policy)
   315  	})
   316  	t.Run("add channel which does not exist", func(t *testing.T) {
   317  		patch := &model.RetentionPolicyWithTeamAndChannelIDs{
   318  			RetentionPolicy: model.RetentionPolicy{
   319  				ID: policy.ID,
   320  			},
   321  			ChannelIDs: []string{"no_such_channel"},
   322  		}
   323  		_, err := ss.RetentionPolicy().Patch(patch)
   324  		require.Error(t, err)
   325  	})
   326  }
   327  
   328  func testRetentionPolicyStoreGet(t *testing.T, ss store.Store, s SqlStore) {
   329  	// create multiple policies
   330  	policiesWithCounts := make([]*model.RetentionPolicyWithTeamAndChannelCounts, 0)
   331  	for i := 0; i < 3; i++ {
   332  		teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   333  		defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   334  		policyWithIds := createRetentionPolicyWithTeamAndChannelIds(
   335  			"Policy "+strconv.Itoa(i+1), teamIDs, channelIDs)
   336  		policyWithCounts, err := ss.RetentionPolicy().Save(policyWithIds)
   337  		require.NoError(t, err)
   338  		policiesWithCounts = append(policiesWithCounts, policyWithCounts)
   339  	}
   340  	defer cleanupRetentionPolicyTest(s)
   341  
   342  	t.Run("get all", func(t *testing.T) {
   343  		retrievedPolicies, err := ss.RetentionPolicy().GetAll(0, 60)
   344  		require.NoError(t, err)
   345  		require.Equal(t, len(policiesWithCounts), len(retrievedPolicies))
   346  		for i := range policiesWithCounts {
   347  			CheckRetentionPolicyWithTeamAndChannelCountsAreEqual(t, policiesWithCounts[i], retrievedPolicies[i])
   348  		}
   349  	})
   350  	t.Run("get all with limit", func(t *testing.T) {
   351  		for i := range policiesWithCounts {
   352  			retrievedPolicies, err := ss.RetentionPolicy().GetAll(i, 1)
   353  			require.NoError(t, err)
   354  			require.Equal(t, 1, len(retrievedPolicies))
   355  			CheckRetentionPolicyWithTeamAndChannelCountsAreEqual(t, policiesWithCounts[i], retrievedPolicies[0])
   356  		}
   357  	})
   358  	t.Run("get all with same display name", func(t *testing.T) {
   359  		for i := 0; i < 5; i++ {
   360  			teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   361  			defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   362  			proposal := createRetentionPolicyWithTeamAndChannelIds(
   363  				"Policy Name", teamIDs, channelIDs)
   364  			_, err := ss.RetentionPolicy().Save(proposal)
   365  			require.NoError(t, err)
   366  		}
   367  		policies, err := ss.RetentionPolicy().GetAll(0, 60)
   368  		require.NoError(t, err)
   369  		for i := 1; i < len(policies); i++ {
   370  			require.True(t,
   371  				policies[i-1].DisplayName < policies[i].DisplayName ||
   372  					(policies[i-1].DisplayName == policies[i].DisplayName &&
   373  						policies[i-1].ID < policies[i].ID),
   374  				"policies with the same display name should be sorted by ID")
   375  		}
   376  	})
   377  }
   378  
   379  func testRetentionPolicyStoreGetCount(t *testing.T, ss store.Store, s SqlStore) {
   380  	defer cleanupRetentionPolicyTest(s)
   381  
   382  	t.Run("no policies", func(t *testing.T) {
   383  		count, err := ss.RetentionPolicy().GetCount()
   384  		require.NoError(t, err)
   385  		require.Equal(t, int64(0), count)
   386  	})
   387  	t.Run("some policies", func(t *testing.T) {
   388  		for i := 0; i < 2; i++ {
   389  			saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy "+strconv.Itoa(i), nil, nil)
   390  		}
   391  		count, err := ss.RetentionPolicy().GetCount()
   392  		require.NoError(t, err)
   393  		require.Equal(t, int64(2), count)
   394  	})
   395  }
   396  
   397  func testRetentionPolicyStoreDelete(t *testing.T, ss store.Store, s SqlStore) {
   398  	teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   399  	policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", teamIDs, channelIDs)
   400  
   401  	defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   402  	defer cleanupRetentionPolicyTest(s)
   403  
   404  	t.Run("delete policy", func(t *testing.T) {
   405  		err := ss.RetentionPolicy().Delete(policy.ID)
   406  		require.NoError(t, err)
   407  		policies, err := ss.RetentionPolicy().GetAll(0, 1)
   408  		require.NoError(t, err)
   409  		require.Empty(t, policies)
   410  	})
   411  }
   412  
   413  func testRetentionPolicyStoreGetChannels(t *testing.T, ss store.Store, s SqlStore) {
   414  	defer cleanupRetentionPolicyTest(s)
   415  
   416  	t.Run("no channels", func(t *testing.T) {
   417  		policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", nil, nil)
   418  		channels, err := ss.RetentionPolicy().GetChannels(policy.ID, 0, 1)
   419  		require.NoError(t, err)
   420  		require.Len(t, channels, 0)
   421  	})
   422  	t.Run("some channels", func(t *testing.T) {
   423  		teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   424  		defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   425  		policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 2", teamIDs, channelIDs)
   426  		channels, err := ss.RetentionPolicy().GetChannels(policy.ID, 0, len(channelIDs))
   427  		require.NoError(t, err)
   428  		require.Len(t, channels, len(channelIDs))
   429  		sort.Strings(channelIDs)
   430  		sort.Slice(channels, func(i, j int) bool {
   431  			return channels[i].Id < channels[j].Id
   432  		})
   433  		for i := range channelIDs {
   434  			require.Equal(t, channelIDs[i], channels[i].Id)
   435  		}
   436  	})
   437  }
   438  
   439  func testRetentionPolicyStoreAddChannels(t *testing.T, ss store.Store, s SqlStore) {
   440  	teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   441  	policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", teamIDs, channelIDs)
   442  
   443  	defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   444  	defer cleanupRetentionPolicyTest(s)
   445  
   446  	t.Run("add empty array", func(t *testing.T) {
   447  		err := ss.RetentionPolicy().AddChannels(policy.ID, []string{})
   448  		require.NoError(t, err)
   449  		checkRetentionPolicyLikeThisExists(t, ss, policy)
   450  	})
   451  	t.Run("add new channels", func(t *testing.T) {
   452  		channelIDs := createChannelsForRetentionPolicy(t, ss, teamIDs[0], 2)
   453  		defer deleteTeamsAndChannels(ss, nil, channelIDs)
   454  		err := ss.RetentionPolicy().AddChannels(policy.ID, channelIDs)
   455  		require.NoError(t, err)
   456  		// verify that the channels were actually added
   457  		copy := copyRetentionPolicyWithTeamAndChannelIds(policy)
   458  		copy.ChannelIDs = append(copy.ChannelIDs, channelIDs...)
   459  		checkRetentionPolicyLikeThisExists(t, ss, copy)
   460  		restoreRetentionPolicy(t, ss, policy)
   461  	})
   462  	t.Run("add channel which does not exist", func(t *testing.T) {
   463  		err := ss.RetentionPolicy().AddChannels(policy.ID, []string{"no_such_channel"})
   464  		require.Error(t, err)
   465  	})
   466  	t.Run("add channel to policy which does not exist", func(t *testing.T) {
   467  		channelIDs := createChannelsForRetentionPolicy(t, ss, teamIDs[0], 1)
   468  		defer deleteTeamsAndChannels(ss, nil, channelIDs)
   469  		err := ss.RetentionPolicy().AddChannels("no_such_policy", channelIDs)
   470  		require.Error(t, err)
   471  	})
   472  }
   473  
   474  func testRetentionPolicyStoreRemoveChannels(t *testing.T, ss store.Store, s SqlStore) {
   475  	teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   476  	policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", teamIDs, channelIDs)
   477  
   478  	defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   479  	defer cleanupRetentionPolicyTest(s)
   480  
   481  	t.Run("remove empty array", func(t *testing.T) {
   482  		err := ss.RetentionPolicy().RemoveChannels(policy.ID, []string{})
   483  		require.NoError(t, err)
   484  		checkRetentionPolicyLikeThisExists(t, ss, policy)
   485  	})
   486  	t.Run("remove existing channel", func(t *testing.T) {
   487  		channelID := channelIDs[0]
   488  		err := ss.RetentionPolicy().RemoveChannels(policy.ID, []string{channelID})
   489  		require.NoError(t, err)
   490  		// verify that the channel was actually removed
   491  		copy := copyRetentionPolicyWithTeamAndChannelIds(policy)
   492  		copy.ChannelIDs = make([]string, 0)
   493  		for _, oldChannelID := range policy.ChannelIDs {
   494  			if oldChannelID != channelID {
   495  				copy.ChannelIDs = append(copy.ChannelIDs, oldChannelID)
   496  			}
   497  		}
   498  		checkRetentionPolicyLikeThisExists(t, ss, copy)
   499  		restoreRetentionPolicy(t, ss, policy)
   500  	})
   501  	t.Run("remove channel which does not exist", func(t *testing.T) {
   502  		err := ss.RetentionPolicy().RemoveChannels(policy.ID, []string{"no_such_channel"})
   503  		require.NoError(t, err)
   504  		// verify that the policy did not change
   505  		checkRetentionPolicyLikeThisExists(t, ss, policy)
   506  	})
   507  }
   508  
   509  func testRetentionPolicyStoreGetTeams(t *testing.T, ss store.Store, s SqlStore) {
   510  	defer cleanupRetentionPolicyTest(s)
   511  
   512  	t.Run("no teams", func(t *testing.T) {
   513  		policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", nil, nil)
   514  		teams, err := ss.RetentionPolicy().GetTeams(policy.ID, 0, 1)
   515  		require.NoError(t, err)
   516  		require.Len(t, teams, 0)
   517  	})
   518  	t.Run("some teams", func(t *testing.T) {
   519  		teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   520  		defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   521  		policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 2", teamIDs, channelIDs)
   522  		teams, err := ss.RetentionPolicy().GetTeams(policy.ID, 0, len(teamIDs))
   523  		require.NoError(t, err)
   524  		require.Len(t, teams, len(teamIDs))
   525  		sort.Strings(teamIDs)
   526  		sort.Slice(teams, func(i, j int) bool {
   527  			return teams[i].Id < teams[j].Id
   528  		})
   529  		for i := range teamIDs {
   530  			require.Equal(t, teamIDs[i], teams[i].Id)
   531  		}
   532  	})
   533  }
   534  
   535  func testRetentionPolicyStoreAddTeams(t *testing.T, ss store.Store, s SqlStore) {
   536  	teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   537  	policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", teamIDs, channelIDs)
   538  
   539  	defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   540  	defer cleanupRetentionPolicyTest(s)
   541  
   542  	t.Run("add empty array", func(t *testing.T) {
   543  		err := ss.RetentionPolicy().AddTeams(policy.ID, []string{})
   544  		require.NoError(t, err)
   545  		checkRetentionPolicyLikeThisExists(t, ss, policy)
   546  	})
   547  	t.Run("add new teams", func(t *testing.T) {
   548  		teamIDs := createTeamsForRetentionPolicy(t, ss, 2)
   549  		defer deleteTeamsAndChannels(ss, teamIDs, nil)
   550  		err := ss.RetentionPolicy().AddTeams(policy.ID, teamIDs)
   551  		require.NoError(t, err)
   552  		// verify that the teams were actually added
   553  		copy := copyRetentionPolicyWithTeamAndChannelIds(policy)
   554  		copy.TeamIDs = append(copy.TeamIDs, teamIDs...)
   555  		checkRetentionPolicyLikeThisExists(t, ss, copy)
   556  		restoreRetentionPolicy(t, ss, policy)
   557  	})
   558  	t.Run("add team which does not exist", func(t *testing.T) {
   559  		err := ss.RetentionPolicy().AddTeams(policy.ID, []string{"no_such_team"})
   560  		require.Error(t, err)
   561  	})
   562  	t.Run("add team to policy which does not exist", func(t *testing.T) {
   563  		teamIDs := createTeamsForRetentionPolicy(t, ss, 1)
   564  		defer deleteTeamsAndChannels(ss, teamIDs, nil)
   565  		err := ss.RetentionPolicy().AddTeams("no_such_policy", teamIDs)
   566  		require.Error(t, err)
   567  	})
   568  }
   569  
   570  func testRetentionPolicyStoreRemoveTeams(t *testing.T, ss store.Store, s SqlStore) {
   571  	teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   572  	policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", teamIDs, channelIDs)
   573  
   574  	defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   575  	defer cleanupRetentionPolicyTest(s)
   576  
   577  	t.Run("remove empty array", func(t *testing.T) {
   578  		err := ss.RetentionPolicy().RemoveTeams(policy.ID, []string{})
   579  		require.NoError(t, err)
   580  		checkRetentionPolicyLikeThisExists(t, ss, policy)
   581  	})
   582  	t.Run("remove existing team", func(t *testing.T) {
   583  		teamID := teamIDs[0]
   584  		err := ss.RetentionPolicy().RemoveTeams(policy.ID, []string{teamID})
   585  		require.NoError(t, err)
   586  		// verify that the team was actually removed
   587  		copy := copyRetentionPolicyWithTeamAndChannelIds(policy)
   588  		copy.TeamIDs = make([]string, 0)
   589  		for _, oldTeamID := range policy.TeamIDs {
   590  			if oldTeamID != teamID {
   591  				copy.TeamIDs = append(copy.TeamIDs, oldTeamID)
   592  			}
   593  		}
   594  		checkRetentionPolicyLikeThisExists(t, ss, copy)
   595  		restoreRetentionPolicy(t, ss, policy)
   596  	})
   597  	t.Run("remove team which does not exist", func(t *testing.T) {
   598  		err := ss.RetentionPolicy().RemoveTeams(policy.ID, []string{"no_such_team"})
   599  		require.NoError(t, err)
   600  		// verify that the policy did not change
   601  		checkRetentionPolicyLikeThisExists(t, ss, policy)
   602  	})
   603  }
   604  
   605  func testRetentionPolicyStoreGetPoliciesForUser(t *testing.T, ss store.Store, s SqlStore) {
   606  	teamIDs, channelIDs := createTeamsAndChannelsForRetentionPolicy(t, ss)
   607  	saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1", teamIDs, channelIDs)
   608  
   609  	defer deleteTeamsAndChannels(ss, teamIDs, channelIDs)
   610  	defer cleanupRetentionPolicyTest(s)
   611  
   612  	user, userSaveErr := ss.User().Save(&model.User{
   613  		Email:    MakeEmail(),
   614  		Username: model.NewId(),
   615  	})
   616  	require.NoError(t, userSaveErr)
   617  
   618  	t.Run("user has no relevant policies", func(t *testing.T) {
   619  		// Teams
   620  		teamPolicies, err := ss.RetentionPolicy().GetTeamPoliciesForUser(user.Id, 0, 100)
   621  		require.NoError(t, err)
   622  		require.Empty(t, teamPolicies)
   623  		count, err := ss.RetentionPolicy().GetTeamPoliciesCountForUser(user.Id)
   624  		require.NoError(t, err)
   625  		require.Equal(t, int64(0), count)
   626  		// Channels
   627  		channelPolicies, err := ss.RetentionPolicy().GetChannelPoliciesForUser(user.Id, 0, 100)
   628  		require.NoError(t, err)
   629  		require.Empty(t, channelPolicies)
   630  		count, err = ss.RetentionPolicy().GetChannelPoliciesCountForUser(user.Id)
   631  		require.NoError(t, err)
   632  		require.Equal(t, int64(0), count)
   633  	})
   634  
   635  	t.Run("user has relevant policies", func(t *testing.T) {
   636  		for _, teamID := range teamIDs {
   637  			_, err := ss.Team().SaveMember(&model.TeamMember{TeamId: teamID, UserId: user.Id}, -1)
   638  			require.NoError(t, err)
   639  		}
   640  		for _, channelID := range channelIDs {
   641  			_, err := ss.Channel().SaveMember(&model.ChannelMember{ChannelId: channelID, UserId: user.Id, NotifyProps: model.GetDefaultChannelNotifyProps()})
   642  			require.NoError(t, err)
   643  		}
   644  		// Teams
   645  		teamPolicies, err := ss.RetentionPolicy().GetTeamPoliciesForUser(user.Id, 0, 100)
   646  		require.NoError(t, err)
   647  		require.Len(t, teamPolicies, len(teamIDs))
   648  		count, err := ss.RetentionPolicy().GetTeamPoliciesCountForUser(user.Id)
   649  		require.NoError(t, err)
   650  		require.Equal(t, int64(len(teamIDs)), count)
   651  		// Channels
   652  		channelPolicies, err := ss.RetentionPolicy().GetChannelPoliciesForUser(user.Id, 0, 100)
   653  		require.NoError(t, err)
   654  		require.Len(t, channelPolicies, len(channelIDs))
   655  		count, err = ss.RetentionPolicy().GetChannelPoliciesCountForUser(user.Id)
   656  		require.NoError(t, err)
   657  		require.Equal(t, int64(len(channelIDs)), count)
   658  	})
   659  }
   660  
   661  func testRetentionPolicyStoreRemoveOrphanedRows(t *testing.T, ss store.Store, s SqlStore) {
   662  	teamID := createTeamsForRetentionPolicy(t, ss, 1)[0]
   663  	channelID := createChannelsForRetentionPolicy(t, ss, teamID, 1)[0]
   664  	policy := saveRetentionPolicyWithTeamAndChannelIds(t, ss, "Policy 1",
   665  		[]string{teamID}, []string{channelID})
   666  
   667  	err := ss.Channel().PermanentDelete(channelID)
   668  	require.NoError(t, err)
   669  	err = ss.Team().PermanentDelete(teamID)
   670  	require.NoError(t, err)
   671  	_, err = ss.RetentionPolicy().DeleteOrphanedRows(1000)
   672  	require.NoError(t, err)
   673  
   674  	policy.ChannelIDs = make([]string, 0)
   675  	policy.TeamIDs = make([]string, 0)
   676  	checkRetentionPolicyLikeThisExists(t, ss, policy)
   677  }