* 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 удалений

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

@@ -44,6 +44,7 @@ type TestHelper struct {
BasicTeam *model.Team BasicTeam *model.Team
BasicChannel *model.Channel BasicChannel *model.Channel
BasicPrivateChannel *model.Channel BasicPrivateChannel *model.Channel
BasicDeletedChannel *model.Channel
BasicChannel2 *model.Channel BasicChannel2 *model.Channel
BasicPost *model.Post BasicPost *model.Post
@@ -250,6 +251,7 @@ func (me *TestHelper) InitBasic() *TestHelper {
me.BasicTeam = me.CreateTeam() me.BasicTeam = me.CreateTeam()
me.BasicChannel = me.CreatePublicChannel() me.BasicChannel = me.CreatePublicChannel()
me.BasicPrivateChannel = me.CreatePrivateChannel() me.BasicPrivateChannel = me.CreatePrivateChannel()
me.BasicDeletedChannel = me.CreatePublicChannel()
me.BasicChannel2 = me.CreatePublicChannel() me.BasicChannel2 = me.CreatePublicChannel()
me.BasicPost = me.CreatePost() me.BasicPost = me.CreatePost()
me.BasicUser = me.CreateUser() me.BasicUser = me.CreateUser()
@@ -262,7 +264,10 @@ func (me *TestHelper) InitBasic() *TestHelper {
me.App.AddUserToChannel(me.BasicUser2, me.BasicChannel2) me.App.AddUserToChannel(me.BasicUser2, me.BasicChannel2)
me.App.AddUserToChannel(me.BasicUser, me.BasicPrivateChannel) me.App.AddUserToChannel(me.BasicUser, me.BasicPrivateChannel)
me.App.AddUserToChannel(me.BasicUser2, 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.App.UpdateUserRoles(me.BasicUser.Id, model.SYSTEM_USER_ROLE_ID, false)
me.Client.DeleteChannel(me.BasicDeletedChannel.Id)
me.LoginBasic() me.LoginBasic()
return me return me

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

@@ -589,7 +589,7 @@ func getChannelsForTeamForUser(c *Context, w http.ResponseWriter, r *http.Reques
return 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 { if err != nil {
c.Err = err c.Err = err
return return
@@ -709,7 +709,9 @@ func getChannelByName(c *Context, w http.ResponseWriter, r *http.Request) {
var channel *model.Channel var channel *model.Channel
var err *model.AppError 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 c.Err = err
return return
} }
@@ -744,7 +746,9 @@ func getChannelByNameForTeamName(c *Context, w http.ResponseWriter, r *http.Requ
var channel *model.Channel var channel *model.Channel
var err *model.AppError 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 c.Err = err
return return
} }

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

@@ -867,7 +867,7 @@ func TestDeleteChannel(t *testing.T) {
CheckNoError(t, resp) CheckNoError(t, resp)
// default channel cannot be deleted. // 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) pass, resp = Client.DeleteChannel(defaultChannel.Id)
CheckBadRequestStatus(t, resp) CheckBadRequestStatus(t, resp)
@@ -998,7 +998,7 @@ func TestConvertChannelToPrivate(t *testing.T) {
defer th.TearDown() defer th.TearDown()
Client := th.Client 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) _, resp := Client.ConvertChannelToPrivate(defaultChannel.Id)
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
@@ -1115,6 +1115,16 @@ func TestGetChannelByName(t *testing.T) {
_, resp = Client.GetChannelByName(strings.ToUpper(th.BasicPrivateChannel.Name), th.BasicTeam.Id, "") _, resp = Client.GetChannelByName(strings.ToUpper(th.BasicPrivateChannel.Name), th.BasicTeam.Id, "")
CheckNoError(t, resp) 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) Client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id)
_, resp = Client.GetChannelByName(th.BasicChannel.Name, th.BasicTeam.Id, "") _, resp = Client.GetChannelByName(th.BasicChannel.Name, th.BasicTeam.Id, "")
CheckNoError(t, resp) CheckNoError(t, resp)
@@ -1157,6 +1167,16 @@ func TestGetChannelByNameForTeamName(t *testing.T) {
_, resp = Client.GetChannelByNameForTeamName(th.BasicChannel.Name, th.BasicTeam.Name, "") _, resp = Client.GetChannelByNameForTeamName(th.BasicChannel.Name, th.BasicTeam.Name, "")
CheckNoError(t, resp) 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), "") _, resp = Client.GetChannelByNameForTeamName(th.BasicChannel.Name, model.NewRandomString(15), "")
CheckNotFoundStatus(t, resp) CheckNotFoundStatus(t, resp)
@@ -1330,8 +1350,8 @@ func TestGetChannelMembersForUser(t *testing.T) {
members, resp := Client.GetChannelMembersForUser(th.BasicUser.Id, th.BasicTeam.Id, "") members, resp := Client.GetChannelMembersForUser(th.BasicUser.Id, th.BasicTeam.Id, "")
CheckNoError(t, resp) CheckNoError(t, resp)
if len(*members) != 5 { if len(*members) != 6 {
t.Fatal("should have 5 members on team") t.Fatal("should have 6 members on team")
} }
_, resp = Client.GetChannelMembersForUser("", th.BasicTeam.Id, "") _, resp = Client.GetChannelMembersForUser("", th.BasicTeam.Id, "")

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

@@ -330,6 +330,8 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
includeDeletedChannels := r.URL.Query().Get("include_deleted_channels") == "true"
props := model.StringInterfaceFromJson(r.Body) props := model.StringInterfaceFromJson(r.Body)
terms, ok := props["terms"].(string) terms, ok := props["terms"].(string)
if !ok || len(terms) == 0 { if !ok || len(terms) == 0 {
@@ -341,7 +343,7 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
startTime := time.Now() 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) elapsedTime := float64(time.Since(startTime)) / float64(time.Second)
metrics := c.App.Metrics metrics := c.App.Metrics

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

@@ -1288,6 +1288,10 @@ func TestSearchPosts(t *testing.T) {
message = "hashtag for post4" message = "hashtag for post4"
_ = th.CreateMessagePost(message) _ = 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) posts, resp := Client.SearchPosts(th.BasicTeam.Id, "search", false)
CheckNoError(t, resp) CheckNoError(t, resp)
if len(posts.Order) != 3 { if len(posts.Order) != 3 {
@@ -1306,6 +1310,12 @@ func TestSearchPosts(t *testing.T) {
t.Fatal("wrong search") 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 { if posts, resp = Client.SearchPosts(th.BasicTeam.Id, "*", false); len(posts.Order) != 0 {
t.Fatal("searching for just * shouldn't return any results") t.Fatal("searching for just * shouldn't return any results")
} }
@@ -1328,7 +1338,6 @@ func TestSearchPosts(t *testing.T) {
Client.Logout() Client.Logout()
_, resp = Client.SearchPosts(th.BasicTeam.Id, "#sgtitlereview", false) _, resp = Client.SearchPosts(th.BasicTeam.Id, "#sgtitlereview", false)
CheckUnauthorizedStatus(t, resp) CheckUnauthorizedStatus(t, resp)
} }
func TestSearchHashtagPosts(t *testing.T) { func TestSearchHashtagPosts(t *testing.T) {

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

@@ -176,7 +176,7 @@ func TestSaveReaction(t *testing.T) {
t.Run("unable-to-react-in-read-only-town-square", func(t *testing.T) { t.Run("unable-to-react-in-read-only-town-square", func(t *testing.T) {
th.LoginBasic() 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) assert.Nil(t, err)
post := th.CreatePostWithClient(th.Client, channel) 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) { t.Run("unable-to-delete-reactions-in-read-only-town-square", func(t *testing.T) {
th.LoginBasic() 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) assert.Nil(t, err)
post := th.CreatePostWithClient(th.Client, channel) post := th.CreatePostWithClient(th.Client, channel)

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

@@ -37,7 +37,7 @@ func (a *App) SessionHasPermissionToChannel(session model.Session, channelId str
return false return false
} }
cmc := a.Srv.Store.Channel().GetAllChannelMembersForUser(session.UserId, true) cmc := a.Srv.Store.Channel().GetAllChannelMembersForUser(session.UserId, true, true)
var channelRoles []string var channelRoles []string
if cmcresult := <-cmc; cmcresult.Err == nil { if cmcresult := <-cmc; cmcresult.Err == nil {

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

@@ -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) 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 { if err != nil {
return nil, err 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) { func (a *App) GetChannelByName(channelName, teamId string, includeDeleted bool) (*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" { 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 result.Err.StatusCode = http.StatusNotFound
return nil, result.Err return nil, result.Err
} else if result.Err != nil { }
if result.Err != nil {
result.Err.StatusCode = http.StatusBadRequest result.Err.StatusCode = http.StatusBadRequest
return nil, result.Err 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) { 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 var team *model.Team
if result := <-a.Srv.Store.Team().GetByName(teamName); result.Err != nil { 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) 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 result.Err.StatusCode = http.StatusNotFound
return nil, result.Err return nil, result.Err
} else if result.Err != nil { }
if result.Err != nil {
result.Err.StatusCode = http.StatusBadRequest result.Err.StatusCode = http.StatusBadRequest
return nil, result.Err 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) { func (a *App) GetChannelsForUser(teamId string, userId string, includeDeleted bool) (*model.ChannelList, *model.AppError) {
if result := <-a.Srv.Store.Channel().GetChannels(teamId, userId); result.Err != nil { if result := <-a.Srv.Store.Channel().GetChannels(teamId, userId, includeDeleted); result.Err != nil {
return nil, result.Err return nil, result.Err
} else { } else {
return result.Data.(*model.ChannelList), nil 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) { 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 return nil, result.Err
} else { } else {
return result.Data.(*model.ChannelList), nil 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) { 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 return nil, result.Err
} else { } else {
return result.Data.(*model.ChannelList), nil return result.Data.(*model.ChannelList), nil

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

@@ -175,7 +175,7 @@ func TestJoinDefaultChannelsExperimentalDefaultChannels(t *testing.T) {
th.App.JoinDefaultChannels(th.BasicTeam.Id, user, false, "") th.App.JoinDefaultChannels(th.BasicTeam.Id, user, false, "")
for _, channelName := range defaultChannelList { 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 { if err != nil {
t.Errorf("Expected nil, got %s", err) t.Errorf("Expected nil, got %s", err)

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

@@ -59,7 +59,7 @@ func (me *InviteProvider) DoCommand(a *App, args *model.CommandArgs, message str
if len(splitMessage) > 1 && splitMessage[1] != "" { if len(splitMessage) > 1 && splitMessage[1] != "" {
targetChannelName := strings.TrimPrefix(strings.TrimSpace(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} return &model.CommandResponse{Text: args.T("api.command_invite.channel.error", map[string]interface{}{"Channel": targetChannelName}), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
} }
} else { } else {

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

@@ -1116,7 +1116,7 @@ func (a *App) ImportUserTeams(user *model.User, data *[]UserTeamImportData) *mod
a.UpdateTeamMemberSchemeRoles(team.Id, user.Id, isSchemeUser, isSchemeAdmin) 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 return err
} else if _, err = a.addUserToChannel(user, defaultChannel, member); err != nil { } else if _, err = a.addUserToChannel(user, defaultChannel, member); err != nil {
return err return err
@@ -1139,7 +1139,7 @@ func (a *App) ImportUserChannels(user *model.User, team *model.Team, teamMember
// Loop through all channels. // Loop through all channels.
for _, cdata := range *data { for _, cdata := range *data {
channel, err := a.GetChannelByName(*cdata.Name, team.Id) channel, err := a.GetChannelByName(*cdata.Name, team.Id, true)
if err != nil { if err != nil {
return err return err
} }

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

@@ -1898,7 +1898,7 @@ func TestImportImportChannel(t *testing.T) {
th.CheckChannelsCount(t, channelCount+1) th.CheckChannelsCount(t, channelCount+1)
// Get the Channel and check all the fields are correct. // 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.") t.Fatalf("Failed to get channel from database.")
} else { } else {
assert.Equal(t, *data.Name, channel.Name) assert.Equal(t, *data.Name, channel.Name)
@@ -1923,7 +1923,7 @@ func TestImportImportChannel(t *testing.T) {
th.CheckChannelsCount(t, channelCount) th.CheckChannelsCount(t, channelCount)
// Get the Channel and check all the fields are correct. // 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.") t.Fatalf("Failed to get channel from database.")
} else { } else {
assert.Equal(t, *data.Name, channel.Name) assert.Equal(t, *data.Name, channel.Name)
@@ -2157,7 +2157,7 @@ func TestImportImportUser(t *testing.T) {
DisplayName: ptrStr("Display Name"), DisplayName: ptrStr("Display Name"),
Type: ptrStr("O"), Type: ptrStr("O"),
}, false) }, false)
channel, err := th.App.GetChannelByName(channelName, team.Id) channel, err := th.App.GetChannelByName(channelName, team.Id, false)
if err != nil { if err != nil {
t.Fatalf("Failed to get channel from database.") 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 { if err := th.App.ImportChannel(channelData, false); err != nil {
t.Fatalf("Import should have succeeded.") 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 { if err != nil {
t.Fatalf("Failed to get channel from database: %v", err.Error()) t.Fatalf("Failed to get channel from database: %v", err.Error())
} }
@@ -2755,7 +2755,7 @@ func TestImportImportPost(t *testing.T) {
DisplayName: ptrStr("Display Name"), DisplayName: ptrStr("Display Name"),
Type: ptrStr("O"), Type: ptrStr("O"),
}, false) }, false)
channel, err := th.App.GetChannelByName(channelName, team.Id) channel, err := th.App.GetChannelByName(channelName, team.Id, false)
if err != nil { if err != nil {
t.Fatalf("Failed to get channel from database.") t.Fatalf("Failed to get channel from database.")
} }
@@ -3959,7 +3959,7 @@ func TestImportPostAndRepliesWithAttachments(t *testing.T) {
DisplayName: ptrStr("Display Name"), DisplayName: ptrStr("Display Name"),
Type: ptrStr("O"), Type: ptrStr("O"),
}, false) }, false)
_, err = th.App.GetChannelByName(channelName, team.Id) _, err = th.App.GetChannelByName(channelName, team.Id, false)
if err != nil { if err != nil {
t.Fatalf("Failed to get channel from database.") t.Fatalf("Failed to get channel from database.")
} }

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

@@ -195,12 +195,12 @@ func (api *PluginAPI) GetChannel(channelId string) (*model.Channel, *model.AppEr
return api.app.GetChannel(channelId) return api.app.GetChannel(channelId)
} }
func (api *PluginAPI) GetChannelByName(teamId, name string) (*model.Channel, *model.AppError) { func (api *PluginAPI) GetChannelByName(teamId, name string, includeDeleted bool) (*model.Channel, *model.AppError) {
return api.app.GetChannelByName(name, teamId) return api.app.GetChannelByName(name, teamId, includeDeleted)
} }
func (api *PluginAPI) GetChannelByNameForTeamName(teamName, channelName string) (*model.Channel, *model.AppError) { func (api *PluginAPI) GetChannelByNameForTeamName(teamName, channelName string, includeDeleted bool) (*model.Channel, *model.AppError) {
return api.app.GetChannelByNameForTeamName(channelName, teamName) return api.app.GetChannelByNameForTeamName(channelName, teamName, includeDeleted)
} }
func (api *PluginAPI) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) { func (api *PluginAPI) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) {

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

@@ -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) paramsList := model.ParseSearchParams(terms)
includeDeleted := includeDeletedChannels && *a.Config().TeamSettings.ViewArchivedChannels
esInterface := a.Elasticsearch esInterface := a.Elasticsearch
if license := a.License(); esInterface != nil && *a.Config().ElasticsearchSettings.EnableSearching && license != nil && *license.Features.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 != "*" { if params.Terms != "*" {
// Convert channel names to channel IDs // Convert channel names to channel IDs
for idx, channelName := range params.InChannels { 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)) mlog.Error(fmt.Sprint(err))
} else { } else {
params.InChannels[idx] = channel.Id 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. // 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 { if err != nil {
mlog.Error(fmt.Sprint(err)) mlog.Error(fmt.Sprint(err))
return nil, err return nil, err
@@ -710,6 +711,7 @@ func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOr
channels := []store.StoreChannel{} channels := []store.StoreChannel{}
for _, params := range paramsList { for _, params := range paramsList {
params.IncludeDeletedChannels = includeDeleted
params.OrTerms = isOrSearch params.OrTerms = isOrSearch
// don't allow users to search for everything // don't allow users to search for everything
if params.Terms != "*" { if params.Terms != "*" {

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

@@ -715,7 +715,7 @@ func (a *App) LeaveTeam(team *model.Team, user *model.User, requestorId string)
var channelList *model.ChannelList 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" { if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" {
channelList = &model.ChannelList{} channelList = &model.ChannelList{}
} else { } else {

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

@@ -901,7 +901,7 @@ func (a *App) UpdateActive(user *model.User, active bool) (*model.User, *model.A
} }
for _, team := range teamsForUser { for _, team := range teamsForUser {
channelsForUser, err := a.GetChannelsForUser(team.Id, user.Id) channelsForUser, err := a.GetChannelsForUser(team.Id, user.Id, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }

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

@@ -334,7 +334,7 @@ func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool {
} }
if webCon.AllChannelMembers == nil { 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()) mlog.Error("webhub.shouldSendEvent: " + result.Err.Error())
return false return false
} else { } else {

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

@@ -101,6 +101,7 @@
"MaxNotificationsPerChannel": 1000, "MaxNotificationsPerChannel": 1000,
"EnableConfirmNotificationsToChannel": true, "EnableConfirmNotificationsToChannel": true,
"TeammateNameDisplay": "username", "TeammateNameDisplay": "username",
"ViewArchivedChannels": true,
"ExperimentalEnableAutomaticReplies": false, "ExperimentalEnableAutomaticReplies": false,
"ExperimentalHideTownSquareinLHS": false, "ExperimentalHideTownSquareinLHS": false,
"ExperimentalTownSquareIsReadOnly": false, "ExperimentalTownSquareIsReadOnly": false,

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

@@ -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) { func getChannelID(a *app.App, channelname string, teamid string, userid string) (id string, err bool) {
// Grab all the channels // 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 { if result.Err != nil {
mlog.Debug("Unable to get channels") mlog.Debug("Unable to get channels")
return "", false return "", false

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

@@ -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. // 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) { func (c *Client4) GetChannelByNameForTeamName(channelName, teamName string, etag string) (*Channel, *Response) {
if r, err := c.DoApiGet(c.GetChannelByNameForTeamNameRoute(channelName, teamName), etag); err != nil { 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. // GetChannelMembers gets a page of channel members.
func (c *Client4) GetChannelMembers(channelId string, page, perPage int, etag string) (*ChannelMembers, *Response) { func (c *Client4) GetChannelMembers(channelId string, page, perPage int, etag string) (*ChannelMembers, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 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 . // SearchPosts returns any posts with matching terms string, including .
func (c *Client4) SearchPostsWithMatches(teamId string, terms string, isOrSearch bool) (*PostSearchResults, *Response) { func (c *Client4) SearchPostsWithMatches(teamId string, terms string, isOrSearch bool) (*PostSearchResults, *Response) {
requestBody := map[string]interface{}{"terms": terms, "is_or_search": isOrSearch} requestBody := map[string]interface{}{"terms": terms, "is_or_search": isOrSearch}

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

@@ -1125,6 +1125,7 @@ type TeamSettings struct {
MaxNotificationsPerChannel *int64 MaxNotificationsPerChannel *int64
EnableConfirmNotificationsToChannel *bool EnableConfirmNotificationsToChannel *bool
TeammateNameDisplay *string TeammateNameDisplay *string
ViewArchivedChannels *bool
ExperimentalEnableAutomaticReplies *bool ExperimentalEnableAutomaticReplies *bool
ExperimentalHideTownSquareinLHS *bool ExperimentalHideTownSquareinLHS *bool
ExperimentalTownSquareIsReadOnly *bool ExperimentalTownSquareIsReadOnly *bool
@@ -1254,6 +1255,9 @@ func (s *TeamSettings) SetDefaults() {
s.EnableUserCreation = NewBool(true) s.EnableUserCreation = NewBool(true)
} }
if s.ViewArchivedChannels == nil {
s.ViewArchivedChannels = NewBool(true)
}
} }
type ClientRequirements struct { type ClientRequirements struct {

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

@@ -17,6 +17,7 @@ type SearchParams struct {
InChannels []string InChannels []string
FromUsers []string FromUsers []string
OrTerms bool OrTerms bool
IncludeDeletedChannels bool
} }
var searchFlags = [...]string{"from", "channel", "in"} var searchFlags = [...]string{"from", "channel", "in"}

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

@@ -108,10 +108,10 @@ type API interface {
GetChannel(channelId string) (*model.Channel, *model.AppError) GetChannel(channelId string) (*model.Channel, *model.AppError)
// GetChannelByName gets a channel by its name, given a team id. // 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 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 gets a direct message channel.
GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError)

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

@@ -1349,6 +1349,7 @@ func (s *apiRPCServer) GetChannel(args *Z_GetChannelArgs, returns *Z_GetChannelR
type Z_GetChannelByNameArgs struct { type Z_GetChannelByNameArgs struct {
A string A string
B string B string
C bool
} }
type Z_GetChannelByNameReturns struct { type Z_GetChannelByNameReturns struct {
@@ -1356,8 +1357,8 @@ type Z_GetChannelByNameReturns struct {
B *model.AppError B *model.AppError
} }
func (g *apiRPCClient) GetChannelByName(teamId, name string) (*model.Channel, *model.AppError) { func (g *apiRPCClient) GetChannelByName(teamId, name string, includeDeleted bool) (*model.Channel, *model.AppError) {
_args := &Z_GetChannelByNameArgs{teamId, name} _args := &Z_GetChannelByNameArgs{teamId, name, includeDeleted}
_returns := &Z_GetChannelByNameReturns{} _returns := &Z_GetChannelByNameReturns{}
if err := g.client.Call("Plugin.GetChannelByName", _args, _returns); err != nil { if err := g.client.Call("Plugin.GetChannelByName", _args, _returns); err != nil {
log.Printf("RPC call to GetChannelByName API failed: %s", err.Error()) 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 { func (s *apiRPCServer) GetChannelByName(args *Z_GetChannelByNameArgs, returns *Z_GetChannelByNameReturns) error {
if hook, ok := s.impl.(interface { 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 { }); ok {
returns.A, returns.B = hook.GetChannelByName(args.A, args.B) returns.A, returns.B = hook.GetChannelByName(args.A, args.B, args.C)
} else { } else {
return fmt.Errorf("API GetChannelByName called but not implemented.") 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 { type Z_GetChannelByNameForTeamNameArgs struct {
A string A string
B string B string
C bool
} }
type Z_GetChannelByNameForTeamNameReturns struct { type Z_GetChannelByNameForTeamNameReturns struct {
@@ -1386,8 +1388,8 @@ type Z_GetChannelByNameForTeamNameReturns struct {
B *model.AppError B *model.AppError
} }
func (g *apiRPCClient) GetChannelByNameForTeamName(teamName, channelName string) (*model.Channel, *model.AppError) { func (g *apiRPCClient) GetChannelByNameForTeamName(teamName, channelName string, includeDeleted bool) (*model.Channel, *model.AppError) {
_args := &Z_GetChannelByNameForTeamNameArgs{teamName, channelName} _args := &Z_GetChannelByNameForTeamNameArgs{teamName, channelName, includeDeleted}
_returns := &Z_GetChannelByNameForTeamNameReturns{} _returns := &Z_GetChannelByNameForTeamNameReturns{}
if err := g.client.Call("Plugin.GetChannelByNameForTeamName", _args, _returns); err != nil { if err := g.client.Call("Plugin.GetChannelByNameForTeamName", _args, _returns); err != nil {
log.Printf("RPC call to GetChannelByNameForTeamName API failed: %s", err.Error()) 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 { func (s *apiRPCServer) GetChannelByNameForTeamName(args *Z_GetChannelByNameForTeamNameArgs, returns *Z_GetChannelByNameForTeamNameReturns) error {
if hook, ok := s.impl.(interface { 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 { }); ok {
returns.A, returns.B = hook.GetChannelByNameForTeamName(args.A, args.B) returns.A, returns.B = hook.GetChannelByNameForTeamName(args.A, args.B, args.C)
} else { } else {
return fmt.Errorf("API GetChannelByNameForTeamName called but not implemented.") return fmt.Errorf("API GetChannelByNameForTeamName called but not implemented.")
} }

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

@@ -30,7 +30,7 @@ func (p *HelpPlugin) OnConfigurationChange() error {
return nil return nil
} }
channel, err := p.API.GetChannelByName(p.ChannelName, team.Id) channel, err := p.API.GetChannelByName(p.ChannelName, team.Id, false)
if err != nil { if err != nil {
p.API.LogError("failed to find channel", "channel_name", p.ChannelName) p.API.LogError("failed to find channel", "channel_name", p.ChannelName)
return nil return nil

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

@@ -308,13 +308,13 @@ func (_m *API) GetChannel(channelId string) (*model.Channel, *model.AppError) {
return r0, r1 return r0, r1
} }
// GetChannelByName provides a mock function with given fields: teamId, name // GetChannelByName provides a mock function with given fields: teamId, name, includeDeleted
func (_m *API) GetChannelByName(teamId string, name string) (*model.Channel, *model.AppError) { func (_m *API) GetChannelByName(teamId string, name string, includeDeleted bool) (*model.Channel, *model.AppError) {
ret := _m.Called(teamId, name) ret := _m.Called(teamId, name, includeDeleted)
var r0 *model.Channel var r0 *model.Channel
if rf, ok := ret.Get(0).(func(string, string) *model.Channel); ok { if rf, ok := ret.Get(0).(func(string, string, bool) *model.Channel); ok {
r0 = rf(teamId, name) r0 = rf(teamId, name, includeDeleted)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.Channel) 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 var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string, string) *model.AppError); ok { if rf, ok := ret.Get(1).(func(string, string, bool) *model.AppError); ok {
r1 = rf(teamId, name) r1 = rf(teamId, name, includeDeleted)
} else { } else {
if ret.Get(1) != nil { if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError) r1 = ret.Get(1).(*model.AppError)
@@ -333,13 +333,13 @@ func (_m *API) GetChannelByName(teamId string, name string) (*model.Channel, *mo
return r0, r1 return r0, r1
} }
// GetChannelByNameForTeamName provides a mock function with given fields: teamName, channelName // GetChannelByNameForTeamName provides a mock function with given fields: teamName, channelName, includeDeleted
func (_m *API) GetChannelByNameForTeamName(teamName string, channelName string) (*model.Channel, *model.AppError) { func (_m *API) GetChannelByNameForTeamName(teamName string, channelName string, includeDeleted bool) (*model.Channel, *model.AppError) {
ret := _m.Called(teamName, channelName) ret := _m.Called(teamName, channelName, includeDeleted)
var r0 *model.Channel var r0 *model.Channel
if rf, ok := ret.Get(0).(func(string, string) *model.Channel); ok { if rf, ok := ret.Get(0).(func(string, string, bool) *model.Channel); ok {
r0 = rf(teamName, channelName) r0 = rf(teamName, channelName, includeDeleted)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.Channel) r0 = ret.Get(0).(*model.Channel)
@@ -347,8 +347,8 @@ func (_m *API) GetChannelByNameForTeamName(teamName string, channelName string)
} }
var r1 *model.AppError var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string, string) *model.AppError); ok { if rf, ok := ret.Get(1).(func(string, string, bool) *model.AppError); ok {
r1 = rf(teamName, channelName) r1 = rf(teamName, channelName, includeDeleted)
} else { } else {
if ret.Get(1) != nil { if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError) r1 = ret.Get(1).(*model.AppError)

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

@@ -303,6 +303,11 @@ func (s SqlChannelStore) CreateIndexesIfNotExists() {
func (s SqlChannelStore) Save(channel *model.Channel, maxChannelsPerTeam int64) store.StoreChannel { func (s SqlChannelStore) Save(channel *model.Channel, maxChannelsPerTeam int64) store.StoreChannel {
return store.Do(func(result *store.StoreResult) { 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 { if channel.Type == model.CHANNEL_DIRECT {
result.Err = model.NewAppError("SqlChannelStore.Save", "store.sql_channel.save.direct_channel.app_error", nil, "", http.StatusBadRequest) result.Err = model.NewAppError("SqlChannelStore.Save", "store.sql_channel.save.direct_channel.app_error", nil, "", http.StatusBadRequest)
return 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 { func (s SqlChannelStore) SaveDirectChannel(directchannel *model.Channel, member1 *model.ChannelMember, member2 *model.ChannelMember) store.StoreChannel {
return store.Do(func(result *store.StoreResult) { 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 { 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) result.Err = model.NewAppError("SqlChannelStore.SaveDirectChannel", "store.sql_channel.save_direct_channel.not_direct.app_error", nil, "", http.StatusBadRequest)
return 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) { 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{} 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 { 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) 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") s.metrics.IncrementMemCacheMissCounter("All Channel Members for User")
} }
result := <-s.GetAllChannelMembersForUser(userId, true) result := <-s.GetAllChannelMembersForUser(userId, true, false)
if result.Err != nil { if result.Err != nil {
mlog.Error("SqlChannelStore.IsUserInChannelUseCache: " + result.Err.Error()) mlog.Error("SqlChannelStore.IsUserInChannelUseCache: " + result.Err.Error())
return false 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) { return store.Do(func(result *store.StoreResult) {
if allowFromCache { if allowFromCache {
if cacheItem, ok := allChannelMembersForUserCache.Get(userId); ok { 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") s.metrics.IncrementMemCacheMissCounter("All Channel Members for User")
} }
var deletedClause string
if !includeDeleted {
deletedClause = "Channels.DeleteAt = 0 AND"
}
var data allChannelMembers var data allChannelMembers
_, err := s.GetReplica().Select(&data, ` _, err := s.GetReplica().Select(&data, `
SELECT SELECT
@@ -1182,8 +1201,8 @@ func (s SqlChannelStore) GetAllChannelMembersForUser(userId string, allowFromCac
LEFT JOIN LEFT JOIN
Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id
WHERE WHERE
Channels.DeleteAt = 0 `+deletedClause+`
AND ChannelMembers.UserId = :UserId`, map[string]interface{}{"UserId": userId}) ChannelMembers.UserId = :UserId`, map[string]interface{}{"UserId": userId})
if err != nil { 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) 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) { return store.Do(func(result *store.StoreResult) {
deleteFilter := "AND DeleteAt = 0"
if includeDeleted {
deleteFilter = ""
}
queryFormat := ` queryFormat := `
SELECT SELECT
* *
@@ -1525,7 +1549,7 @@ func (s SqlChannelStore) AutocompleteInTeam(teamId string, term string) store.St
WHERE WHERE
TeamId = :TeamId TeamId = :TeamId
AND Type = 'O' AND Type = 'O'
AND DeleteAt = 0 ` + deleteFilter + `
%v %v
LIMIT 50` 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) { return store.Do(func(result *store.StoreResult) {
deleteFilter := "AND DeleteAt = 0"
if includeDeleted {
deleteFilter = ""
}
searchQuery := ` searchQuery := `
SELECT SELECT
* *
@@ -1565,7 +1593,7 @@ func (s SqlChannelStore) SearchInTeam(teamId string, term string) store.StoreCha
WHERE WHERE
TeamId = :TeamId TeamId = :TeamId
AND Type = 'O' AND Type = 'O'
AND DeleteAt = 0 ` + deleteFilter + `
SEARCH_CLAUSE SEARCH_CLAUSE
ORDER BY DisplayName ORDER BY DisplayName
LIMIT 100` LIMIT 100`

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

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

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

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

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

@@ -493,7 +493,7 @@ func testChannelStoreDelete(t *testing.T, ss store.Store) {
t.Fatal(r.Err) 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) list := cresult.Data.(*model.ChannelList)
if len(*list) != 1 { if len(*list) != 1 {
@@ -509,7 +509,7 @@ func testChannelStoreDelete(t *testing.T, ss store.Store) {
<-ss.Channel().PermanentDelete(o2.Id) <-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) t.Log(cresult.Err)
if cresult.Err.Id != "store.sql_channel.get_channels.not_found.app_error" { if cresult.Err.Id != "store.sql_channel.get_channels.not_found.app_error" {
t.Fatal("no channels should be found") 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())) 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()") 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.DisplayName = "Name"
o1.Name = "zz" + model.NewId() + "b" o1.Name = "zz" + model.NewId() + "b"
o1.Type = model.CHANNEL_OPEN o1.Type = model.CHANNEL_OPEN
o1.DeleteAt = model.GetMillis()
store.Must(ss.Channel().Save(&o1, -1)) 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 { if r1 := <-ss.Channel().GetDeletedByName(o1.TeamId, o1.Name); r1.Err != nil {
t.Fatal(r1.Err) t.Fatal(r1.Err)
@@ -639,8 +642,8 @@ func testChannelStoreGetDeleted(t *testing.T, ss store.Store) {
o1.DisplayName = "Channel1" o1.DisplayName = "Channel1"
o1.Name = "zz" + model.NewId() + "b" o1.Name = "zz" + model.NewId() + "b"
o1.Type = model.CHANNEL_OPEN o1.Type = model.CHANNEL_OPEN
o1.DeleteAt = model.GetMillis()
store.Must(ss.Channel().Save(&o1, -1)) store.Must(ss.Channel().Save(&o1, -1))
store.Must(ss.Channel().Delete(o1.Id, model.GetMillis()))
cresult := <-ss.Channel().GetDeleted(o1.TeamId, 0, 100) cresult := <-ss.Channel().GetDeleted(o1.TeamId, 0, 100)
if cresult.Err != nil { if cresult.Err != nil {
@@ -678,8 +681,8 @@ func testChannelStoreGetDeleted(t *testing.T, ss store.Store) {
o3.DisplayName = "Channel3" o3.DisplayName = "Channel3"
o3.Name = "zz" + model.NewId() + "b" o3.Name = "zz" + model.NewId() + "b"
o3.Type = model.CHANNEL_OPEN o3.Type = model.CHANNEL_OPEN
o3.DeleteAt = model.GetMillis()
store.Must(ss.Channel().Save(&o3, -1)) 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) cresult = <-ss.Channel().GetDeleted(o1.TeamId, 0, 100)
if cresult.Err != nil { if cresult.Err != nil {
@@ -890,26 +893,26 @@ func testChannelStoreGetChannels(t *testing.T, ss store.Store) {
m3.NotifyProps = model.GetDefaultChannelNotifyProps() m3.NotifyProps = model.GetDefaultChannelNotifyProps()
store.Must(ss.Channel().SaveMember(&m3)) 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) list := cresult.Data.(*model.ChannelList)
if (*list)[0].Id != o1.Id { if (*list)[0].Id != o1.Id {
t.Fatal("missing channel") 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) ids := acresult.Data.(map[string]string)
if _, ok := ids[o1.Id]; !ok { if _, ok := ids[o1.Id]; !ok {
t.Fatal("missing channel") 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) ids2 := acresult2.Data.(map[string]string)
if _, ok := ids2[o1.Id]; !ok { if _, ok := ids2[o1.Id]; !ok {
t.Fatal("missing channel") 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) ids3 := acresult3.Data.(map[string]string)
if _, ok := ids3[o1.Id]; !ok { if _, ok := ids3[o1.Id]; !ok {
t.Fatal("missing channel") t.Fatal("missing channel")
@@ -1913,12 +1916,12 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
o12.Type = model.CHANNEL_OPEN o12.Type = model.CHANNEL_OPEN
store.Must(ss.Channel().Save(&o12, -1)) 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, "AutocompleteInTeam": ss.Channel().AutocompleteInTeam,
"SearchInTeam": ss.Channel().SearchInTeam, "SearchInTeam": ss.Channel().SearchInTeam,
} { } {
t.Run(name, func(t *testing.T) { 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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) t.Fatal(result.Err)
} else { } else {
channels := result.Data.(*model.ChannelList) 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 // 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) ret := _m.Called(teamId, term)
var r0 store.StoreChannel var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string, string, bool) store.StoreChannel); ok {
r0 = rf(teamId, term) r0 = rf(teamId, term, includeDeleted)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) 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 // 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) ret := _m.Called(userId, allowFromCache)
var r0 store.StoreChannel var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, bool) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string, bool, bool) store.StoreChannel); ok {
r0 = rf(userId, allowFromCache) r0 = rf(userId, allowFromCache, includeDeleted)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) 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 // 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) ret := _m.Called(teamId, userId)
var r0 store.StoreChannel var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string, string, bool) store.StoreChannel); ok {
r0 = rf(teamId, userId) r0 = rf(teamId, userId, includeDeleted)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) 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 // 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) ret := _m.Called(teamId, term)
var r0 store.StoreChannel var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string, string, bool) store.StoreChannel); ok {
r0 = rf(teamId, term) r0 = rf(teamId, term, includeDeleted)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).(store.StoreChannel)

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

@@ -13,6 +13,7 @@ import (
"github.com/mattermost/mattermost-server/store" "github.com/mattermost/mattermost-server/store"
"github.com/mattermost/mattermost-server/utils" "github.com/mattermost/mattermost-server/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func TestPostStore(t *testing.T, ss store.Store) { 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.Type = model.CHANNEL_OPEN
c2 = (<-ss.Channel().Save(c2, -1)).Data.(*model.Channel) 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 := &model.Post{}
o1.ChannelId = c1.Id o1.ChannelId = c1.Id
o1.UserId = model.NewId() o1.UserId = model.NewId()
@@ -877,69 +892,129 @@ func testPostStoreSearch(t *testing.T, ss store.Store) {
o5.Hashtags = "#secret #howdy" o5.Hashtags = "#secret #howdy"
o5 = (<-ss.Post().Save(o5)).Data.(*model.Post) o5 = (<-ss.Post().Save(o5)).Data.(*model.Post)
r1 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "corey", IsHashtag: false})).Data.(*model.PostList) o6 := &model.Post{}
if len(r1.Order) != 1 || r1.Order[0] != o1.Id { o6.ChannelId = c3.Id
t.Fatal("returned wrong search result") 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) o7 := &model.Post{}
if len(r3.Order) != 2 || (r3.Order[0] != o1.Id && r3.Order[1] != o1.Id) { o7.ChannelId = c3.Id
t.Fatal("returned wrong search result") 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) o8 := &model.Post{}
if len(r4.Order) != 1 || r4.Order[0] != o2.Id { o8.ChannelId = c3.Id
t.Fatal("returned wrong search result") 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) tt := []struct {
if len(r5.Order) != 1 || r5.Order[0] != o1.Id { name string
t.Fatal("returned wrong search result") 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},
},
} }
for _, tc := range tt {
r6 := (<-ss.Post().Search(teamId, userId, &model.SearchParams{Terms: "#hashtag", IsHashtag: true})).Data.(*model.PostList) t.Run(tc.name, func(t *testing.T) {
if len(r6.Order) != 1 || r6.Order[0] != o4.Id { result := (<-ss.Post().Search(teamId, userId, tc.searchParams)).Data.(*model.PostList)
t.Fatal("returned wrong search result") require.Len(t, result.Order, tc.extectedResultsCount)
for _, expectedMessageResultId := range tc.expectedMessageResultIds {
assert.Contains(t, result.Order, expectedMessageResultId)
} }
})
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")
} }
} }

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

@@ -512,6 +512,7 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
props["EnableXToLeaveChannelsFromLHS"] = strconv.FormatBool(*c.TeamSettings.EnableXToLeaveChannelsFromLHS) props["EnableXToLeaveChannelsFromLHS"] = strconv.FormatBool(*c.TeamSettings.EnableXToLeaveChannelsFromLHS)
props["TeammateNameDisplay"] = *c.TeamSettings.TeammateNameDisplay props["TeammateNameDisplay"] = *c.TeamSettings.TeammateNameDisplay
props["ExperimentalPrimaryTeam"] = *c.TeamSettings.ExperimentalPrimaryTeam props["ExperimentalPrimaryTeam"] = *c.TeamSettings.ExperimentalPrimaryTeam
props["ViewArchivedChannels"] = strconv.FormatBool(*c.TeamSettings.ViewArchivedChannels)
props["EnableOAuthServiceProvider"] = strconv.FormatBool(c.ServiceSettings.EnableOAuthServiceProvider) props["EnableOAuthServiceProvider"] = strconv.FormatBool(c.ServiceSettings.EnableOAuthServiceProvider)
props["GoogleDeveloperKey"] = c.ServiceSettings.GoogleDeveloperKey props["GoogleDeveloperKey"] = c.ServiceSettings.GoogleDeveloperKey