* Migrate feature/wrangler to mono-repo

* Add wrangler files

* Fix linters, types, etc

* Fix snapshots

* Fix playwright

* Fix pipelines

* Fix more pipeline

* Fixes for pipelines

* More changes for pipeline

* Fix types

* Add support for a feature flag, but leave it defaulted on for spinwick usage for now

* Update snapshot

* fix js error when removing last value of multiselect, support CSV marshaling to string array for textsetting

* Fix linter

* Remove TODO

* Remove another TODO

* fix tests

* Fix i18n

* Add server tests

* Fix linter

* Fix linter

* Use proper icon for dot menu

* Update snapshot

* Add Cypress UI tests for various entrypoints to move thread modal, split SCSS out from forward post into its own thing

* clean up

* fix linter

* More cleanup

* Revert files to master

* Fix linter for e2e tests

* Make ForwardPostChannelSelect channel types configurable with a prop

* Add missing return

* Fixes from PR feedback

* First batch of PR Feedback

* Another batch of PR changes

* Fix linter

* Update snapshots

* Wrangler system messages are translated to each user's locale

* Initially translate Wrangler into system locale rather than initiating user

* More fixes for PR Feedback

* Fix some server tests

* More updates with master. Fixes around pipelines. Enforce Enterprise license on front/back end

* Add tests for dot_menu

* More pipeline fixes

* Fix e2etests prettier

* Update cypress tests, change occurrences of 'Wrangler' with 'Move Thread'

* Fix linter

* Remove enterprise lock

* A couple more occurrences of wrangler strings, and one more enterprise lock

* Fix server tests

* Fix i18n

* Fix e2e linter

* Feature flag shouldn't be on by default

* Enable move threads feature in smoke tests (#25657)

* enable move threads feature
* add @prod tag

* Fix move_thread_from_public_channel e2e test

* Fix e2e style

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
Этот коммит содержится в:
Nick Misasi
2023-12-11 15:27:34 -05:00
коммит произвёл GitHub
родитель bfb8320afd
Коммит f0a336ba07
56 изменённых файлов: 3107 добавлений и 16 удалений

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

@@ -44,6 +44,8 @@ func (api *API) InitPost() {
api.BaseRoutes.PostForUser.Handle("/ack", api.APISessionRequired(acknowledgePost)).Methods("POST")
api.BaseRoutes.PostForUser.Handle("/ack", api.APISessionRequired(unacknowledgePost)).Methods("DELETE")
api.BaseRoutes.Post.Handle("/move", api.APISessionRequired(moveThread)).Methods("POST")
}
func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -1128,6 +1130,83 @@ func unacknowledgePost(c *Context, w http.ResponseWriter, r *http.Request) {
ReturnStatusOK(w)
}
func moveThread(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequirePostId()
if c.Err != nil {
return
}
if !c.App.Config().FeatureFlags.MoveThreadsEnabled {
c.Err = model.NewAppError("moveThread", "api.post.move_thread.disabled.app_error", nil, "", http.StatusNotImplemented)
return
}
var moveThreadParams model.MoveThreadParams
if jsonErr := json.NewDecoder(r.Body).Decode(&moveThreadParams); jsonErr != nil {
c.SetInvalidParamWithErr("post", jsonErr)
return
}
auditRec := c.MakeAuditRecord("moveThread", audit.Fail)
defer c.LogAuditRecWithLevel(auditRec, app.LevelContent)
audit.AddEventParameter(auditRec, "original_post_id", c.Params.PostId)
audit.AddEventParameter(auditRec, "to_channel_id", moveThreadParams.ChannelId)
user, err := c.App.GetUser(c.AppContext.Session().UserId)
if err != nil {
c.Err = err
return
}
// If there are no configured PermittedWranglerRoles, skip the check
userHasRole := len(c.App.Config().WranglerSettings.PermittedWranglerRoles) == 0
for _, role := range c.App.Config().WranglerSettings.PermittedWranglerRoles {
if user.IsInRole(role) {
userHasRole = true
break
}
}
// Sysadmins are always permitted
if !userHasRole && !user.IsSystemAdmin() {
c.Err = model.NewAppError("moveThread", "api.post.move_thread.no_permission", nil, "", http.StatusForbidden)
return
}
userHasEmailDomain := len(c.App.Config().WranglerSettings.AllowedEmailDomain) == 0
for _, domain := range c.App.Config().WranglerSettings.AllowedEmailDomain {
if user.EmailDomain() == domain {
userHasEmailDomain = true
break
}
}
if !userHasEmailDomain && !user.IsSystemAdmin() {
c.Err = model.NewAppError("moveThread", "api.post.move_thread.no_permission", nil, fmt.Sprintf("User: %+v", user), http.StatusForbidden)
return
}
sourcePost, err := c.App.GetPostIfAuthorized(c.AppContext, c.Params.PostId, c.AppContext.Session(), false)
if err != nil {
c.Err = err
if err.Id == "app.post.cloud.get.app_error" {
w.Header().Set(model.HeaderFirstInaccessiblePostTime, "1")
}
return
}
err = c.App.MoveThread(c.AppContext, c.Params.PostId, sourcePost.ChannelId, moveThreadParams.ChannelId, user)
if err != nil {
c.Err = err
return
}
auditRec.Success()
ReturnStatusOK(w)
}
func getFileInfosForPost(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequirePostId()
if c.Err != nil {

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

@@ -730,6 +730,239 @@ func TestCreatePostWithOutgoingHook_no_content_type(t *testing.T) {
})
}
func TestMoveThread(t *testing.T) {
os.Setenv("MM_FEATUREFLAGS_MOVETHREADSENABLED", "true")
defer os.Unsetenv("MM_FEATUREFLAGS_MOVETHREADSENABLED")
th := Setup(t).InitBasic()
defer th.TearDown()
client := th.Client
ctx := context.Background()
basicUser1 := th.BasicUser
basicUser2 := th.BasicUser2
basicUser3 := th.CreateUser()
// Create a new public channel to move the post to
publicChannel, resp, err := client.CreateChannel(ctx, &model.Channel{
TeamId: th.BasicTeam.Id,
Name: "test-public-channel",
DisplayName: "Test Public Channel",
Type: model.ChannelTypeOpen,
})
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, publicChannel)
// Create a new private channel to move the post to
privateChannel, resp, err := client.CreateChannel(ctx, &model.Channel{
TeamId: th.BasicTeam.Id,
Name: "test-private-channel",
DisplayName: "Test Private Channel",
Type: model.ChannelTypePrivate,
})
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, privateChannel)
// Create a new direct message channel to move the post to
dmChannel, resp, err := client.CreateDirectChannel(ctx, basicUser1.Id, basicUser2.Id)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, dmChannel)
// Create a new group message channel to move the post to
gmChannel, resp, err := client.CreateGroupChannel(ctx, []string{basicUser1.Id, basicUser2.Id, basicUser3.Id})
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, gmChannel)
t.Run("Move to public channel", func(t *testing.T) {
// Create a new post to move
post := &model.Post{
ChannelId: th.BasicChannel.Id,
Message: "test post",
}
newPost, resp, err := client.CreatePost(ctx, post)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, newPost)
// Move the post to the public channel
moveThreadParams := &model.MoveThreadParams{
ChannelId: publicChannel.Id,
}
resp, err = client.MoveThread(ctx, newPost.Id, moveThreadParams)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Check that the post was moved to the public channel
posts, resp, err := client.GetPostsForChannel(ctx, publicChannel.Id, 0, 100, "", true, false)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, posts)
// There should be 2 posts, the system join message for the user who moved it joining the channel, and the post we moved
require.Equal(t, 2, len(posts.Posts))
require.Equal(t, newPost.Message, posts.Posts[posts.Order[0]].Message)
})
t.Run("Move to private channel", func(t *testing.T) {
// Create a new post to move
post := &model.Post{
ChannelId: th.BasicChannel.Id,
Message: "test post",
}
newPost, resp, err := client.CreatePost(ctx, post)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, newPost)
// Move the post to the private channel
moveThreadParams := &model.MoveThreadParams{
ChannelId: privateChannel.Id,
}
resp, err = client.MoveThread(ctx, newPost.Id, moveThreadParams)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Check that the post was moved to the private channel
posts, resp, err := client.GetPostsForChannel(ctx, privateChannel.Id, 0, 100, "", true, false)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, posts)
// There should be 2 posts, the system join message for the user who moved it joining the channel, and the post we moved
require.Equal(t, 2, len(posts.Posts))
require.Equal(t, newPost.Message, posts.Posts[posts.Order[0]].Message)
})
t.Run("Move to direct message channel", func(t *testing.T) {
// Create a new post to move
post := &model.Post{
ChannelId: th.BasicChannel.Id,
Message: "test post",
}
newPost, resp, err := client.CreatePost(ctx, post)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, newPost)
// Move the post to the direct message channel
moveThreadParams := &model.MoveThreadParams{
ChannelId: dmChannel.Id,
}
resp, err = client.MoveThread(ctx, newPost.Id, moveThreadParams)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Check that the post was moved to the direct message channel
posts, resp, err := client.GetPostsForChannel(ctx, dmChannel.Id, 0, 100, "", true, false)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, posts)
// There should be 1 post, the post we moved
require.Equal(t, 1, len(posts.Posts))
require.Equal(t, newPost.Message, posts.Posts[posts.Order[0]].Message)
})
t.Run("Move to group message channel", func(t *testing.T) {
// Create a new post to move
post := &model.Post{
ChannelId: th.BasicChannel.Id,
Message: "test post",
}
newPost, resp, err := client.CreatePost(ctx, post)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, newPost)
// Move the post to the group message channel
moveThreadParams := &model.MoveThreadParams{
ChannelId: gmChannel.Id,
}
resp, err = client.MoveThread(ctx, newPost.Id, moveThreadParams)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Check that the post was moved to the group message channel
posts, resp, err := client.GetPostsForChannel(ctx, gmChannel.Id, 0, 100, "", true, false)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, posts)
// There should be 1 post, the post we moved
require.Equal(t, 1, len(posts.Posts))
require.Equal(t, newPost.Message, posts.Posts[posts.Order[0]].Message)
})
t.Run("Move thread with more than one post", func(t *testing.T) {
// Create a new public channel to move the post to
pChannel, resp, err := client.CreateChannel(ctx, &model.Channel{
TeamId: th.BasicTeam.Id,
Name: "test-public-channel2",
DisplayName: "Test Public Channel",
Type: model.ChannelTypeOpen,
})
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, pChannel)
// Create a new post to use as the root post
rootPost := &model.Post{
ChannelId: th.BasicChannel.Id,
Message: "root post",
}
rootPost, resp, err = client.CreatePost(ctx, rootPost)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, rootPost)
// Create a new post to move
post := &model.Post{
ChannelId: th.BasicChannel.Id,
Message: "test post",
RootId: rootPost.Id,
}
newPost, resp, err := client.CreatePost(ctx, post)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, newPost)
// Create another post in the thread
post = &model.Post{
ChannelId: th.BasicChannel.Id,
Message: "test post 2",
RootId: rootPost.Id,
}
newPost2, resp, err := client.CreatePost(ctx, post)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, newPost2)
// Move the thread to the public channel
moveThreadParams := &model.MoveThreadParams{
ChannelId: pChannel.Id,
}
resp, err = client.MoveThread(ctx, rootPost.Id, moveThreadParams)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Check that the thread was moved to the public channel
posts, resp, err := client.GetPostsForChannel(ctx, pChannel.Id, 0, 100, "", false, false)
require.NoError(t, err)
require.NotNil(t, resp)
require.NotNil(t, posts)
// There should be 3 posts, the system join message for the user who moved it joining the channel, and the two posts in the thread
// require.Equal(t, 3, len(posts.Posts))
fmt.Println(posts.Order)
for _, p := range posts.Order {
fmt.Println(posts.Posts[p].Id)
fmt.Println(posts.Posts[p].Message)
}
require.Equal(t, "This thread was moved from another channel", posts.Posts[posts.Order[0]].Message)
require.Equal(t, newPost2.Message, posts.Posts[posts.Order[1]].Message)
require.Equal(t, newPost.Message, posts.Posts[posts.Order[2]].Message)
require.Equal(t, rootPost.Message, posts.Posts[posts.Order[3]].Message)
})
}
func TestCreatePostPublic(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()