Fix cross-team search from: filter not working (#31277)

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Julien Tant
2025-06-05 11:53:35 -07:00
committed by GitHub
co-authored by Claude Mattermost Build
parent 924ed4ae02
commit 7e013f4c1a
2 changed files with 71 additions and 5 deletions
@@ -280,6 +280,11 @@ var searchPostStoreTests = []searchTest{
Fn: testSearchAcrossTeams,
Tags: []string{EngineAll},
},
{
Name: "Should search across teams with from filter",
Fn: testSearchAcrossTeamsWithFromFilter,
Tags: []string{EngineAll},
},
{
Name: "Should be removed from search index when deleted",
Fn: testSearchPostDeleted,
@@ -2025,6 +2030,60 @@ func testSearchAcrossTeams(t *testing.T, th *SearchTestHelper) {
require.Len(t, results.Posts, 2)
}
func testSearchAcrossTeamsWithFromFilter(t *testing.T, th *SearchTestHelper) {
err := th.addUserToChannels(th.User, []string{th.ChannelAnotherTeam.Id})
require.NoError(t, err)
defer th.Store.Channel().RemoveMember(th.Context, th.ChannelAnotherTeam.Id, th.User.Id)
err = th.addUserToChannels(th.User2, []string{th.ChannelAnotherTeam.Id})
require.NoError(t, err)
defer th.Store.Channel().RemoveMember(th.Context, th.ChannelAnotherTeam.Id, th.User2.Id)
// Create posts from different users in different teams
p1, err := th.createPost(th.User.Id, th.ChannelAnotherTeam.Id, "cross team search test", "", model.PostTypeDefault, 0, false)
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
_, err = th.createPost(th.User2.Id, th.ChannelAnotherTeam.Id, "cross team search test", "", model.PostTypeDefault, 0, false)
require.NoError(t, err)
defer th.deleteUserPosts(th.User2.Id)
p3, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "cross team search test", "", model.PostTypeDefault, 0, false)
require.NoError(t, err)
_, err = th.createPost(th.User2.Id, th.ChannelBasic.Id, "cross team search test", "", model.PostTypeDefault, 0, false)
require.NoError(t, err)
t.Run("Cross-team search with from filter should work", func(t *testing.T) {
// Cross-team search with from filter (empty teamId)
params := &model.SearchParams{
Terms: "search test",
FromUsers: []string{th.User.Id},
}
results, err := th.Store.Post().SearchPostsForUser(th.Context, []*model.SearchParams{params}, th.User.Id, "", 0, 20)
require.NoError(t, err)
// Should find both posts from th.User across teams
require.Len(t, results.Posts, 2)
th.checkPostInSearchResults(t, p1.Id, results.Posts)
th.checkPostInSearchResults(t, p3.Id, results.Posts)
})
t.Run("Team-scoped search with from filter should still work", func(t *testing.T) {
// Team-scoped search with from filter (specific teamId)
params := &model.SearchParams{
Terms: "search test",
FromUsers: []string{th.User.Id},
}
results, err := th.Store.Post().SearchPostsForUser(th.Context, []*model.SearchParams{params}, th.User.Id, th.Team.Id, 0, 20)
require.NoError(t, err)
// Should find only the post from th.User in th.Team
require.Len(t, results.Posts, 1)
th.checkPostInSearchResults(t, p3.Id, results.Posts)
})
}
func testSearchPostDeleted(t *testing.T, th *SearchTestHelper) {
t.Run("Search for soft deleted post", func(t *testing.T) {
p1, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "message to delete", "", model.PostTypeDefault, 0, false)
+12 -5
View File
@@ -2079,11 +2079,18 @@ func (s *SqlPostStore) buildSearchPostFilterClause(teamID string, fromUsers []st
}
// Sub-query builder.
sb := s.getSubQueryBuilder().Select("Id").From("Users, TeamMembers").Where(
sq.And{
sq.Eq{"TeamMembers.TeamId": teamID},
sq.Expr("Users.Id = TeamMembers.UserId"),
})
sb := s.getSubQueryBuilder().Select("Id")
if teamID == "" {
// Cross-team search: don't filter by team membership
sb = sb.From("Users")
} else {
// Team-scoped search: filter by team membership
sb = sb.From("Users, TeamMembers").Where(
sq.And{
sq.Eq{"TeamMembers.TeamId": teamID},
sq.Expr("Users.Id = TeamMembers.UserId"),
})
}
sb = s.buildSearchUserFilterClause(fromUsers, false, userByUsername, sb)
sb = s.buildSearchUserFilterClause(excludedUsers, true, userByUsername, sb)
subQuery, subQueryArgs, err := sb.ToSql()