[MM-18946] [MM-26721] [MM-6842] Cross team search+private channel autocomplete (#18468)
* Show private channels in autocomplete This is supported in all Engines: MySQL, Postgres, Bleve, Elasticsearch. https://mattermost.atlassian.net/browse/MM-18496 ```release-note Private channels will now appear in channel autocomplete. If you are using Bleve or ElasticSearch, you will have to reindex the channels again to populate them with the new attributes. ``` A large chunk of this work has been based on the earlier effort at https://github.com/mattermost/mattermost-server/pull/17804. Full credit goes to https://github.com/arvinDarmawan. * Add comment ```release-note NONE ``` * Adding more tests ```release-note NONE ``` * fix more tests ```release-note NONE ``` * tmp ```release-note NONE ``` * more fixes ```release-note NONE ``` * add tests ```release-note NONE ``` * Add review comments from previous PR ```release-note NONE ``` * Add API to return all channels from all team ```release-note NONE ``` * Added support for bleve and ES ```release-note NONE ``` * Streaming response for GetAllChannels ```release-note NONE ``` * Fix tests ```release-note NONE ``` * Trigger CI ```release-note NONE ``` * fix tests ```release-note NONE ``` * Addressing review comments ```release-note NONE ``` * Fix lint ```release-note NONE ``` * Removing flaky test ```release-note NONE ``` * Address comments ```release-note NONE ``` * Trigger CI ```release-note NONE ``` * Added /users/<userid>/channel_members endpoint ```release-note NONE ``` * Minor edit ```release-note NONE ``` * Improve embedding ```release-note NONE ``` * Fix lint error ```release-note NONE ``` Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
971af6935c
Коммит
e24f22745e
@@ -61,6 +61,7 @@ func TestChannelStore(t *testing.T, ss store.Store, s SqlStore) {
|
||||
t.Run("GetChannelUnread", func(t *testing.T) { testGetChannelUnread(t, ss) })
|
||||
t.Run("Get", func(t *testing.T) { testChannelStoreGet(t, ss, s) })
|
||||
t.Run("GetChannelsByIds", func(t *testing.T) { testChannelStoreGetChannelsByIds(t, ss) })
|
||||
t.Run("GetChannelsWithTeamDataByIds", func(t *testing.T) { testGetChannelsWithTeamDataByIds(t, ss) })
|
||||
t.Run("GetForPost", func(t *testing.T) { testChannelStoreGetForPost(t, ss) })
|
||||
t.Run("Restore", func(t *testing.T) { testChannelStoreRestore(t, ss) })
|
||||
t.Run("Delete", func(t *testing.T) { testChannelStoreDelete(t, ss) })
|
||||
@@ -78,6 +79,7 @@ func TestChannelStore(t *testing.T, ss store.Store, s SqlStore) {
|
||||
t.Run("RemoveMembers", func(t *testing.T) { testChannelRemoveMembers(t, ss) })
|
||||
t.Run("ChannelDeleteMemberStore", func(t *testing.T) { testChannelDeleteMemberStore(t, ss) })
|
||||
t.Run("GetChannels", func(t *testing.T) { testChannelStoreGetChannels(t, ss) })
|
||||
t.Run("GetChannelsByUser", func(t *testing.T) { testChannelStoreGetChannelsByUser(t, ss) })
|
||||
t.Run("GetAllChannels", func(t *testing.T) { testChannelStoreGetAllChannels(t, ss, s) })
|
||||
t.Run("GetMoreChannels", func(t *testing.T) { testChannelStoreGetMoreChannels(t, ss) })
|
||||
t.Run("GetPrivateChannelsForTeam", func(t *testing.T) { testChannelStoreGetPrivateChannelsForTeam(t, ss) })
|
||||
@@ -97,6 +99,7 @@ func TestChannelStore(t *testing.T, ss store.Store, s SqlStore) {
|
||||
t.Run("GetGuestCount", func(t *testing.T) { testGetGuestCount(t, ss) })
|
||||
t.Run("SearchMore", func(t *testing.T) { testChannelStoreSearchMore(t, ss) })
|
||||
t.Run("SearchInTeam", func(t *testing.T) { testChannelStoreSearchInTeam(t, ss) })
|
||||
t.Run("Autocomplete", func(t *testing.T) { testAutocomplete(t, ss) })
|
||||
t.Run("SearchArchivedInTeam", func(t *testing.T) { testChannelStoreSearchArchivedInTeam(t, ss, s) })
|
||||
t.Run("SearchForUserInTeam", func(t *testing.T) { testChannelStoreSearchForUserInTeam(t, ss) })
|
||||
t.Run("SearchAllChannels", func(t *testing.T) { testChannelStoreSearchAllChannels(t, ss) })
|
||||
@@ -536,6 +539,81 @@ func testChannelStoreGetChannelsByIds(t *testing.T, ss store.Store) {
|
||||
})
|
||||
}
|
||||
|
||||
func testGetChannelsWithTeamDataByIds(t *testing.T, ss store.Store) {
|
||||
t1 := &model.Team{
|
||||
DisplayName: "DisplayName",
|
||||
Name: NewTestId(),
|
||||
Email: MakeEmail(),
|
||||
Type: model.TeamOpen,
|
||||
}
|
||||
|
||||
t1, err := ss.Team().Save(t1)
|
||||
require.NoError(t, err, "couldn't save item")
|
||||
|
||||
c1 := model.Channel{}
|
||||
c1.TeamId = t1.Id
|
||||
c1.DisplayName = "Name"
|
||||
c1.Name = "aa" + model.NewId()
|
||||
c1.Type = model.ChannelTypeOpen
|
||||
_, nErr := ss.Channel().Save(&c1, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
u1 := &model.User{}
|
||||
u1.Email = MakeEmail()
|
||||
u1.Nickname = model.NewId()
|
||||
_, err = ss.User().Save(u1)
|
||||
require.NoError(t, err)
|
||||
_, nErr = ss.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u1.Id}, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
u2 := model.User{}
|
||||
u2.Email = MakeEmail()
|
||||
u2.Nickname = model.NewId()
|
||||
_, err = ss.User().Save(&u2)
|
||||
require.NoError(t, err)
|
||||
_, nErr = ss.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u2.Id}, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
c2 := model.Channel{}
|
||||
c2.TeamId = t1.Id
|
||||
c2.DisplayName = "Direct Name"
|
||||
c2.Name = "bb" + model.NewId()
|
||||
c2.Type = model.ChannelTypeDirect
|
||||
|
||||
c3 := model.Channel{}
|
||||
c3.TeamId = t1.Id
|
||||
c3.DisplayName = "Deleted channel"
|
||||
c3.Name = "cc" + model.NewId()
|
||||
c3.Type = model.ChannelTypeOpen
|
||||
_, nErr = ss.Channel().Save(&c3, -1)
|
||||
require.NoError(t, nErr)
|
||||
nErr = ss.Channel().Delete(c3.Id, 123)
|
||||
require.NoError(t, nErr)
|
||||
c3.DeleteAt = 123
|
||||
c3.UpdateAt = 123
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = c2.Id
|
||||
m1.UserId = u1.Id
|
||||
m1.NotifyProps = model.GetDefaultChannelNotifyProps()
|
||||
|
||||
m2 := model.ChannelMember{}
|
||||
m2.ChannelId = c2.Id
|
||||
m2.UserId = u2.Id
|
||||
m2.NotifyProps = model.GetDefaultChannelNotifyProps()
|
||||
|
||||
_, nErr = ss.Channel().SaveDirectChannel(&c2, &m1, &m2)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
res, err := ss.Channel().GetChannelsWithTeamDataByIds([]string{c1.Id, c2.Id}, false)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, res, 2)
|
||||
assert.Equal(t, res[0].Id, c1.Id)
|
||||
assert.Equal(t, res[0].TeamName, t1.Name)
|
||||
assert.Equal(t, res[1].Id, c2.Id)
|
||||
assert.Equal(t, res[1].TeamName, "")
|
||||
}
|
||||
|
||||
func testChannelStoreGetForPost(t *testing.T, ss store.Store) {
|
||||
|
||||
ch := &model.Channel{
|
||||
@@ -3317,6 +3395,97 @@ func testChannelStoreGetChannels(t *testing.T, ss store.Store) {
|
||||
ss.Channel().InvalidateAllChannelMembersForUser(m1.UserId)
|
||||
}
|
||||
|
||||
func testChannelStoreGetChannelsByUser(t *testing.T, ss store.Store) {
|
||||
team := model.NewId()
|
||||
team2 := model.NewId()
|
||||
o1 := model.Channel{}
|
||||
o1.TeamId = team
|
||||
o1.DisplayName = "Channel1"
|
||||
o1.Name = NewTestId()
|
||||
o1.Type = model.ChannelTypeOpen
|
||||
_, nErr := ss.Channel().Save(&o1, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o2 := model.Channel{}
|
||||
o2.TeamId = team
|
||||
o2.DisplayName = "Channel2"
|
||||
o2.Name = NewTestId()
|
||||
o2.Type = model.ChannelTypeOpen
|
||||
_, nErr = ss.Channel().Save(&o2, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o3 := model.Channel{}
|
||||
o3.TeamId = team2
|
||||
o3.DisplayName = "Channel3"
|
||||
o3.Name = NewTestId()
|
||||
o3.Type = model.ChannelTypeOpen
|
||||
_, nErr = ss.Channel().Save(&o3, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
m1.UserId = model.NewId()
|
||||
m1.NotifyProps = model.GetDefaultChannelNotifyProps()
|
||||
_, err := ss.Channel().SaveMember(&m1)
|
||||
require.NoError(t, err)
|
||||
|
||||
m2 := model.ChannelMember{}
|
||||
m2.ChannelId = o1.Id
|
||||
m2.UserId = model.NewId()
|
||||
m2.NotifyProps = model.GetDefaultChannelNotifyProps()
|
||||
_, err = ss.Channel().SaveMember(&m2)
|
||||
require.NoError(t, err)
|
||||
|
||||
m3 := model.ChannelMember{}
|
||||
m3.ChannelId = o2.Id
|
||||
m3.UserId = m1.UserId
|
||||
m3.NotifyProps = model.GetDefaultChannelNotifyProps()
|
||||
_, err = ss.Channel().SaveMember(&m3)
|
||||
require.NoError(t, err)
|
||||
|
||||
m4 := model.ChannelMember{}
|
||||
m4.ChannelId = o3.Id
|
||||
m4.UserId = m1.UserId
|
||||
m4.NotifyProps = model.GetDefaultChannelNotifyProps()
|
||||
_, err = ss.Channel().SaveMember(&m4)
|
||||
require.NoError(t, err)
|
||||
|
||||
list, nErr := ss.Channel().GetChannelsByUser(m1.UserId, false, 0, -1, "")
|
||||
require.NoError(t, nErr)
|
||||
require.Len(t, list, 3)
|
||||
require.ElementsMatch(t, []string{o1.Id, o2.Id, o3.Id}, []string{list[0].Id, list[1].Id, list[2].Id}, "channels did not match")
|
||||
|
||||
nErr = ss.Channel().Delete(o2.Id, 10)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
nErr = ss.Channel().Delete(o3.Id, 20)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// should return 1
|
||||
list, nErr = ss.Channel().GetChannelsByUser(m1.UserId, false, 0, -1, "")
|
||||
require.NoError(t, nErr)
|
||||
require.Len(t, list, 1)
|
||||
require.Equal(t, o1.Id, list[0].Id, "missing channel")
|
||||
|
||||
// Should return all
|
||||
list, nErr = ss.Channel().GetChannelsByUser(m1.UserId, true, 0, -1, "")
|
||||
require.NoError(t, nErr)
|
||||
require.Len(t, list, 3)
|
||||
require.ElementsMatch(t, []string{o1.Id, o2.Id, o3.Id}, []string{list[0].Id, list[1].Id, list[2].Id}, "channels did not match")
|
||||
|
||||
// Should still return all
|
||||
list, nErr = ss.Channel().GetChannelsByUser(m1.UserId, true, 10, -1, "")
|
||||
require.NoError(t, nErr)
|
||||
require.Len(t, list, 3)
|
||||
require.ElementsMatch(t, []string{o1.Id, o2.Id, o3.Id}, []string{list[0].Id, list[1].Id, list[2].Id}, "channels did not match")
|
||||
|
||||
// Should return 2
|
||||
list, nErr = ss.Channel().GetChannelsByUser(m1.UserId, true, 20, -1, "")
|
||||
require.NoError(t, nErr)
|
||||
require.Len(t, list, 2)
|
||||
require.ElementsMatch(t, []string{o1.Id, o3.Id}, []string{list[0].Id, list[1].Id}, "channels did not match")
|
||||
}
|
||||
|
||||
func testChannelStoreGetAllChannels(t *testing.T, ss store.Store, s SqlStore) {
|
||||
cleanupChannels(t, ss)
|
||||
|
||||
@@ -4019,29 +4188,41 @@ func testChannelStoreGetMembersForUser(t *testing.T, ss store.Store) {
|
||||
}
|
||||
|
||||
func testChannelStoreGetMembersForUserWithPagination(t *testing.T, ss store.Store) {
|
||||
t1 := model.Team{}
|
||||
t1.DisplayName = "Name"
|
||||
t1.Name = NewTestId()
|
||||
t1.Email = MakeEmail()
|
||||
t1.Type = model.TeamOpen
|
||||
t1 := model.Team{
|
||||
DisplayName: "team1",
|
||||
Name: NewTestId(),
|
||||
Email: MakeEmail(),
|
||||
Type: model.TeamOpen,
|
||||
}
|
||||
_, err := ss.Team().Save(&t1)
|
||||
require.NoError(t, err)
|
||||
|
||||
o1 := model.Channel{}
|
||||
o1.TeamId = t1.Id
|
||||
o1.DisplayName = "Channel1"
|
||||
o1.Name = NewTestId()
|
||||
o1.Type = model.ChannelTypeOpen
|
||||
_, nErr := ss.Channel().Save(&o1, -1)
|
||||
require.NoError(t, nErr)
|
||||
o1 := model.Channel{
|
||||
TeamId: t1.Id,
|
||||
DisplayName: "Channel1",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
_, err = ss.Channel().Save(&o1, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
o2 := model.Channel{}
|
||||
o2.TeamId = o1.TeamId
|
||||
o2.DisplayName = "Channel2"
|
||||
o2.Name = NewTestId()
|
||||
o2.Type = model.ChannelTypeOpen
|
||||
_, nErr = ss.Channel().Save(&o2, -1)
|
||||
require.NoError(t, nErr)
|
||||
t2 := model.Team{
|
||||
DisplayName: "team2",
|
||||
Name: NewTestId(),
|
||||
Email: MakeEmail(),
|
||||
Type: model.TeamOpen,
|
||||
}
|
||||
_, err = ss.Team().Save(&t2)
|
||||
require.NoError(t, err)
|
||||
|
||||
o2 := model.Channel{
|
||||
TeamId: t2.Id,
|
||||
DisplayName: "Channel2",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
_, err = ss.Channel().Save(&o2, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
@@ -4057,11 +4238,16 @@ func testChannelStoreGetMembersForUserWithPagination(t *testing.T, ss store.Stor
|
||||
_, err = ss.Channel().SaveMember(&m2)
|
||||
require.NoError(t, err)
|
||||
|
||||
members, err := ss.Channel().GetMembersForUserWithPagination(o1.TeamId, m1.UserId, 0, 1)
|
||||
members, err := ss.Channel().GetMembersForUserWithPagination(m1.UserId, 0, 2)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, members, 1)
|
||||
assert.Len(t, members, 2)
|
||||
teamNames := make([]string, 0, 2)
|
||||
for _, member := range members {
|
||||
teamNames = append(teamNames, member.TeamDisplayName)
|
||||
}
|
||||
assert.ElementsMatch(t, teamNames, []string{t1.DisplayName, t2.DisplayName})
|
||||
|
||||
members, err = ss.Channel().GetMembersForUserWithPagination(o1.TeamId, m1.UserId, 1, 1)
|
||||
members, err = ss.Channel().GetMembersForUserWithPagination(m1.UserId, 1, 1)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, members, 1)
|
||||
}
|
||||
@@ -5065,11 +5251,11 @@ func testChannelStoreSearchArchivedInTeam(t *testing.T, ss store.Store, s SqlSto
|
||||
}
|
||||
|
||||
func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
teamId := model.NewId()
|
||||
otherTeamId := model.NewId()
|
||||
teamID := model.NewId()
|
||||
otherTeamID := model.NewId()
|
||||
|
||||
o1 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "ChannelA",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
@@ -5078,7 +5264,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o2 := model.Channel{
|
||||
TeamId: otherTeamId,
|
||||
TeamId: otherTeamID,
|
||||
DisplayName: "ChannelA",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
@@ -5111,7 +5297,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, err)
|
||||
|
||||
o3 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "ChannelA (alternate)",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
@@ -5120,7 +5306,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o4 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "Channel B",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypePrivate,
|
||||
@@ -5128,8 +5314,16 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
_, nErr = ss.Channel().Save(&o4, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
m4 := &model.ChannelMember{
|
||||
ChannelId: o4.Id,
|
||||
UserId: m3.UserId,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, err = ss.Channel().SaveMember(m4)
|
||||
require.NoError(t, err)
|
||||
|
||||
o5 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "Channel C",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypePrivate,
|
||||
@@ -5138,7 +5332,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o6 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "Off-Topic",
|
||||
Name: "off-topic",
|
||||
Type: model.ChannelTypeOpen,
|
||||
@@ -5147,7 +5341,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o7 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "Off-Set",
|
||||
Name: "off-set",
|
||||
Type: model.ChannelTypeOpen,
|
||||
@@ -5156,7 +5350,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o8 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "Off-Limit",
|
||||
Name: "off-limit",
|
||||
Type: model.ChannelTypePrivate,
|
||||
@@ -5164,8 +5358,16 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
_, nErr = ss.Channel().Save(&o8, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
m5 := &model.ChannelMember{
|
||||
ChannelId: o8.Id,
|
||||
UserId: model.NewId(),
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, err = ss.Channel().SaveMember(m5)
|
||||
require.NoError(t, err)
|
||||
|
||||
o9 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "Town Square",
|
||||
Name: "town-square",
|
||||
Type: model.ChannelTypeOpen,
|
||||
@@ -5174,7 +5376,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o10 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "The",
|
||||
Name: "thename",
|
||||
Type: model.ChannelTypeOpen,
|
||||
@@ -5183,7 +5385,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o11 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "Native Mobile Apps",
|
||||
Name: "native-mobile-apps",
|
||||
Type: model.ChannelTypeOpen,
|
||||
@@ -5192,7 +5394,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o12 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "ChannelZ",
|
||||
Purpose: "This can now be searchable!",
|
||||
Name: "with-purpose",
|
||||
@@ -5202,7 +5404,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o13 := model.Channel{
|
||||
TeamId: teamId,
|
||||
TeamId: teamID,
|
||||
DisplayName: "ChannelA (deleted)",
|
||||
Name: model.NewId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
@@ -5216,42 +5418,199 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
||||
|
||||
testCases := []struct {
|
||||
Description string
|
||||
TeamId string
|
||||
TeamID string
|
||||
UserID string
|
||||
Term string
|
||||
IncludeDeleted bool
|
||||
ExpectedResults model.ChannelList
|
||||
}{
|
||||
{"ChannelA", teamId, "ChannelA", false, model.ChannelList{&o1, &o3}},
|
||||
{"ChannelA, include deleted", teamId, "ChannelA", true, model.ChannelList{&o1, &o3, &o13}},
|
||||
{"ChannelA, other team", otherTeamId, "ChannelA", false, model.ChannelList{&o2}},
|
||||
{"empty string", teamId, "", false, model.ChannelList{&o1, &o3, &o12, &o11, &o7, &o6, &o10, &o9}},
|
||||
{"no matches", teamId, "blargh", false, model.ChannelList{}},
|
||||
{"prefix", teamId, "off-", false, model.ChannelList{&o7, &o6}},
|
||||
{"full match with dash", teamId, "off-topic", false, model.ChannelList{&o6}},
|
||||
{"town square", teamId, "town square", false, model.ChannelList{&o9}},
|
||||
{"the in name", teamId, "thename", false, model.ChannelList{&o10}},
|
||||
{"Mobile", teamId, "Mobile", false, model.ChannelList{&o11}},
|
||||
{"search purpose", teamId, "now searchable", false, model.ChannelList{&o12}},
|
||||
{"pipe ignored", teamId, "town square |", false, model.ChannelList{&o9}},
|
||||
{"ChannelA", teamID, m1.UserId, "ChannelA", false, model.ChannelList{&o1, &o3}},
|
||||
{"ChannelA, include deleted", teamID, m1.UserId, "ChannelA", true, model.ChannelList{&o1, &o3, &o13}},
|
||||
{"ChannelA, other team", otherTeamID, m3.UserId, "ChannelA", false, model.ChannelList{&o2}},
|
||||
{"empty string", teamID, m1.UserId, "", false, model.ChannelList{&o1, &o3, &o12, &o11, &o7, &o6, &o10, &o9}},
|
||||
{"no matches", teamID, m1.UserId, "blargh", false, model.ChannelList{}},
|
||||
{"prefix", teamID, m1.UserId, "off-", false, model.ChannelList{&o7, &o6}},
|
||||
{"full match with dash", teamID, m1.UserId, "off-topic", false, model.ChannelList{&o6}},
|
||||
{"town square", teamID, m1.UserId, "town square", false, model.ChannelList{&o9}},
|
||||
{"the in name", teamID, m1.UserId, "thename", false, model.ChannelList{&o10}},
|
||||
{"Mobile", teamID, m1.UserId, "Mobile", false, model.ChannelList{&o11}},
|
||||
{"search purpose", teamID, m1.UserId, "now searchable", false, model.ChannelList{&o12}},
|
||||
{"pipe ignored", teamID, m1.UserId, "town square |", false, model.ChannelList{&o9}},
|
||||
}
|
||||
|
||||
for name, search := range map[string]func(teamId string, term string, includeDeleted bool) (model.ChannelList, error){
|
||||
"AutocompleteInTeam": ss.Channel().AutocompleteInTeam,
|
||||
"SearchInTeam": ss.Channel().SearchInTeam,
|
||||
} {
|
||||
for _, testCase := range testCases {
|
||||
t.Run(name+"/"+testCase.Description, func(t *testing.T) {
|
||||
channels, err := search(testCase.TeamId, testCase.Term, testCase.IncludeDeleted)
|
||||
require.NoError(t, err)
|
||||
for _, testCase := range testCases {
|
||||
t.Run("SearchInTeam/"+testCase.Description, func(t *testing.T) {
|
||||
channels, err := ss.Channel().SearchInTeam(testCase.TeamID, testCase.Term, testCase.IncludeDeleted)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, testCase.ExpectedResults, channels)
|
||||
})
|
||||
}
|
||||
|
||||
// AutoCompleteInTeam doesn't currently sort its output results.
|
||||
if name == "AutocompleteInTeam" {
|
||||
sort.Sort(ByChannelDisplayName(channels))
|
||||
}
|
||||
testCases = append(testCases, []struct {
|
||||
Description string
|
||||
TeamID string
|
||||
UserID string
|
||||
Term string
|
||||
IncludeDeleted bool
|
||||
ExpectedResults model.ChannelList
|
||||
}{
|
||||
{"Channel A", teamID, m4.UserId, "Channel ", false, model.ChannelList{&o4, &o1, &o3, &o12}},
|
||||
{"off limit (private)", teamID, m5.UserId, "off limit", false, model.ChannelList{&o8}},
|
||||
}...,
|
||||
)
|
||||
|
||||
require.Equal(t, testCase.ExpectedResults, channels)
|
||||
})
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
t.Run("AutoCompleteInTeam/"+testCase.Description, func(t *testing.T) {
|
||||
channels, err := ss.Channel().AutocompleteInTeam(testCase.TeamID, testCase.UserID, testCase.Term, testCase.IncludeDeleted)
|
||||
require.NoError(t, err)
|
||||
sort.Sort(ByChannelDisplayName(channels))
|
||||
require.Equal(t, testCase.ExpectedResults, channels)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testAutocomplete(t *testing.T, ss store.Store) {
|
||||
t1 := &model.Team{
|
||||
DisplayName: "t1",
|
||||
Name: NewTestId(),
|
||||
Email: MakeEmail(),
|
||||
Type: model.TeamOpen,
|
||||
}
|
||||
t1, err := ss.Team().Save(t1)
|
||||
require.NoError(t, err)
|
||||
teamID := t1.Id
|
||||
|
||||
t2 := &model.Team{
|
||||
DisplayName: "t2",
|
||||
Name: NewTestId(),
|
||||
Email: MakeEmail(),
|
||||
Type: model.TeamOpen,
|
||||
}
|
||||
t2, err = ss.Team().Save(t2)
|
||||
require.NoError(t, err)
|
||||
otherTeamID := t2.Id
|
||||
|
||||
o1 := model.Channel{
|
||||
TeamId: teamID,
|
||||
DisplayName: "ChannelA1",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
_, err = ss.Channel().Save(&o1, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
o2 := model.Channel{
|
||||
TeamId: otherTeamID,
|
||||
DisplayName: "ChannelA2",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
_, err = ss.Channel().Save(&o2, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
m1 := model.ChannelMember{
|
||||
ChannelId: o1.Id,
|
||||
UserId: model.NewId(),
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, err = ss.Channel().SaveMember(&m1)
|
||||
require.NoError(t, err)
|
||||
|
||||
m2 := model.ChannelMember{
|
||||
ChannelId: o2.Id,
|
||||
UserId: m1.UserId,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, err = ss.Channel().SaveMember(&m2)
|
||||
require.NoError(t, err)
|
||||
|
||||
tm1 := &model.TeamMember{TeamId: teamID, UserId: m1.UserId}
|
||||
_, err = ss.Team().SaveMember(tm1, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
tm2 := &model.TeamMember{TeamId: otherTeamID, UserId: m1.UserId}
|
||||
_, err = ss.Team().SaveMember(tm2, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
m3 := model.ChannelMember{
|
||||
ChannelId: o2.Id,
|
||||
UserId: model.NewId(),
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, err = ss.Channel().SaveMember(&m3)
|
||||
require.NoError(t, err)
|
||||
|
||||
tm3 := &model.TeamMember{TeamId: otherTeamID, UserId: m3.UserId}
|
||||
_, err = ss.Team().SaveMember(tm3, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
tm4 := &model.TeamMember{TeamId: teamID, UserId: m3.UserId}
|
||||
_, err = ss.Team().SaveMember(tm4, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
o3 := model.Channel{
|
||||
TeamId: teamID,
|
||||
DisplayName: "ChannelA private",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypePrivate,
|
||||
}
|
||||
_, err = ss.Channel().Save(&o3, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
o4 := model.Channel{
|
||||
TeamId: otherTeamID,
|
||||
DisplayName: "ChannelB",
|
||||
Name: NewTestId(),
|
||||
Type: model.ChannelTypePrivate,
|
||||
}
|
||||
_, err = ss.Channel().Save(&o4, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
m4 := &model.ChannelMember{
|
||||
ChannelId: o3.Id,
|
||||
UserId: m3.UserId,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, err = ss.Channel().SaveMember(m4)
|
||||
require.NoError(t, err)
|
||||
|
||||
m5 := &model.ChannelMember{
|
||||
ChannelId: o4.Id,
|
||||
UserId: m1.UserId,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, err = ss.Channel().SaveMember(m5)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCases := []struct {
|
||||
Description string
|
||||
UserID string
|
||||
Term string
|
||||
IncludeDeleted bool
|
||||
ExpectedChannelIds []string
|
||||
ExpectedTeamNames []string
|
||||
}{
|
||||
{"user 1, Channel A", m1.UserId, "ChannelA", false, []string{o1.Id, o2.Id}, []string{t1.Name, t2.Name}},
|
||||
{"user 1, Channel B", m1.UserId, "ChannelB", false, []string{o4.Id}, []string{t2.Name}},
|
||||
{"user 2, Channel A", m3.UserId, "ChannelA", false, []string{o3.Id, o1.Id, o2.Id}, []string{t2.Name, t1.Name, t1.Name}},
|
||||
{"user 2, Channel B", m3.UserId, "ChannelB", false, nil, nil},
|
||||
{"user 1, empty string", m1.UserId, "", false, []string{o1.Id, o2.Id, o4.Id}, []string{t1.Name, t2.Name, t2.Name}},
|
||||
{"user 2, empty string", m3.UserId, "", false, []string{o1.Id, o2.Id, o3.Id}, []string{t1.Name, t2.Name, t1.Name}},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run("Autocomplete/"+testCase.Description, func(t *testing.T) {
|
||||
channels, err := ss.Channel().Autocomplete(testCase.UserID, testCase.Term, testCase.IncludeDeleted)
|
||||
require.NoError(t, err)
|
||||
var gotChannelIds []string
|
||||
var gotTeamNames []string
|
||||
for _, ch := range channels {
|
||||
gotChannelIds = append(gotChannelIds, ch.Id)
|
||||
gotTeamNames = append(gotTeamNames, ch.TeamName)
|
||||
}
|
||||
require.ElementsMatch(t, testCase.ExpectedChannelIds, gotChannelIds)
|
||||
require.ElementsMatch(t, testCase.ExpectedTeamNames, gotTeamNames)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6903,13 +7262,13 @@ func testChannelStoreGetChannelsBatchForIndexing(t *testing.T, ss store.Store) {
|
||||
// First and last channel should be outside the range
|
||||
channels, err := ss.Channel().GetChannelsBatchForIndexing(startTime, endTime, 1000)
|
||||
assert.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*model.Channel{c2, c3, c5}, channels)
|
||||
assert.ElementsMatch(t, []*model.Channel{c2, c3, c4, c5}, channels)
|
||||
|
||||
// Update the endTime, last channel should be in
|
||||
endTime = model.GetMillis()
|
||||
channels, err = ss.Channel().GetChannelsBatchForIndexing(startTime, endTime, 1000)
|
||||
assert.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*model.Channel{c2, c3, c5, c6}, channels)
|
||||
assert.ElementsMatch(t, []*model.Channel{c2, c3, c4, c5, c6}, channels)
|
||||
|
||||
// Testing the limit
|
||||
channels, err = ss.Channel().GetChannelsBatchForIndexing(startTime, endTime, 2)
|
||||
|
||||
@@ -60,13 +60,36 @@ func (_m *ChannelStore) AnalyticsTypeCount(teamID string, channelType model.Chan
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// AutocompleteInTeam provides a mock function with given fields: teamID, term, includeDeleted
|
||||
func (_m *ChannelStore) AutocompleteInTeam(teamID string, term string, includeDeleted bool) (model.ChannelList, error) {
|
||||
ret := _m.Called(teamID, term, includeDeleted)
|
||||
// Autocomplete provides a mock function with given fields: userID, term, includeDeleted
|
||||
func (_m *ChannelStore) Autocomplete(userID string, term string, includeDeleted bool) (model.ChannelListWithTeamData, error) {
|
||||
ret := _m.Called(userID, term, includeDeleted)
|
||||
|
||||
var r0 model.ChannelListWithTeamData
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool) model.ChannelListWithTeamData); ok {
|
||||
r0 = rf(userID, term, includeDeleted)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(model.ChannelListWithTeamData)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string, bool) error); ok {
|
||||
r1 = rf(userID, term, includeDeleted)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// AutocompleteInTeam provides a mock function with given fields: teamID, userID, term, includeDeleted
|
||||
func (_m *ChannelStore) AutocompleteInTeam(teamID string, userID string, term string, includeDeleted bool) (model.ChannelList, error) {
|
||||
ret := _m.Called(teamID, userID, term, includeDeleted)
|
||||
|
||||
var r0 model.ChannelList
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool) model.ChannelList); ok {
|
||||
r0 = rf(teamID, term, includeDeleted)
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, bool) model.ChannelList); ok {
|
||||
r0 = rf(teamID, userID, term, includeDeleted)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(model.ChannelList)
|
||||
@@ -74,8 +97,8 @@ func (_m *ChannelStore) AutocompleteInTeam(teamID string, term string, includeDe
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string, bool) error); ok {
|
||||
r1 = rf(teamID, term, includeDeleted)
|
||||
if rf, ok := ret.Get(1).(func(string, string, string, bool) error); ok {
|
||||
r1 = rf(teamID, userID, term, includeDeleted)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -331,6 +354,29 @@ func (_m *ChannelStore) GetAll(teamID string) ([]*model.Channel, error) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetAllChannelMembersById provides a mock function with given fields: id
|
||||
func (_m *ChannelStore) GetAllChannelMembersById(id string) ([]string, error) {
|
||||
ret := _m.Called(id)
|
||||
|
||||
var r0 []string
|
||||
if rf, ok := ret.Get(0).(func(string) []string); ok {
|
||||
r0 = rf(id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]string)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(id)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetAllChannelMembersForUser provides a mock function with given fields: userID, allowFromCache, includeDeleted
|
||||
func (_m *ChannelStore) GetAllChannelMembersForUser(userID string, allowFromCache bool, includeDeleted bool) (map[string]string, error) {
|
||||
ret := _m.Called(userID, allowFromCache, includeDeleted)
|
||||
@@ -720,6 +766,52 @@ func (_m *ChannelStore) GetChannelsByScheme(schemeID string, offset int, limit i
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetChannelsByUser provides a mock function with given fields: userID, includeDeleted, lastDeleteAt, pageSize, fromChannelID
|
||||
func (_m *ChannelStore) GetChannelsByUser(userID string, includeDeleted bool, lastDeleteAt int, pageSize int, fromChannelID string) (model.ChannelList, error) {
|
||||
ret := _m.Called(userID, includeDeleted, lastDeleteAt, pageSize, fromChannelID)
|
||||
|
||||
var r0 model.ChannelList
|
||||
if rf, ok := ret.Get(0).(func(string, bool, int, int, string) model.ChannelList); ok {
|
||||
r0 = rf(userID, includeDeleted, lastDeleteAt, pageSize, fromChannelID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(model.ChannelList)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, bool, int, int, string) error); ok {
|
||||
r1 = rf(userID, includeDeleted, lastDeleteAt, pageSize, fromChannelID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetChannelsWithTeamDataByIds provides a mock function with given fields: channelIds, includeDeleted
|
||||
func (_m *ChannelStore) GetChannelsWithTeamDataByIds(channelIds []string, includeDeleted bool) ([]*model.ChannelWithTeamData, error) {
|
||||
ret := _m.Called(channelIds, includeDeleted)
|
||||
|
||||
var r0 []*model.ChannelWithTeamData
|
||||
if rf, ok := ret.Get(0).(func([]string, bool) []*model.ChannelWithTeamData); ok {
|
||||
r0 = rf(channelIds, includeDeleted)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.ChannelWithTeamData)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func([]string, bool) error); ok {
|
||||
r1 = rf(channelIds, includeDeleted)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetDeleted provides a mock function with given fields: team_id, offset, limit, userID
|
||||
func (_m *ChannelStore) GetDeleted(team_id string, offset int, limit int, userID string) (model.ChannelList, error) {
|
||||
ret := _m.Called(team_id, offset, limit, userID)
|
||||
@@ -1029,22 +1121,22 @@ func (_m *ChannelStore) GetMembersForUser(teamID string, userID string) (model.C
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetMembersForUserWithPagination provides a mock function with given fields: teamID, userID, page, perPage
|
||||
func (_m *ChannelStore) GetMembersForUserWithPagination(teamID string, userID string, page int, perPage int) (model.ChannelMembers, error) {
|
||||
ret := _m.Called(teamID, userID, page, perPage)
|
||||
// GetMembersForUserWithPagination provides a mock function with given fields: userID, page, perPage
|
||||
func (_m *ChannelStore) GetMembersForUserWithPagination(userID string, page int, perPage int) (model.ChannelMembersWithTeamData, error) {
|
||||
ret := _m.Called(userID, page, perPage)
|
||||
|
||||
var r0 model.ChannelMembers
|
||||
if rf, ok := ret.Get(0).(func(string, string, int, int) model.ChannelMembers); ok {
|
||||
r0 = rf(teamID, userID, page, perPage)
|
||||
var r0 model.ChannelMembersWithTeamData
|
||||
if rf, ok := ret.Get(0).(func(string, int, int) model.ChannelMembersWithTeamData); ok {
|
||||
r0 = rf(userID, page, perPage)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(model.ChannelMembers)
|
||||
r0 = ret.Get(0).(model.ChannelMembersWithTeamData)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string, int, int) error); ok {
|
||||
r1 = rf(teamID, userID, page, perPage)
|
||||
if rf, ok := ret.Get(1).(func(string, int, int) error); ok {
|
||||
r1 = rf(userID, page, perPage)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -1303,6 +1395,29 @@ func (_m *ChannelStore) GetTeamForChannel(channelID string) (*model.Team, error)
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetTeamMembersForChannel provides a mock function with given fields: channelID
|
||||
func (_m *ChannelStore) GetTeamMembersForChannel(channelID string) ([]string, error) {
|
||||
ret := _m.Called(channelID)
|
||||
|
||||
var r0 []string
|
||||
if rf, ok := ret.Get(0).(func(string) []string); ok {
|
||||
r0 = rf(channelID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]string)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(channelID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GroupSyncedChannelCount provides a mock function with given fields:
|
||||
func (_m *ChannelStore) GroupSyncedChannelCount() (int64, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
Ссылка в новой задаче
Block a user