summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api4/apitestlib.go5
-rw-r--r--api4/channel.go10
-rw-r--r--api4/channel_test.go28
-rw-r--r--api4/post.go4
-rw-r--r--api4/post_test.go11
-rw-r--r--api4/reaction_test.go4
-rw-r--r--app/authorization.go2
-rw-r--r--app/channel.go53
-rw-r--r--app/channel_test.go2
-rw-r--r--app/command_invite.go2
-rw-r--r--app/import.go4
-rw-r--r--app/import_test.go12
-rw-r--r--app/plugin_api.go8
-rw-r--r--app/post.go8
-rw-r--r--app/team.go2
-rw-r--r--app/user.go2
-rw-r--r--app/web_conn.go2
-rw-r--r--config/default.json1
-rw-r--r--manualtesting/manual_testing.go2
-rw-r--r--model/client4.go29
-rw-r--r--model/config.go4
-rw-r--r--model/search_params.go11
-rw-r--r--plugin/api.go4
-rw-r--r--plugin/client_rpc_generated.go18
-rw-r--r--plugin/example_help_test.go2
-rw-r--r--plugin/plugintest/api.go28
-rw-r--r--store/sqlstore/channel_store.go48
-rw-r--r--store/sqlstore/post_store.go7
-rw-r--r--store/store.go8
-rw-r--r--store/storetest/channel_store.go45
-rw-r--r--store/storetest/mocks/ChannelStore.go24
-rw-r--r--store/storetest/post_store.go197
-rw-r--r--utils/config.go1
33 files changed, 401 insertions, 187 deletions
diff --git a/api4/apitestlib.go b/api4/apitestlib.go
index fce44cfa1..652a8f882 100644
--- a/api4/apitestlib.go
+++ b/api4/apitestlib.go
@@ -44,6 +44,7 @@ type TestHelper struct {
BasicTeam *model.Team
BasicChannel *model.Channel
BasicPrivateChannel *model.Channel
+ BasicDeletedChannel *model.Channel
BasicChannel2 *model.Channel
BasicPost *model.Post
@@ -250,6 +251,7 @@ func (me *TestHelper) InitBasic() *TestHelper {
me.BasicTeam = me.CreateTeam()
me.BasicChannel = me.CreatePublicChannel()
me.BasicPrivateChannel = me.CreatePrivateChannel()
+ me.BasicDeletedChannel = me.CreatePublicChannel()
me.BasicChannel2 = me.CreatePublicChannel()
me.BasicPost = me.CreatePost()
me.BasicUser = me.CreateUser()
@@ -262,7 +264,10 @@ func (me *TestHelper) InitBasic() *TestHelper {
me.App.AddUserToChannel(me.BasicUser2, me.BasicChannel2)
me.App.AddUserToChannel(me.BasicUser, me.BasicPrivateChannel)
me.App.AddUserToChannel(me.BasicUser2, me.BasicPrivateChannel)
+ me.App.AddUserToChannel(me.BasicUser, me.BasicDeletedChannel)
+ me.App.AddUserToChannel(me.BasicUser2, me.BasicDeletedChannel)
me.App.UpdateUserRoles(me.BasicUser.Id, model.SYSTEM_USER_ROLE_ID, false)
+ me.Client.DeleteChannel(me.BasicDeletedChannel.Id)
me.LoginBasic()
return me
diff --git a/api4/channel.go b/api4/channel.go
index db34bf03c..0b8470975 100644
--- a/api4/channel.go
+++ b/api4/channel.go
@@ -589,7 +589,7 @@ func getChannelsForTeamForUser(c *Context, w http.ResponseWriter, r *http.Reques
return
}
- channels, err := c.App.GetChannelsForUser(c.Params.TeamId, c.Params.UserId)
+ channels, err := c.App.GetChannelsForUser(c.Params.TeamId, c.Params.UserId, false)
if err != nil {
c.Err = err
return
@@ -709,7 +709,9 @@ func getChannelByName(c *Context, w http.ResponseWriter, r *http.Request) {
var channel *model.Channel
var err *model.AppError
- if channel, err = c.App.GetChannelByName(c.Params.ChannelName, c.Params.TeamId); err != nil {
+ includeDeleted := r.URL.Query().Get("include_deleted") == "true"
+
+ if channel, err = c.App.GetChannelByName(c.Params.ChannelName, c.Params.TeamId, includeDeleted); err != nil {
c.Err = err
return
}
@@ -744,7 +746,9 @@ func getChannelByNameForTeamName(c *Context, w http.ResponseWriter, r *http.Requ
var channel *model.Channel
var err *model.AppError
- if channel, err = c.App.GetChannelByNameForTeamName(c.Params.ChannelName, c.Params.TeamName); err != nil {
+ includeDeleted := r.URL.Query().Get("include_deleted") == "true"
+
+ if channel, err = c.App.GetChannelByNameForTeamName(c.Params.ChannelName, c.Params.TeamName, includeDeleted); err != nil {
c.Err = err
return
}
diff --git a/api4/channel_test.go b/api4/channel_test.go
index 0d8fbe4d5..4645a0ab6 100644
--- a/api4/channel_test.go
+++ b/api4/channel_test.go
@@ -867,7 +867,7 @@ func TestDeleteChannel(t *testing.T) {
CheckNoError(t, resp)
// default channel cannot be deleted.
- defaultChannel, _ := th.App.GetChannelByName(model.DEFAULT_CHANNEL, team.Id)
+ defaultChannel, _ := th.App.GetChannelByName(model.DEFAULT_CHANNEL, team.Id, false)
pass, resp = Client.DeleteChannel(defaultChannel.Id)
CheckBadRequestStatus(t, resp)
@@ -998,7 +998,7 @@ func TestConvertChannelToPrivate(t *testing.T) {
defer th.TearDown()
Client := th.Client
- defaultChannel, _ := th.App.GetChannelByName(model.DEFAULT_CHANNEL, th.BasicTeam.Id)
+ defaultChannel, _ := th.App.GetChannelByName(model.DEFAULT_CHANNEL, th.BasicTeam.Id, false)
_, resp := Client.ConvertChannelToPrivate(defaultChannel.Id)
CheckForbiddenStatus(t, resp)
@@ -1115,6 +1115,16 @@ func TestGetChannelByName(t *testing.T) {
_, resp = Client.GetChannelByName(strings.ToUpper(th.BasicPrivateChannel.Name), th.BasicTeam.Id, "")
CheckNoError(t, resp)
+ _, resp = Client.GetChannelByName(th.BasicDeletedChannel.Name, th.BasicTeam.Id, "")
+ CheckNotFoundStatus(t, resp)
+
+ channel, resp = Client.GetChannelByNameIncludeDeleted(th.BasicDeletedChannel.Name, th.BasicTeam.Id, "")
+ CheckNoError(t, resp)
+
+ if channel.Name != th.BasicDeletedChannel.Name {
+ t.Fatal("names did not match")
+ }
+
Client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id)
_, resp = Client.GetChannelByName(th.BasicChannel.Name, th.BasicTeam.Id, "")
CheckNoError(t, resp)
@@ -1157,6 +1167,16 @@ func TestGetChannelByNameForTeamName(t *testing.T) {
_, resp = Client.GetChannelByNameForTeamName(th.BasicChannel.Name, th.BasicTeam.Name, "")
CheckNoError(t, resp)
+ _, resp = Client.GetChannelByNameForTeamName(th.BasicDeletedChannel.Name, th.BasicTeam.Name, "")
+ CheckNotFoundStatus(t, resp)
+
+ channel, resp = Client.GetChannelByNameForTeamNameIncludeDeleted(th.BasicDeletedChannel.Name, th.BasicTeam.Name, "")
+ CheckNoError(t, resp)
+
+ if channel.Name != th.BasicDeletedChannel.Name {
+ t.Fatal("names did not match")
+ }
+
_, resp = Client.GetChannelByNameForTeamName(th.BasicChannel.Name, model.NewRandomString(15), "")
CheckNotFoundStatus(t, resp)
@@ -1330,8 +1350,8 @@ func TestGetChannelMembersForUser(t *testing.T) {
members, resp := Client.GetChannelMembersForUser(th.BasicUser.Id, th.BasicTeam.Id, "")
CheckNoError(t, resp)
- if len(*members) != 5 {
- t.Fatal("should have 5 members on team")
+ if len(*members) != 6 {
+ t.Fatal("should have 6 members on team")
}
_, resp = Client.GetChannelMembersForUser("", th.BasicTeam.Id, "")
diff --git a/api4/post.go b/api4/post.go
index b76e89964..12664cc24 100644
--- a/api4/post.go
+++ b/api4/post.go
@@ -330,6 +330,8 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
+ includeDeletedChannels := r.URL.Query().Get("include_deleted_channels") == "true"
+
props := model.StringInterfaceFromJson(r.Body)
terms, ok := props["terms"].(string)
if !ok || len(terms) == 0 {
@@ -341,7 +343,7 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
startTime := time.Now()
- results, err := c.App.SearchPostsInTeam(terms, c.Session.UserId, c.Params.TeamId, isOrSearch)
+ results, err := c.App.SearchPostsInTeam(terms, c.Session.UserId, c.Params.TeamId, isOrSearch, includeDeletedChannels)
elapsedTime := float64(time.Since(startTime)) / float64(time.Second)
metrics := c.App.Metrics
diff --git a/api4/post_test.go b/api4/post_test.go
index 720fdc410..036a64fc7 100644
--- a/api4/post_test.go
+++ b/api4/post_test.go
@@ -1288,6 +1288,10 @@ func TestSearchPosts(t *testing.T) {
message = "hashtag for post4"
_ = th.CreateMessagePost(message)
+ archivedChannel := th.CreatePublicChannel()
+ _ = th.CreateMessagePostWithClient(th.Client, archivedChannel, "#hashtag for post3")
+ th.Client.DeleteChannel(archivedChannel.Id)
+
posts, resp := Client.SearchPosts(th.BasicTeam.Id, "search", false)
CheckNoError(t, resp)
if len(posts.Order) != 3 {
@@ -1306,6 +1310,12 @@ func TestSearchPosts(t *testing.T) {
t.Fatal("wrong search")
}
+ posts, resp = Client.SearchPostsIncludeDeletedChannels(th.BasicTeam.Id, "#hashtag", false)
+ CheckNoError(t, resp)
+ if len(posts.Order) != 2 {
+ t.Fatal("wrong search")
+ }
+
if posts, resp = Client.SearchPosts(th.BasicTeam.Id, "*", false); len(posts.Order) != 0 {
t.Fatal("searching for just * shouldn't return any results")
}
@@ -1328,7 +1338,6 @@ func TestSearchPosts(t *testing.T) {
Client.Logout()
_, resp = Client.SearchPosts(th.BasicTeam.Id, "#sgtitlereview", false)
CheckUnauthorizedStatus(t, resp)
-
}
func TestSearchHashtagPosts(t *testing.T) {
diff --git a/api4/reaction_test.go b/api4/reaction_test.go
index dda9a578a..ca2c49808 100644
--- a/api4/reaction_test.go
+++ b/api4/reaction_test.go
@@ -176,7 +176,7 @@ func TestSaveReaction(t *testing.T) {
t.Run("unable-to-react-in-read-only-town-square", func(t *testing.T) {
th.LoginBasic()
- channel, err := th.App.GetChannelByName("town-square", th.BasicTeam.Id)
+ channel, err := th.App.GetChannelByName("town-square", th.BasicTeam.Id, true)
assert.Nil(t, err)
post := th.CreatePostWithClient(th.Client, channel)
@@ -482,7 +482,7 @@ func TestDeleteReaction(t *testing.T) {
t.Run("unable-to-delete-reactions-in-read-only-town-square", func(t *testing.T) {
th.LoginBasic()
- channel, err := th.App.GetChannelByName("town-square", th.BasicTeam.Id)
+ channel, err := th.App.GetChannelByName("town-square", th.BasicTeam.Id, true)
assert.Nil(t, err)
post := th.CreatePostWithClient(th.Client, channel)
diff --git a/app/authorization.go b/app/authorization.go
index 3de50e27b..0955cb90c 100644
--- a/app/authorization.go
+++ b/app/authorization.go
@@ -37,7 +37,7 @@ func (a *App) SessionHasPermissionToChannel(session model.Session, channelId str
return false
}
- cmc := a.Srv.Store.Channel().GetAllChannelMembersForUser(session.UserId, true)
+ cmc := a.Srv.Store.Channel().GetAllChannelMembersForUser(session.UserId, true, true)
var channelRoles []string
if cmcresult := <-cmc; cmcresult.Err == nil {
diff --git a/app/channel.go b/app/channel.go
index 619cc09eb..830dbb8b7 100644
--- a/app/channel.go
+++ b/app/channel.go
@@ -393,7 +393,7 @@ func (a *App) GetGroupChannel(userIds []string) (*model.Channel, *model.AppError
return nil, model.NewAppError("GetGroupChannel", "api.channel.create_group.bad_user.app_error", nil, "user_ids="+model.ArrayToJson(userIds), http.StatusBadRequest)
}
- channel, err := a.GetChannelByName(model.GetGroupNameFromUserIds(userIds), "")
+ channel, err := a.GetChannelByName(model.GetGroupNameFromUserIds(userIds), "", true)
if err != nil {
return nil, err
}
@@ -1011,16 +1011,26 @@ func (a *App) GetChannel(channelId string) (*model.Channel, *model.AppError) {
}
}
-func (a *App) GetChannelByName(channelName, teamId string) (*model.Channel, *model.AppError) {
- if result := <-a.Srv.Store.Channel().GetByName(teamId, channelName, true); result.Err != nil && result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" {
+func (a *App) GetChannelByName(channelName, teamId string, includeDeleted bool) (*model.Channel, *model.AppError) {
+ var result store.StoreResult
+
+ if includeDeleted {
+ result = <-a.Srv.Store.Channel().GetByNameIncludeDeleted(teamId, channelName, false)
+ } else {
+ result = <-a.Srv.Store.Channel().GetByName(teamId, channelName, false)
+ }
+
+ if result.Err != nil && result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" {
result.Err.StatusCode = http.StatusNotFound
return nil, result.Err
- } else if result.Err != nil {
+ }
+
+ if result.Err != nil {
result.Err.StatusCode = http.StatusBadRequest
return nil, result.Err
- } else {
- return result.Data.(*model.Channel), nil
}
+
+ return result.Data.(*model.Channel), nil
}
func (a *App) GetChannelsByNames(channelNames []string, teamId string) ([]*model.Channel, *model.AppError) {
@@ -1035,7 +1045,7 @@ func (a *App) GetChannelsByNames(channelNames []string, teamId string) ([]*model
}
}
-func (a *App) GetChannelByNameForTeamName(channelName, teamName string) (*model.Channel, *model.AppError) {
+func (a *App) GetChannelByNameForTeamName(channelName, teamName string, includeDeleted bool) (*model.Channel, *model.AppError) {
var team *model.Team
if result := <-a.Srv.Store.Team().GetByName(teamName); result.Err != nil {
@@ -1045,19 +1055,28 @@ func (a *App) GetChannelByNameForTeamName(channelName, teamName string) (*model.
team = result.Data.(*model.Team)
}
- if result := <-a.Srv.Store.Channel().GetByName(team.Id, channelName, true); result.Err != nil && result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" {
+ var result store.StoreResult
+ if includeDeleted {
+ result = <-a.Srv.Store.Channel().GetByNameIncludeDeleted(team.Id, channelName, false)
+ } else {
+ result = <-a.Srv.Store.Channel().GetByName(team.Id, channelName, false)
+ }
+
+ if result.Err != nil && result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" {
result.Err.StatusCode = http.StatusNotFound
return nil, result.Err
- } else if result.Err != nil {
+ }
+
+ if result.Err != nil {
result.Err.StatusCode = http.StatusBadRequest
return nil, result.Err
- } else {
- return result.Data.(*model.Channel), nil
}
+
+ return result.Data.(*model.Channel), nil
}
-func (a *App) GetChannelsForUser(teamId string, userId string) (*model.ChannelList, *model.AppError) {
- if result := <-a.Srv.Store.Channel().GetChannels(teamId, userId); result.Err != nil {
+func (a *App) GetChannelsForUser(teamId string, userId string, includeDeleted bool) (*model.ChannelList, *model.AppError) {
+ if result := <-a.Srv.Store.Channel().GetChannels(teamId, userId, includeDeleted); result.Err != nil {
return nil, result.Err
} else {
return result.Data.(*model.ChannelList), nil
@@ -1494,7 +1513,9 @@ func (a *App) UpdateChannelLastViewedAt(channelIds []string, userId string) *mod
}
func (a *App) AutocompleteChannels(teamId string, term string) (*model.ChannelList, *model.AppError) {
- if result := <-a.Srv.Store.Channel().AutocompleteInTeam(teamId, term); result.Err != nil {
+ includeDeleted := *a.Config().TeamSettings.ViewArchivedChannels
+
+ if result := <-a.Srv.Store.Channel().AutocompleteInTeam(teamId, term, includeDeleted); result.Err != nil {
return nil, result.Err
} else {
return result.Data.(*model.ChannelList), nil
@@ -1502,7 +1523,9 @@ func (a *App) AutocompleteChannels(teamId string, term string) (*model.ChannelLi
}
func (a *App) SearchChannels(teamId string, term string) (*model.ChannelList, *model.AppError) {
- if result := <-a.Srv.Store.Channel().SearchInTeam(teamId, term); result.Err != nil {
+ includeDeleted := *a.Config().TeamSettings.ViewArchivedChannels
+
+ if result := <-a.Srv.Store.Channel().SearchInTeam(teamId, term, includeDeleted); result.Err != nil {
return nil, result.Err
} else {
return result.Data.(*model.ChannelList), nil
diff --git a/app/channel_test.go b/app/channel_test.go
index fa9520b52..ba5f3eb58 100644
--- a/app/channel_test.go
+++ b/app/channel_test.go
@@ -175,7 +175,7 @@ func TestJoinDefaultChannelsExperimentalDefaultChannels(t *testing.T) {
th.App.JoinDefaultChannels(th.BasicTeam.Id, user, false, "")
for _, channelName := range defaultChannelList {
- channel, err := th.App.GetChannelByName(channelName, th.BasicTeam.Id)
+ channel, err := th.App.GetChannelByName(channelName, th.BasicTeam.Id, false)
if err != nil {
t.Errorf("Expected nil, got %s", err)
diff --git a/app/command_invite.go b/app/command_invite.go
index 54cf2da02..86cc5fdbb 100644
--- a/app/command_invite.go
+++ b/app/command_invite.go
@@ -59,7 +59,7 @@ func (me *InviteProvider) DoCommand(a *App, args *model.CommandArgs, message str
if len(splitMessage) > 1 && splitMessage[1] != "" {
targetChannelName := strings.TrimPrefix(strings.TrimSpace(splitMessage[1]), "~")
- if channelToJoin, err = a.GetChannelByName(targetChannelName, args.TeamId); err != nil {
+ if channelToJoin, err = a.GetChannelByName(targetChannelName, args.TeamId, false); err != nil {
return &model.CommandResponse{Text: args.T("api.command_invite.channel.error", map[string]interface{}{"Channel": targetChannelName}), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
} else {
diff --git a/app/import.go b/app/import.go
index dc4b65396..50973d504 100644
--- a/app/import.go
+++ b/app/import.go
@@ -1116,7 +1116,7 @@ func (a *App) ImportUserTeams(user *model.User, data *[]UserTeamImportData) *mod
a.UpdateTeamMemberSchemeRoles(team.Id, user.Id, isSchemeUser, isSchemeAdmin)
}
- if defaultChannel, err := a.GetChannelByName(model.DEFAULT_CHANNEL, team.Id); err != nil {
+ if defaultChannel, err := a.GetChannelByName(model.DEFAULT_CHANNEL, team.Id, true); err != nil {
return err
} else if _, err = a.addUserToChannel(user, defaultChannel, member); err != nil {
return err
@@ -1139,7 +1139,7 @@ func (a *App) ImportUserChannels(user *model.User, team *model.Team, teamMember
// Loop through all channels.
for _, cdata := range *data {
- channel, err := a.GetChannelByName(*cdata.Name, team.Id)
+ channel, err := a.GetChannelByName(*cdata.Name, team.Id, true)
if err != nil {
return err
}
diff --git a/app/import_test.go b/app/import_test.go
index f99e100f1..a8e5a65a8 100644
--- a/app/import_test.go
+++ b/app/import_test.go
@@ -1898,7 +1898,7 @@ func TestImportImportChannel(t *testing.T) {
th.CheckChannelsCount(t, channelCount+1)
// Get the Channel and check all the fields are correct.
- if channel, err := th.App.GetChannelByName(*data.Name, team.Id); err != nil {
+ if channel, err := th.App.GetChannelByName(*data.Name, team.Id, false); err != nil {
t.Fatalf("Failed to get channel from database.")
} else {
assert.Equal(t, *data.Name, channel.Name)
@@ -1923,7 +1923,7 @@ func TestImportImportChannel(t *testing.T) {
th.CheckChannelsCount(t, channelCount)
// Get the Channel and check all the fields are correct.
- if channel, err := th.App.GetChannelByName(*data.Name, team.Id); err != nil {
+ if channel, err := th.App.GetChannelByName(*data.Name, team.Id, false); err != nil {
t.Fatalf("Failed to get channel from database.")
} else {
assert.Equal(t, *data.Name, channel.Name)
@@ -2157,7 +2157,7 @@ func TestImportImportUser(t *testing.T) {
DisplayName: ptrStr("Display Name"),
Type: ptrStr("O"),
}, false)
- channel, err := th.App.GetChannelByName(channelName, team.Id)
+ channel, err := th.App.GetChannelByName(channelName, team.Id, false)
if err != nil {
t.Fatalf("Failed to get channel from database.")
}
@@ -2671,7 +2671,7 @@ func TestImportImportUser(t *testing.T) {
if err := th.App.ImportChannel(channelData, false); err != nil {
t.Fatalf("Import should have succeeded.")
}
- channel, err = th.App.GetChannelByName(*channelData.Name, team.Id)
+ channel, err = th.App.GetChannelByName(*channelData.Name, team.Id, false)
if err != nil {
t.Fatalf("Failed to get channel from database: %v", err.Error())
}
@@ -2755,7 +2755,7 @@ func TestImportImportPost(t *testing.T) {
DisplayName: ptrStr("Display Name"),
Type: ptrStr("O"),
}, false)
- channel, err := th.App.GetChannelByName(channelName, team.Id)
+ channel, err := th.App.GetChannelByName(channelName, team.Id, false)
if err != nil {
t.Fatalf("Failed to get channel from database.")
}
@@ -3959,7 +3959,7 @@ func TestImportPostAndRepliesWithAttachments(t *testing.T) {
DisplayName: ptrStr("Display Name"),
Type: ptrStr("O"),
}, false)
- _, err = th.App.GetChannelByName(channelName, team.Id)
+ _, err = th.App.GetChannelByName(channelName, team.Id, false)
if err != nil {
t.Fatalf("Failed to get channel from database.")
}
diff --git a/app/plugin_api.go b/app/plugin_api.go
index 414ce4d6e..66f17bdfb 100644
--- a/app/plugin_api.go
+++ b/app/plugin_api.go
@@ -195,12 +195,12 @@ func (api *PluginAPI) GetChannel(channelId string) (*model.Channel, *model.AppEr
return api.app.GetChannel(channelId)
}
-func (api *PluginAPI) GetChannelByName(teamId, name string) (*model.Channel, *model.AppError) {
- return api.app.GetChannelByName(name, teamId)
+func (api *PluginAPI) GetChannelByName(teamId, name string, includeDeleted bool) (*model.Channel, *model.AppError) {
+ return api.app.GetChannelByName(name, teamId, includeDeleted)
}
-func (api *PluginAPI) GetChannelByNameForTeamName(teamName, channelName string) (*model.Channel, *model.AppError) {
- return api.app.GetChannelByNameForTeamName(channelName, teamName)
+func (api *PluginAPI) GetChannelByNameForTeamName(teamName, channelName string, includeDeleted bool) (*model.Channel, *model.AppError) {
+ return api.app.GetChannelByNameForTeamName(channelName, teamName, includeDeleted)
}
func (api *PluginAPI) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) {
diff --git a/app/post.go b/app/post.go
index 0344d8f0d..8c44436aa 100644
--- a/app/post.go
+++ b/app/post.go
@@ -638,8 +638,9 @@ func (a *App) DeletePostFiles(post *model.Post) {
}
}
-func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOrSearch bool) (*model.PostSearchResults, *model.AppError) {
+func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOrSearch bool, includeDeletedChannels bool) (*model.PostSearchResults, *model.AppError) {
paramsList := model.ParseSearchParams(terms)
+ includeDeleted := includeDeletedChannels && *a.Config().TeamSettings.ViewArchivedChannels
esInterface := a.Elasticsearch
if license := a.License(); esInterface != nil && *a.Config().ElasticsearchSettings.EnableSearching && license != nil && *license.Features.Elasticsearch {
@@ -651,7 +652,7 @@ func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOr
if params.Terms != "*" {
// Convert channel names to channel IDs
for idx, channelName := range params.InChannels {
- if channel, err := a.GetChannelByName(channelName, teamId); err != nil {
+ if channel, err := a.GetChannelByName(channelName, teamId, includeDeleted); err != nil {
mlog.Error(fmt.Sprint(err))
} else {
params.InChannels[idx] = channel.Id
@@ -677,7 +678,7 @@ func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOr
}
// We only allow the user to search in channels they are a member of.
- userChannels, err := a.GetChannelsForUser(teamId, userId)
+ userChannels, err := a.GetChannelsForUser(teamId, userId, includeDeleted)
if err != nil {
mlog.Error(fmt.Sprint(err))
return nil, err
@@ -710,6 +711,7 @@ func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOr
channels := []store.StoreChannel{}
for _, params := range paramsList {
+ params.IncludeDeletedChannels = includeDeleted
params.OrTerms = isOrSearch
// don't allow users to search for everything
if params.Terms != "*" {
diff --git a/app/team.go b/app/team.go
index ff1037b7c..8d1331823 100644
--- a/app/team.go
+++ b/app/team.go
@@ -715,7 +715,7 @@ func (a *App) LeaveTeam(team *model.Team, user *model.User, requestorId string)
var channelList *model.ChannelList
- if result := <-a.Srv.Store.Channel().GetChannels(team.Id, user.Id); result.Err != nil {
+ if result := <-a.Srv.Store.Channel().GetChannels(team.Id, user.Id, true); result.Err != nil {
if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" {
channelList = &model.ChannelList{}
} else {
diff --git a/app/user.go b/app/user.go
index b9a97b2a9..fa4f36ff1 100644
--- a/app/user.go
+++ b/app/user.go
@@ -901,7 +901,7 @@ func (a *App) UpdateActive(user *model.User, active bool) (*model.User, *model.A
}
for _, team := range teamsForUser {
- channelsForUser, err := a.GetChannelsForUser(team.Id, user.Id)
+ channelsForUser, err := a.GetChannelsForUser(team.Id, user.Id, false)
if err != nil {
return nil, err
}
diff --git a/app/web_conn.go b/app/web_conn.go
index 47fae24c3..1c314bb11 100644
--- a/app/web_conn.go
+++ b/app/web_conn.go
@@ -334,7 +334,7 @@ func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool {
}
if webCon.AllChannelMembers == nil {
- if result := <-webCon.App.Srv.Store.Channel().GetAllChannelMembersForUser(webCon.UserId, true); result.Err != nil {
+ if result := <-webCon.App.Srv.Store.Channel().GetAllChannelMembersForUser(webCon.UserId, true, false); result.Err != nil {
mlog.Error("webhub.shouldSendEvent: " + result.Err.Error())
return false
} else {
diff --git a/config/default.json b/config/default.json
index d0c18e60c..22f94d8f0 100644
--- a/config/default.json
+++ b/config/default.json
@@ -101,6 +101,7 @@
"MaxNotificationsPerChannel": 1000,
"EnableConfirmNotificationsToChannel": true,
"TeammateNameDisplay": "username",
+ "ViewArchivedChannels": true,
"ExperimentalEnableAutomaticReplies": false,
"ExperimentalHideTownSquareinLHS": false,
"ExperimentalTownSquareIsReadOnly": false,
diff --git a/manualtesting/manual_testing.go b/manualtesting/manual_testing.go
index 2dbe61343..df72fbb57 100644
--- a/manualtesting/manual_testing.go
+++ b/manualtesting/manual_testing.go
@@ -154,7 +154,7 @@ func manualTest(c *web.Context, w http.ResponseWriter, r *http.Request) {
func getChannelID(a *app.App, channelname string, teamid string, userid string) (id string, err bool) {
// Grab all the channels
- result := <-a.Srv.Store.Channel().GetChannels(teamid, userid)
+ result := <-a.Srv.Store.Channel().GetChannels(teamid, userid, false)
if result.Err != nil {
mlog.Debug("Unable to get channels")
return "", false
diff --git a/model/client4.go b/model/client4.go
index d34354715..48627c4b0 100644
--- a/model/client4.go
+++ b/model/client4.go
@@ -1791,6 +1791,15 @@ func (c *Client4) GetChannelByName(channelName, teamId string, etag string) (*Ch
}
}
+func (c *Client4) GetChannelByNameIncludeDeleted(channelName, teamId string, etag string) (*Channel, *Response) {
+ if r, err := c.DoApiGet(c.GetChannelByNameRoute(channelName, teamId)+"?include_deleted=true", etag); err != nil {
+ return nil, BuildErrorResponse(r, err)
+ } else {
+ defer closeBody(r)
+ return ChannelFromJson(r.Body), BuildResponse(r)
+ }
+}
+
// GetChannelByNameForTeamName returns a channel based on the provided channel name and team name strings.
func (c *Client4) GetChannelByNameForTeamName(channelName, teamName string, etag string) (*Channel, *Response) {
if r, err := c.DoApiGet(c.GetChannelByNameForTeamNameRoute(channelName, teamName), etag); err != nil {
@@ -1801,6 +1810,15 @@ func (c *Client4) GetChannelByNameForTeamName(channelName, teamName string, etag
}
}
+func (c *Client4) GetChannelByNameForTeamNameIncludeDeleted(channelName, teamName string, etag string) (*Channel, *Response) {
+ if r, err := c.DoApiGet(c.GetChannelByNameForTeamNameRoute(channelName, teamName)+"?include_deleted=true", etag); err != nil {
+ return nil, BuildErrorResponse(r, err)
+ } else {
+ defer closeBody(r)
+ return ChannelFromJson(r.Body), BuildResponse(r)
+ }
+}
+
// GetChannelMembers gets a page of channel members.
func (c *Client4) GetChannelMembers(channelId string, page, perPage int, etag string) (*ChannelMembers, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)
@@ -2127,6 +2145,17 @@ func (c *Client4) SearchPosts(teamId string, terms string, isOrSearch bool) (*Po
}
}
+// SearchPosts returns any posts with matching terms string including deleted channels.
+func (c *Client4) SearchPostsIncludeDeletedChannels(teamId string, terms string, isOrSearch bool) (*PostList, *Response) {
+ requestBody := map[string]interface{}{"terms": terms, "is_or_search": isOrSearch}
+ if r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/posts/search?include_deleted_channels=true", StringInterfaceToJson(requestBody)); err != nil {
+ return nil, BuildErrorResponse(r, err)
+ } else {
+ defer closeBody(r)
+ return PostListFromJson(r.Body), BuildResponse(r)
+ }
+}
+
// SearchPosts returns any posts with matching terms string, including .
func (c *Client4) SearchPostsWithMatches(teamId string, terms string, isOrSearch bool) (*PostSearchResults, *Response) {
requestBody := map[string]interface{}{"terms": terms, "is_or_search": isOrSearch}
diff --git a/model/config.go b/model/config.go
index aa7900279..e38c993a8 100644
--- a/model/config.go
+++ b/model/config.go
@@ -1125,6 +1125,7 @@ type TeamSettings struct {
MaxNotificationsPerChannel *int64
EnableConfirmNotificationsToChannel *bool
TeammateNameDisplay *string
+ ViewArchivedChannels *bool
ExperimentalEnableAutomaticReplies *bool
ExperimentalHideTownSquareinLHS *bool
ExperimentalTownSquareIsReadOnly *bool
@@ -1254,6 +1255,9 @@ func (s *TeamSettings) SetDefaults() {
s.EnableUserCreation = NewBool(true)
}
+ if s.ViewArchivedChannels == nil {
+ s.ViewArchivedChannels = NewBool(true)
+ }
}
type ClientRequirements struct {
diff --git a/model/search_params.go b/model/search_params.go
index 481671ab5..21aa69a0d 100644
--- a/model/search_params.go
+++ b/model/search_params.go
@@ -12,11 +12,12 @@ var searchTermPuncStart = regexp.MustCompile(`^[^\pL\d\s#"]+`)
var searchTermPuncEnd = regexp.MustCompile(`[^\pL\d\s*"]+$`)
type SearchParams struct {
- Terms string
- IsHashtag bool
- InChannels []string
- FromUsers []string
- OrTerms bool
+ Terms string
+ IsHashtag bool
+ InChannels []string
+ FromUsers []string
+ OrTerms bool
+ IncludeDeletedChannels bool
}
var searchFlags = [...]string{"from", "channel", "in"}
diff --git a/plugin/api.go b/plugin/api.go
index 6d4976c4f..0b413d4d1 100644
--- a/plugin/api.go
+++ b/plugin/api.go
@@ -108,10 +108,10 @@ type API interface {
GetChannel(channelId string) (*model.Channel, *model.AppError)
// GetChannelByName gets a channel by its name, given a team id.
- GetChannelByName(teamId, name string) (*model.Channel, *model.AppError)
+ GetChannelByName(teamId, name string, includeDeleted bool) (*model.Channel, *model.AppError)
// GetChannelByNameForTeamName gets a channel by its name, given a team name.
- GetChannelByNameForTeamName(teamName, channelName string) (*model.Channel, *model.AppError)
+ GetChannelByNameForTeamName(teamName, channelName string, includeDeleted bool) (*model.Channel, *model.AppError)
// GetDirectChannel gets a direct message channel.
GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError)
diff --git a/plugin/client_rpc_generated.go b/plugin/client_rpc_generated.go
index 9eac71be4..98b906186 100644
--- a/plugin/client_rpc_generated.go
+++ b/plugin/client_rpc_generated.go
@@ -1349,6 +1349,7 @@ func (s *apiRPCServer) GetChannel(args *Z_GetChannelArgs, returns *Z_GetChannelR
type Z_GetChannelByNameArgs struct {
A string
B string
+ C bool
}
type Z_GetChannelByNameReturns struct {
@@ -1356,8 +1357,8 @@ type Z_GetChannelByNameReturns struct {
B *model.AppError
}
-func (g *apiRPCClient) GetChannelByName(teamId, name string) (*model.Channel, *model.AppError) {
- _args := &Z_GetChannelByNameArgs{teamId, name}
+func (g *apiRPCClient) GetChannelByName(teamId, name string, includeDeleted bool) (*model.Channel, *model.AppError) {
+ _args := &Z_GetChannelByNameArgs{teamId, name, includeDeleted}
_returns := &Z_GetChannelByNameReturns{}
if err := g.client.Call("Plugin.GetChannelByName", _args, _returns); err != nil {
log.Printf("RPC call to GetChannelByName API failed: %s", err.Error())
@@ -1367,9 +1368,9 @@ func (g *apiRPCClient) GetChannelByName(teamId, name string) (*model.Channel, *m
func (s *apiRPCServer) GetChannelByName(args *Z_GetChannelByNameArgs, returns *Z_GetChannelByNameReturns) error {
if hook, ok := s.impl.(interface {
- GetChannelByName(teamId, name string) (*model.Channel, *model.AppError)
+ GetChannelByName(teamId, name string, includeDeleted bool) (*model.Channel, *model.AppError)
}); ok {
- returns.A, returns.B = hook.GetChannelByName(args.A, args.B)
+ returns.A, returns.B = hook.GetChannelByName(args.A, args.B, args.C)
} else {
return fmt.Errorf("API GetChannelByName called but not implemented.")
}
@@ -1379,6 +1380,7 @@ func (s *apiRPCServer) GetChannelByName(args *Z_GetChannelByNameArgs, returns *Z
type Z_GetChannelByNameForTeamNameArgs struct {
A string
B string
+ C bool
}
type Z_GetChannelByNameForTeamNameReturns struct {
@@ -1386,8 +1388,8 @@ type Z_GetChannelByNameForTeamNameReturns struct {
B *model.AppError
}
-func (g *apiRPCClient) GetChannelByNameForTeamName(teamName, channelName string) (*model.Channel, *model.AppError) {
- _args := &Z_GetChannelByNameForTeamNameArgs{teamName, channelName}
+func (g *apiRPCClient) GetChannelByNameForTeamName(teamName, channelName string, includeDeleted bool) (*model.Channel, *model.AppError) {
+ _args := &Z_GetChannelByNameForTeamNameArgs{teamName, channelName, includeDeleted}
_returns := &Z_GetChannelByNameForTeamNameReturns{}
if err := g.client.Call("Plugin.GetChannelByNameForTeamName", _args, _returns); err != nil {
log.Printf("RPC call to GetChannelByNameForTeamName API failed: %s", err.Error())
@@ -1397,9 +1399,9 @@ func (g *apiRPCClient) GetChannelByNameForTeamName(teamName, channelName string)
func (s *apiRPCServer) GetChannelByNameForTeamName(args *Z_GetChannelByNameForTeamNameArgs, returns *Z_GetChannelByNameForTeamNameReturns) error {
if hook, ok := s.impl.(interface {
- GetChannelByNameForTeamName(teamName, channelName string) (*model.Channel, *model.AppError)
+ GetChannelByNameForTeamName(teamName, channelName string, includeDeleted bool) (*model.Channel, *model.AppError)
}); ok {
- returns.A, returns.B = hook.GetChannelByNameForTeamName(args.A, args.B)
+ returns.A, returns.B = hook.GetChannelByNameForTeamName(args.A, args.B, args.C)
} else {
return fmt.Errorf("API GetChannelByNameForTeamName called but not implemented.")
}
diff --git a/plugin/example_help_test.go b/plugin/example_help_test.go
index 3f9be9a20..175b6588e 100644
--- a/plugin/example_help_test.go
+++ b/plugin/example_help_test.go
@@ -30,7 +30,7 @@ func (p *HelpPlugin) OnConfigurationChange() error {
return nil
}
- channel, err := p.API.GetChannelByName(p.ChannelName, team.Id)
+ channel, err := p.API.GetChannelByName(p.ChannelName, team.Id, false)
if err != nil {
p.API.LogError("failed to find channel", "channel_name", p.ChannelName)
return nil
diff --git a/plugin/plugintest/api.go b/plugin/plugintest/api.go
index 473ef6d2b..70e90df4b 100644
--- a/plugin/plugintest/api.go
+++ b/plugin/plugintest/api.go
@@ -308,13 +308,13 @@ func (_m *API) GetChannel(channelId string) (*model.Channel, *model.AppError) {
return r0, r1
}
-// GetChannelByName provides a mock function with given fields: teamId, name
-func (_m *API) GetChannelByName(teamId string, name string) (*model.Channel, *model.AppError) {
- ret := _m.Called(teamId, name)
+// GetChannelByName provides a mock function with given fields: teamId, name, includeDeleted
+func (_m *API) GetChannelByName(teamId string, name string, includeDeleted bool) (*model.Channel, *model.AppError) {
+ ret := _m.Called(teamId, name, includeDeleted)
var r0 *model.Channel
- if rf, ok := ret.Get(0).(func(string, string) *model.Channel); ok {
- r0 = rf(teamId, name)
+ if rf, ok := ret.Get(0).(func(string, string, bool) *model.Channel); ok {
+ r0 = rf(teamId, name, includeDeleted)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.Channel)
@@ -322,8 +322,8 @@ func (_m *API) GetChannelByName(teamId string, name string) (*model.Channel, *mo
}
var r1 *model.AppError
- if rf, ok := ret.Get(1).(func(string, string) *model.AppError); ok {
- r1 = rf(teamId, name)
+ if rf, ok := ret.Get(1).(func(string, string, bool) *model.AppError); ok {
+ r1 = rf(teamId, name, includeDeleted)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
@@ -333,13 +333,13 @@ func (_m *API) GetChannelByName(teamId string, name string) (*model.Channel, *mo
return r0, r1
}
-// GetChannelByNameForTeamName provides a mock function with given fields: teamName, channelName
-func (_m *API) GetChannelByNameForTeamName(teamName string, channelName string) (*model.Channel, *model.AppError) {
- ret := _m.Called(teamName, channelName)
+// GetChannelByNameForTeamName provides a mock function with given fields: teamName, channelName, includeDeleted
+func (_m *API) GetChannelByNameForTeamName(teamName string, channelName string, includeDeleted bool) (*model.Channel, *model.AppError) {
+ ret := _m.Called(teamName, channelName, includeDeleted)
var r0 *model.Channel
- if rf, ok := ret.Get(0).(func(string, string) *model.Channel); ok {
- r0 = rf(teamName, channelName)
+ if rf, ok := ret.Get(0).(func(string, string, bool) *model.Channel); ok {
+ r0 = rf(teamName, channelName, includeDeleted)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.Channel)
@@ -347,8 +347,8 @@ func (_m *API) GetChannelByNameForTeamName(teamName string, channelName string)
}
var r1 *model.AppError
- if rf, ok := ret.Get(1).(func(string, string) *model.AppError); ok {
- r1 = rf(teamName, channelName)
+ if rf, ok := ret.Get(1).(func(string, string, bool) *model.AppError); ok {
+ r1 = rf(teamName, channelName, includeDeleted)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
diff --git a/store/sqlstore/channel_store.go b/store/sqlstore/channel_store.go
index 63e924e21..c073680f4 100644
--- a/store/sqlstore/channel_store.go
+++ b/store/sqlstore/channel_store.go
@@ -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`
diff --git a/store/sqlstore/post_store.go b/store/sqlstore/post_store.go
index 229005b73..90db80796 100644
--- a/store/sqlstore/post_store.go
+++ b/store/sqlstore/post_store.go
@@ -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
diff --git a/store/store.go b/store/store.go
index 203c637ff..2f18a0d8f 100644
--- a/store/store.go
+++ b/store/store.go
@@ -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
diff --git a/store/storetest/channel_store.go b/store/storetest/channel_store.go
index ccf4b1c59..9b5ac9e38 100644
--- a/store/storetest/channel_store.go
+++ b/store/storetest/channel_store.go
@@ -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)
diff --git a/store/storetest/mocks/ChannelStore.go b/store/storetest/mocks/ChannelStore.go
index 4929557ea..4cbf9cb77 100644
--- a/store/storetest/mocks/ChannelStore.go
+++ b/store/storetest/mocks/ChannelStore.go
@@ -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)
diff --git a/store/storetest/post_store.go b/store/storetest/post_store.go
index 1159af37f..da1b069a2 100644
--- a/store/storetest/post_store.go
+++ b/store/storetest/post_store.go
@@ -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")
- }
-
- 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")
- }
-
- 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")
- }
-
- 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")
- }
-
- 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")
- }
+ o6 := &model.Post{}
+ o6.ChannelId = c3.Id
+ o6.UserId = model.NewId()
+ o6.Hashtags = "#hashtag"
+ o6 = (<-ss.Post().Save(o6)).Data.(*model.Post)
- 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")
+ 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)
+
+ o8 := &model.Post{}
+ o8.ChannelId = c3.Id
+ o8.UserId = model.NewId()
+ o8.Message = "Deleted"
+ o8 = (<-ss.Post().Save(o8)).Data.(*model.Post)
+
+ 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},
+ },
}
-
- 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)
+ }
+ })
}
}
diff --git a/utils/config.go b/utils/config.go
index 0a20c1723..4bbe4cd15 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -512,6 +512,7 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
props["EnableXToLeaveChannelsFromLHS"] = strconv.FormatBool(*c.TeamSettings.EnableXToLeaveChannelsFromLHS)
props["TeammateNameDisplay"] = *c.TeamSettings.TeammateNameDisplay
props["ExperimentalPrimaryTeam"] = *c.TeamSettings.ExperimentalPrimaryTeam
+ props["ViewArchivedChannels"] = strconv.FormatBool(*c.TeamSettings.ViewArchivedChannels)
props["EnableOAuthServiceProvider"] = strconv.FormatBool(c.ServiceSettings.EnableOAuthServiceProvider)
props["GoogleDeveloperKey"] = c.ServiceSettings.GoogleDeveloperKey