* MM-11065: Allow to search and get archived channels from the API

* Fixing more tests

* Add some unit tests

* Add includeDeleted parameter to session permissions check function

* More test fixing

* Adding archive channels list in channels search

* Add restriction for archived channel edition

* Reverting permissions checks modification

* Changed the query parameter to include_deleted

* Enable search archive channels as true by default

* Adding tests for verify search on deleted channels

* Allowing to override archive channels during the imports

* Fixed test

* Search in archive channels from the API must be explicitly requested

* Removing includeDeleted parameter from GetChannelByName and GetChannelByNameForTeam

* Back to ViewArchivedChannels config

* Fixing tests

* Reverting GetChannelByName parameter

* Add include deleted parameter on GetChannel functions in plugins api

* Fixing tests
Этот коммит содержится в:
Martin Kraft
2018-07-30 15:06:08 -04:00
коммит произвёл GitHub
родитель 65cd447a61
Коммит 5872bf9c2f
33 изменённых файлов: 399 добавлений и 185 удалений

Просмотреть файл

@@ -303,6 +303,11 @@ func (s SqlChannelStore) CreateIndexesIfNotExists() {
func (s SqlChannelStore) Save(channel *model.Channel, maxChannelsPerTeam int64) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
if channel.DeleteAt != 0 {
result.Err = model.NewAppError("SqlChannelStore.Save", "store.sql_channel.save.archived_channel.app_error", nil, "", http.StatusBadRequest)
return
}
if channel.Type == model.CHANNEL_DIRECT {
result.Err = model.NewAppError("SqlChannelStore.Save", "store.sql_channel.save.direct_channel.app_error", nil, "", http.StatusBadRequest)
return
@@ -352,6 +357,11 @@ func (s SqlChannelStore) CreateDirectChannel(userId string, otherUserId string)
func (s SqlChannelStore) SaveDirectChannel(directchannel *model.Channel, member1 *model.ChannelMember, member2 *model.ChannelMember) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
if directchannel.DeleteAt != 0 {
result.Err = model.NewAppError("SqlChannelStore.Save", "store.sql_channel.save.archived_channel.app_error", nil, "", http.StatusBadRequest)
return
}
if directchannel.Type != model.CHANNEL_DIRECT {
result.Err = model.NewAppError("SqlChannelStore.SaveDirectChannel", "store.sql_channel.save_direct_channel.not_direct.app_error", nil, "", http.StatusBadRequest)
return
@@ -629,10 +639,14 @@ func (s SqlChannelStore) PermanentDeleteMembersByChannel(channelId string) store
})
}
func (s SqlChannelStore) GetChannels(teamId string, userId string) store.StoreChannel {
func (s SqlChannelStore) GetChannels(teamId string, userId string, includeDeleted bool) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
query := "SELECT Channels.* FROM Channels, ChannelMembers WHERE Id = ChannelId AND UserId = :UserId AND DeleteAt = 0 AND (TeamId = :TeamId OR TeamId = '') ORDER BY DisplayName"
if includeDeleted {
query = "SELECT Channels.* FROM Channels, ChannelMembers WHERE Id = ChannelId AND UserId = :UserId AND (TeamId = :TeamId OR TeamId = '') ORDER BY DisplayName"
}
data := &model.ChannelList{}
_, err := s.GetReplica().Select(data, "SELECT Channels.* FROM Channels, ChannelMembers WHERE Id = ChannelId AND UserId = :UserId AND DeleteAt = 0 AND (TeamId = :TeamId OR TeamId = '') ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
_, err := s.GetReplica().Select(data, query, map[string]interface{}{"TeamId": teamId, "UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetChannels", "store.sql_channel.get_channels.get.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error(), http.StatusInternalServerError)
@@ -1100,7 +1114,7 @@ func (s SqlChannelStore) IsUserInChannelUseCache(userId string, channelId string
s.metrics.IncrementMemCacheMissCounter("All Channel Members for User")
}
result := <-s.GetAllChannelMembersForUser(userId, true)
result := <-s.GetAllChannelMembersForUser(userId, true, false)
if result.Err != nil {
mlog.Error("SqlChannelStore.IsUserInChannelUseCache: " + result.Err.Error())
return false
@@ -1147,7 +1161,7 @@ func (s SqlChannelStore) GetMemberForPost(postId string, userId string) store.St
})
}
func (s SqlChannelStore) GetAllChannelMembersForUser(userId string, allowFromCache bool) store.StoreChannel {
func (s SqlChannelStore) GetAllChannelMembersForUser(userId string, allowFromCache bool, includeDeleted bool) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
if allowFromCache {
if cacheItem, ok := allChannelMembersForUserCache.Get(userId); ok {
@@ -1163,6 +1177,11 @@ func (s SqlChannelStore) GetAllChannelMembersForUser(userId string, allowFromCac
s.metrics.IncrementMemCacheMissCounter("All Channel Members for User")
}
var deletedClause string
if !includeDeleted {
deletedClause = "Channels.DeleteAt = 0 AND"
}
var data allChannelMembers
_, err := s.GetReplica().Select(&data, `
SELECT
@@ -1182,8 +1201,8 @@ func (s SqlChannelStore) GetAllChannelMembersForUser(userId string, allowFromCac
LEFT JOIN
Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id
WHERE
Channels.DeleteAt = 0
AND ChannelMembers.UserId = :UserId`, map[string]interface{}{"UserId": userId})
`+deletedClause+`
ChannelMembers.UserId = :UserId`, map[string]interface{}{"UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetAllChannelMembersForUser", "store.sql_channel.get_channels.get.app_error", nil, "userId="+userId+", err="+err.Error(), http.StatusInternalServerError)
@@ -1515,8 +1534,13 @@ func (s SqlChannelStore) GetMembersForUser(teamId string, userId string) store.S
})
}
func (s SqlChannelStore) AutocompleteInTeam(teamId string, term string) store.StoreChannel {
func (s SqlChannelStore) AutocompleteInTeam(teamId string, term string, includeDeleted bool) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
deleteFilter := "AND DeleteAt = 0"
if includeDeleted {
deleteFilter = ""
}
queryFormat := `
SELECT
*
@@ -1525,7 +1549,7 @@ func (s SqlChannelStore) AutocompleteInTeam(teamId string, term string) store.St
WHERE
TeamId = :TeamId
AND Type = 'O'
AND DeleteAt = 0
` + deleteFilter + `
%v
LIMIT 50`
@@ -1555,8 +1579,12 @@ func (s SqlChannelStore) AutocompleteInTeam(teamId string, term string) store.St
})
}
func (s SqlChannelStore) SearchInTeam(teamId string, term string) store.StoreChannel {
func (s SqlChannelStore) SearchInTeam(teamId string, term string, includeDeleted bool) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
deleteFilter := "AND DeleteAt = 0"
if includeDeleted {
deleteFilter = ""
}
searchQuery := `
SELECT
*
@@ -1565,7 +1593,7 @@ func (s SqlChannelStore) SearchInTeam(teamId string, term string) store.StoreCha
WHERE
TeamId = :TeamId
AND Type = 'O'
AND DeleteAt = 0
` + deleteFilter + `
SEARCH_CLAUSE
ORDER BY DisplayName
LIMIT 100`

Просмотреть файл

@@ -803,6 +803,11 @@ func (s *SqlPostStore) Search(teamId string, userId string, params *model.Search
var posts []*model.Post
deletedQueryPart := "AND DeleteAt = 0"
if params.IncludeDeletedChannels {
deletedQueryPart = ""
}
searchQuery := `
SELECT
*
@@ -822,7 +827,7 @@ func (s *SqlPostStore) Search(teamId string, userId string, params *model.Search
Id = ChannelId
AND (TeamId = :TeamId OR TeamId = '')
AND UserId = :UserId
AND DeleteAt = 0
` + deletedQueryPart + `
CHANNEL_FILTER)
SEARCH_CLAUSE
ORDER BY CreateAt DESC

Просмотреть файл

@@ -131,7 +131,7 @@ type ChannelStore interface {
GetByNameIncludeDeleted(team_id string, name string, allowFromCache bool) StoreChannel
GetDeletedByName(team_id string, name string) StoreChannel
GetDeleted(team_id string, offset int, limit int) StoreChannel
GetChannels(teamId string, userId string) StoreChannel
GetChannels(teamId string, userId string, includeDeleted bool) StoreChannel
GetMoreChannels(teamId string, userId string, offset int, limit int) StoreChannel
GetPublicChannelsForTeam(teamId string, offset int, limit int) StoreChannel
GetPublicChannelsByIdsForTeam(teamId string, channelIds []string) StoreChannel
@@ -143,7 +143,7 @@ type ChannelStore interface {
UpdateMember(member *model.ChannelMember) StoreChannel
GetMembers(channelId string, offset, limit int) StoreChannel
GetMember(channelId string, userId string) StoreChannel
GetAllChannelMembersForUser(userId string, allowFromCache bool) StoreChannel
GetAllChannelMembersForUser(userId string, allowFromCache bool, includeDeleted bool) StoreChannel
InvalidateAllChannelMembersForUser(userId string)
IsUserInChannelUseCache(userId string, channelId string) bool
GetAllChannelMembersNotifyPropsForChannel(channelId string, allowFromCache bool) StoreChannel
@@ -160,8 +160,8 @@ type ChannelStore interface {
IncrementMentionCount(channelId string, userId string) StoreChannel
AnalyticsTypeCount(teamId string, channelType string) StoreChannel
GetMembersForUser(teamId string, userId string) StoreChannel
AutocompleteInTeam(teamId string, term string) StoreChannel
SearchInTeam(teamId string, term string) StoreChannel
AutocompleteInTeam(teamId string, term string, includeDeleted bool) StoreChannel
SearchInTeam(teamId string, term string, includeDeleted bool) StoreChannel
SearchMore(userId string, teamId string, term string) StoreChannel
GetMembersByIds(channelId string, userIds []string) StoreChannel
AnalyticsDeletedTypeCount(teamId string, channelType string) StoreChannel

Просмотреть файл

@@ -493,7 +493,7 @@ func testChannelStoreDelete(t *testing.T, ss store.Store) {
t.Fatal(r.Err)
}
cresult := <-ss.Channel().GetChannels(o1.TeamId, m1.UserId)
cresult := <-ss.Channel().GetChannels(o1.TeamId, m1.UserId, false)
list := cresult.Data.(*model.ChannelList)
if len(*list) != 1 {
@@ -509,7 +509,7 @@ func testChannelStoreDelete(t *testing.T, ss store.Store) {
<-ss.Channel().PermanentDelete(o2.Id)
cresult = <-ss.Channel().GetChannels(o1.TeamId, m1.UserId)
cresult = <-ss.Channel().GetChannels(o1.TeamId, m1.UserId, false)
t.Log(cresult.Err)
if cresult.Err.Id != "store.sql_channel.get_channels.not_found.app_error" {
t.Fatal("no channels should be found")
@@ -555,7 +555,7 @@ func testChannelStoreGetByName(t *testing.T, ss store.Store) {
store.Must(ss.Channel().Delete(r1.Data.(*model.Channel).Id, model.GetMillis()))
if err := (<-ss.Channel().GetByName(o1.TeamId, "", false)).Err; err == nil {
if err := (<-ss.Channel().GetByName(o1.TeamId, r1.Data.(*model.Channel).Name, false)).Err; err == nil {
t.Fatal("Deleted channel should not be returned by GetByName()")
}
}
@@ -617,8 +617,11 @@ func testChannelStoreGetDeletedByName(t *testing.T, ss store.Store) {
o1.DisplayName = "Name"
o1.Name = "zz" + model.NewId() + "b"
o1.Type = model.CHANNEL_OPEN
o1.DeleteAt = model.GetMillis()
store.Must(ss.Channel().Save(&o1, -1))
now := model.GetMillis()
store.Must(ss.Channel().Delete(o1.Id, now))
o1.DeleteAt = now
o1.UpdateAt = now
if r1 := <-ss.Channel().GetDeletedByName(o1.TeamId, o1.Name); r1.Err != nil {
t.Fatal(r1.Err)
@@ -639,8 +642,8 @@ func testChannelStoreGetDeleted(t *testing.T, ss store.Store) {
o1.DisplayName = "Channel1"
o1.Name = "zz" + model.NewId() + "b"
o1.Type = model.CHANNEL_OPEN
o1.DeleteAt = model.GetMillis()
store.Must(ss.Channel().Save(&o1, -1))
store.Must(ss.Channel().Delete(o1.Id, model.GetMillis()))
cresult := <-ss.Channel().GetDeleted(o1.TeamId, 0, 100)
if cresult.Err != nil {
@@ -678,8 +681,8 @@ func testChannelStoreGetDeleted(t *testing.T, ss store.Store) {
o3.DisplayName = "Channel3"
o3.Name = "zz" + model.NewId() + "b"
o3.Type = model.CHANNEL_OPEN
o3.DeleteAt = model.GetMillis()
store.Must(ss.Channel().Save(&o3, -1))
store.Must(ss.Channel().SetDeleteAt(o3.Id, model.GetMillis(), model.GetMillis()))
cresult = <-ss.Channel().GetDeleted(o1.TeamId, 0, 100)
if cresult.Err != nil {
@@ -890,26 +893,26 @@ func testChannelStoreGetChannels(t *testing.T, ss store.Store) {
m3.NotifyProps = model.GetDefaultChannelNotifyProps()
store.Must(ss.Channel().SaveMember(&m3))
cresult := <-ss.Channel().GetChannels(o1.TeamId, m1.UserId)
cresult := <-ss.Channel().GetChannels(o1.TeamId, m1.UserId, false)
list := cresult.Data.(*model.ChannelList)
if (*list)[0].Id != o1.Id {
t.Fatal("missing channel")
}
acresult := <-ss.Channel().GetAllChannelMembersForUser(m1.UserId, false)
acresult := <-ss.Channel().GetAllChannelMembersForUser(m1.UserId, false, false)
ids := acresult.Data.(map[string]string)
if _, ok := ids[o1.Id]; !ok {
t.Fatal("missing channel")
}
acresult2 := <-ss.Channel().GetAllChannelMembersForUser(m1.UserId, true)
acresult2 := <-ss.Channel().GetAllChannelMembersForUser(m1.UserId, true, false)
ids2 := acresult2.Data.(map[string]string)
if _, ok := ids2[o1.Id]; !ok {
t.Fatal("missing channel")
}
acresult3 := <-ss.Channel().GetAllChannelMembersForUser(m1.UserId, true)
acresult3 := <-ss.Channel().GetAllChannelMembersForUser(m1.UserId, true, false)
ids3 := acresult3.Data.(map[string]string)
if _, ok := ids3[o1.Id]; !ok {
t.Fatal("missing channel")
@@ -1913,12 +1916,12 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
o12.Type = model.CHANNEL_OPEN
store.Must(ss.Channel().Save(&o12, -1))
for name, search := range map[string]func(teamId string, term string) store.StoreChannel{
for name, search := range map[string]func(teamId string, term string, includeDeleted bool) store.StoreChannel{
"AutocompleteInTeam": ss.Channel().AutocompleteInTeam,
"SearchInTeam": ss.Channel().SearchInTeam,
} {
t.Run(name, func(t *testing.T) {
if result := <-search(o1.TeamId, "ChannelA"); result.Err != nil {
if result := <-search(o1.TeamId, "ChannelA", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)
@@ -1927,7 +1930,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
}
}
if result := <-search(o1.TeamId, ""); result.Err != nil {
if result := <-search(o1.TeamId, "", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)
@@ -1936,7 +1939,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
}
}
if result := <-search(o1.TeamId, "blargh"); result.Err != nil {
if result := <-search(o1.TeamId, "blargh", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)
@@ -1945,7 +1948,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
}
}
if result := <-search(o1.TeamId, "off-"); result.Err != nil {
if result := <-search(o1.TeamId, "off-", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)
@@ -1962,7 +1965,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
}
}
if result := <-search(o1.TeamId, "off-topic"); result.Err != nil {
if result := <-search(o1.TeamId, "off-topic", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)
@@ -1975,7 +1978,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
}
}
if result := <-search(o1.TeamId, "town square"); result.Err != nil {
if result := <-search(o1.TeamId, "town square", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)
@@ -1988,7 +1991,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
}
}
if result := <-search(o1.TeamId, "the"); result.Err != nil {
if result := <-search(o1.TeamId, "the", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)
@@ -2002,7 +2005,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
}
}
if result := <-search(o1.TeamId, "Mobile"); result.Err != nil {
if result := <-search(o1.TeamId, "Mobile", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)
@@ -2016,7 +2019,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
}
}
if result := <-search(o1.TeamId, "now searchable"); result.Err != nil {
if result := <-search(o1.TeamId, "now searchable", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)
@@ -2029,7 +2032,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
}
}
if result := <-search(o1.TeamId, "town square |"); result.Err != nil {
if result := <-search(o1.TeamId, "town square |", false); result.Err != nil {
t.Fatal(result.Err)
} else {
channels := result.Data.(*model.ChannelList)

Просмотреть файл

@@ -46,12 +46,12 @@ func (_m *ChannelStore) AnalyticsTypeCount(teamId string, channelType string) st
}
// AutocompleteInTeam provides a mock function with given fields: teamId, term
func (_m *ChannelStore) AutocompleteInTeam(teamId string, term string) store.StoreChannel {
func (_m *ChannelStore) AutocompleteInTeam(teamId string, term string, includeDeleted bool) store.StoreChannel {
ret := _m.Called(teamId, term)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, string) store.StoreChannel); ok {
r0 = rf(teamId, term)
if rf, ok := ret.Get(0).(func(string, string, bool) store.StoreChannel); ok {
r0 = rf(teamId, term, includeDeleted)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
@@ -147,12 +147,12 @@ func (_m *ChannelStore) GetAll(teamId string) store.StoreChannel {
}
// GetAllChannelMembersForUser provides a mock function with given fields: userId, allowFromCache
func (_m *ChannelStore) GetAllChannelMembersForUser(userId string, allowFromCache bool) store.StoreChannel {
func (_m *ChannelStore) GetAllChannelMembersForUser(userId string, allowFromCache bool, includeDeleted bool) store.StoreChannel {
ret := _m.Called(userId, allowFromCache)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, bool) store.StoreChannel); ok {
r0 = rf(userId, allowFromCache)
if rf, ok := ret.Get(0).(func(string, bool, bool) store.StoreChannel); ok {
r0 = rf(userId, allowFromCache, includeDeleted)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
@@ -259,12 +259,12 @@ func (_m *ChannelStore) GetChannelUnread(channelId string, userId string) store.
}
// GetChannels provides a mock function with given fields: teamId, userId
func (_m *ChannelStore) GetChannels(teamId string, userId string) store.StoreChannel {
func (_m *ChannelStore) GetChannels(teamId string, userId string, includeDeleted bool) store.StoreChannel {
ret := _m.Called(teamId, userId)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, string) store.StoreChannel); ok {
r0 = rf(teamId, userId)
if rf, ok := ret.Get(0).(func(string, string, bool) store.StoreChannel); ok {
r0 = rf(teamId, userId, includeDeleted)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
@@ -776,12 +776,12 @@ func (_m *ChannelStore) SaveMember(member *model.ChannelMember) store.StoreChann
}
// SearchInTeam provides a mock function with given fields: teamId, term
func (_m *ChannelStore) SearchInTeam(teamId string, term string) store.StoreChannel {
func (_m *ChannelStore) SearchInTeam(teamId string, term string, includeDeleted bool) store.StoreChannel {
ret := _m.Called(teamId, term)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, string) store.StoreChannel); ok {
r0 = rf(teamId, term)
if rf, ok := ret.Get(0).(func(string, string, bool) store.StoreChannel); ok {
r0 = rf(teamId, term, includeDeleted)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)

Просмотреть файл

@@ -13,6 +13,7 @@ import (
"github.com/mattermost/mattermost-server/store"
"github.com/mattermost/mattermost-server/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPostStore(t *testing.T, ss store.Store) {
@@ -839,6 +840,20 @@ func testPostStoreSearch(t *testing.T, ss store.Store) {
c2.Type = model.CHANNEL_OPEN
c2 = (<-ss.Channel().Save(c2, -1)).Data.(*model.Channel)
c3 := &model.Channel{}
c3.TeamId = teamId
c3.DisplayName = "Channel1"
c3.Name = "zz" + model.NewId() + "b"
c3.Type = model.CHANNEL_OPEN
c3 = (<-ss.Channel().Save(c3, -1)).Data.(*model.Channel)
<-ss.Channel().Delete(c3.Id, model.GetMillis())
m3 := model.ChannelMember{}
m3.ChannelId = c3.Id
m3.UserId = userId
m3.NotifyProps = model.GetDefaultChannelNotifyProps()
store.Must(ss.Channel().SaveMember(&m3))
o1 := &model.Post{}
o1.ChannelId = c1.Id
o1.UserId = model.NewId()
@@ -877,69 +892,129 @@ func testPostStoreSearch(t *testing.T, ss store.Store) {
o5.Hashtags = "#secret #howdy"
o5 = (<-ss.Post().Save(o5)).Data.(*model.Post)
r1 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "corey", IsHashtag: false})).Data.(*model.PostList)
if len(r1.Order) != 1 || r1.Order[0] != o1.Id {
t.Fatal("returned wrong search result")
}
o6 := &model.Post{}
o6.ChannelId = c3.Id
o6.UserId = model.NewId()
o6.Hashtags = "#hashtag"
o6 = (<-ss.Post().Save(o6)).Data.(*model.Post)
r3 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "new", IsHashtag: false})).Data.(*model.PostList)
if len(r3.Order) != 2 || (r3.Order[0] != o1.Id && r3.Order[1] != o1.Id) {
t.Fatal("returned wrong search result")
}
o7 := &model.Post{}
o7.ChannelId = c3.Id
o7.UserId = model.NewId()
o7.Message = "New Jersey is where John is from corey new york"
o7 = (<-ss.Post().Save(o7)).Data.(*model.Post)
r4 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "john", IsHashtag: false})).Data.(*model.PostList)
if len(r4.Order) != 1 || r4.Order[0] != o2.Id {
t.Fatal("returned wrong search result")
}
o8 := &model.Post{}
o8.ChannelId = c3.Id
o8.UserId = model.NewId()
o8.Message = "Deleted"
o8 = (<-ss.Post().Save(o8)).Data.(*model.Post)
r5 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "matter*", IsHashtag: false})).Data.(*model.PostList)
if len(r5.Order) != 1 || r5.Order[0] != o1.Id {
t.Fatal("returned wrong search result")
tt := []struct {
name string
searchParams *model.SearchParams
extectedResultsCount int
expectedMessageResultIds []string
}{
{
"normal-search-1",
&model.SearchParams{Terms: "corey"},
1,
[]string{o1.Id},
},
{
"normal-search-2",
&model.SearchParams{Terms: "new"},
2,
[]string{o1.Id, o2.Id},
},
{
"normal-search-3",
&model.SearchParams{Terms: "john"},
1,
[]string{o2.Id},
},
{
"wildcard-search",
&model.SearchParams{Terms: "matter*"},
1,
[]string{o1.Id},
},
{
"hashtag-search",
&model.SearchParams{Terms: "#hashtag", IsHashtag: true},
1,
[]string{o4.Id},
},
{
"hashtag-search-2",
&model.SearchParams{Terms: "#secret", IsHashtag: true},
1,
[]string{o5.Id},
},
{
"no-match-mention",
&model.SearchParams{Terms: "@thisshouldmatchnothing", IsHashtag: true},
0,
[]string{},
},
{
"no-results-search",
&model.SearchParams{Terms: "mattermost jersey"},
0,
[]string{},
},
{
"multiple-words-search",
&model.SearchParams{Terms: "corey new york"},
1,
[]string{o1.Id},
},
{
"multiple-wildcard-search",
&model.SearchParams{Terms: "matter* jer*"},
0,
[]string{},
},
{
"search-with-work-next-to-a-symbol",
&model.SearchParams{Terms: "message blargh"},
1,
[]string{o4.Id},
},
{
"search-with-or",
&model.SearchParams{Terms: "Jersey corey", OrTerms: true},
2,
[]string{o1.Id, o2.Id},
},
{
"search-with-or-and-deleted",
&model.SearchParams{Terms: "Jersey corey", OrTerms: true, IncludeDeletedChannels: true},
3,
[]string{o1.Id, o2.Id, o7.Id},
},
{
"search-hashtag-deleted",
&model.SearchParams{Terms: "#hashtag", IsHashtag: true, IncludeDeletedChannels: true},
2,
[]string{o4.Id, o6.Id},
},
{
"search-deleted-only",
&model.SearchParams{Terms: "Deleted", IncludeDeletedChannels: true},
1,
[]string{o8.Id},
},
}
r6 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "#hashtag", IsHashtag: true})).Data.(*model.PostList)
if len(r6.Order) != 1 || r6.Order[0] != o4.Id {
t.Fatal("returned wrong search result")
}
r7 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "#secret", IsHashtag: true})).Data.(*model.PostList)
if len(r7.Order) != 1 || r7.Order[0] != o5.Id {
t.Fatal("returned wrong search result")
}
r8 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "@thisshouldmatchnothing", IsHashtag: true})).Data.(*model.PostList)
if len(r8.Order) != 0 {
t.Fatal("returned wrong search result")
}
r9 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "mattermost jersey", IsHashtag: false})).Data.(*model.PostList)
if len(r9.Order) != 0 {
t.Fatal("returned wrong search result")
}
r9a := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "corey new york", IsHashtag: false})).Data.(*model.PostList)
if len(r9a.Order) != 1 {
t.Fatal("returned wrong search result")
}
r10 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "matter* jer*", IsHashtag: false})).Data.(*model.PostList)
if len(r10.Order) != 0 {
t.Fatal("returned wrong search result")
}
r11 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "message blargh", IsHashtag: false})).Data.(*model.PostList)
if len(r11.Order) != 1 {
t.Fatal("returned wrong search result")
}
r12 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "blargh>", IsHashtag: false})).Data.(*model.PostList)
if len(r12.Order) != 1 {
t.Fatal("returned wrong search result")
}
r13 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "Jersey corey", IsHashtag: false, OrTerms: true})).Data.(*model.PostList)
if len(r13.Order) != 2 {
t.Fatal("returned wrong search result")
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
result := (<-ss.Post().Search(teamId, userId, tc.searchParams)).Data.(*model.PostList)
require.Len(t, result.Order, tc.extectedResultsCount)
for _, expectedMessageResultId := range tc.expectedMessageResultIds {
assert.Contains(t, result.Order, expectedMessageResultId)
}
})
}
}