[MM-51201/MM-60406/MM-60404] CrossTeam Search posts and files (#28478)

* poc - wip

* add search files across teams

* eslint

* fix existing tests

* fix webapp style

* fix test

* add api doc

* change initial state in test

* add tests on API

* add tests on file info layer

* fix file search tags

* add rhs reducer test

* reset team selected when the RHS is suppressed

* change css to reflect UI

* fix style

* fix doc wording

* make getSearchTeam return currentTeamId when value is not set

* await is unnecessary

* revert boolean check and add test

* add comment to getSearchTeam to let dev knows it defaults to currentTeam

* remove redundant team check

* simplfy test

* fix style check

---------

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Julien Tant
2024-11-21 13:40:46 -07:00
коммит произвёл GitHub
родитель f0280d6dd4
Коммит 3b1eb64e02
25 изменённых файлов: 573 добавлений и 150 удалений

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

@@ -39,7 +39,8 @@ func (api *API) InitFile() {
api.BaseRoutes.File.Handle("/preview", api.APISessionRequiredTrustRequester(getFilePreview)).Methods(http.MethodGet)
api.BaseRoutes.File.Handle("/info", api.APISessionRequired(getFileInfo)).Methods(http.MethodGet)
api.BaseRoutes.Team.Handle("/files/search", api.APISessionRequiredDisableWhenBusy(searchFiles)).Methods(http.MethodPost)
api.BaseRoutes.Team.Handle("/files/search", api.APISessionRequiredDisableWhenBusy(searchFilesInTeam)).Methods(http.MethodPost)
api.BaseRoutes.Files.Handle("/search", api.APISessionRequiredDisableWhenBusy(searchFilesInAllTeams)).Methods(http.MethodPost)
api.BaseRoutes.PublicFile.Handle("", api.APIHandler(getPublicFile)).Methods(http.MethodGet, http.MethodHead)
}
@@ -736,7 +737,7 @@ func getPublicFile(c *Context, w http.ResponseWriter, r *http.Request) {
web.WriteFileResponse(info.Name, info.MimeType, info.Size, time.Unix(0, info.UpdateAt*int64(1000*1000)), *c.App.Config().ServiceSettings.WebserverMode, fileReader, false, w, r)
}
func searchFiles(c *Context, w http.ResponseWriter, r *http.Request) {
func searchFilesInTeam(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireTeamId()
if c.Err != nil {
return
@@ -747,6 +748,14 @@ func searchFiles(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
searchFiles(c, w, r, c.Params.TeamId)
}
func searchFilesInAllTeams(c *Context, w http.ResponseWriter, r *http.Request) {
searchFiles(c, w, r, "")
}
func searchFiles(c *Context, w http.ResponseWriter, r *http.Request, teamID string) {
var params model.SearchParameter
jsonErr := json.NewDecoder(r.Body).Decode(&params)
if jsonErr != nil {
@@ -787,7 +796,7 @@ func searchFiles(c *Context, w http.ResponseWriter, r *http.Request) {
startTime := time.Now()
results, err := c.App.SearchFilesInTeamForUser(c.AppContext, terms, c.AppContext.Session().UserId, c.Params.TeamId, isOrSearch, includeDeletedChannels, timeZoneOffset, page, perPage)
results, err := c.App.SearchFilesInTeamForUser(c.AppContext, terms, c.AppContext.Session().UserId, teamID, isOrSearch, includeDeletedChannels, timeZoneOffset, page, perPage)
elapsedTime := float64(time.Since(startTime)) / float64(time.Second)
metrics := c.App.Metrics()

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

@@ -1169,7 +1169,7 @@ func TestGetPublicFile(t *testing.T) {
require.Equal(t, http.StatusNotFound, resp.StatusCode, "should've failed to get file after it is deleted")
}
func TestSearchFiles(t *testing.T) {
func TestSearchFilesInTeam(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
experimentalViewArchivedChannels := *th.App.Config().TeamSettings.ExperimentalViewArchivedChannels
@@ -1318,3 +1318,61 @@ func TestSearchFiles(t *testing.T) {
require.Error(t, err)
CheckUnauthorizedStatus(t, resp)
}
func TestSearchFilesAcrossTeams(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
experimentalViewArchivedChannels := *th.App.Config().TeamSettings.ExperimentalViewArchivedChannels
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) {
cfg.TeamSettings.ExperimentalViewArchivedChannels = &experimentalViewArchivedChannels
})
}()
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.ExperimentalViewArchivedChannels = true
})
data, err := testutils.ReadTestFile("test.png")
require.NoError(t, err)
th.LoginBasic()
client := th.Client
var teams [2]*model.Team
var channels [2]*model.Channel
for i := 0; i < 2; i++ {
teams[i] = th.CreateTeam()
channels[i] = th.CreateChannelWithClientAndTeam(th.Client, model.ChannelTypeOpen, teams[i].Id)
th.LinkUserToTeam(th.BasicUser, teams[i])
th.AddUserToChannel(th.BasicUser, channels[i])
filename := "search for fileInfo"
fileInfo, appErr := th.App.UploadFile(th.Context, data, th.BasicChannel.Id, filename)
require.Nil(t, appErr)
th.CreatePostInChannelWithFiles(channels[i], fileInfo)
}
terms := "search"
// BasicUser should have access to all the files
fileInfos, _, err := client.SearchFilesAcrossTeams(context.Background(), terms, false)
require.NoError(t, err)
require.Len(t, fileInfos.Order, 2, "wrong search")
// a new user that only belongs to the first team should only get one result
newUser := th.CreateUser()
th.LinkUserToTeam(newUser, teams[0])
th.AddUserToChannel(newUser, channels[0])
th.UnlinkUserFromTeam(th.BasicUser, teams[1])
_, err = th.Client.Logout(context.Background())
require.NoError(t, err)
_, _, err = th.Client.Login(context.Background(), newUser.Email, newUser.Password)
require.NoError(t, err)
fileInfos, _, err = client.SearchFilesAcrossTeams(context.Background(), terms, false)
require.NoError(t, err)
require.Len(t, fileInfos.Order, 1, "wrong search")
require.Equal(t, fileInfos.FileInfos[fileInfos.Order[0]].ChannelId, channels[0].Id, "wrong search")
}