mirror of
https://github.com/hanzoai/team.git
synced 2026-09-30 01:57:35 +00:00
* Add direct message support to mmctl post create Co-authored-by: mattermost-code <[email protected]> * Regenerate mmctl docs for post create direct messages Co-authored-by: mattermost-code <[email protected]> * Strengthen mmctl post create direct message test coverage Co-authored-by: mattermost-code <[email protected]> * Document why local mmctl client cannot send direct messages Add a test comment explaining that local mode lacks the post-create, direct-channel, and current-user API endpoints required by post create. Co-authored-by: mattermost-code <[email protected]> * Add local mode API support for mmctl post create Implement local mode handlers for POST /posts and POST /channels/direct, and add --user flag to mmctl post create for specifying the acting user in local mode instead of relying on GET /users/me. Co-authored-by: mattermost-code <[email protected]> * Address CodeRabbit feedback and regenerate mmctl docs - Defer WriteHeader in localCreatePost until after burn-on-read handling - Preserve prior viper local state in post create tests - Regenerate mmctl docs for --user flag Co-authored-by: mattermost-code <[email protected]> * Address PR feedback: 2 answered, 3 resolved, 0 declined * Reset mmctl unit test config state * Address PR feedback: 3 answered, 1 resolved, 0 declined * Address PR feedback: 1 answered, 1 resolved, 0 declined * Retrigger CI after transient Enterprise FIPS proxy.golang.org failure Co-authored-by: mattermost-code <[email protected]> * Merge local-mode API tests into their parent test functions Fold TestLocalCreateDirectChannel into TestCreateDirectChannel and TestLocalCreatePost into TestCreatePost as local-mode subtests, per reviewer feedback to consolidate the local-mode coverage with the existing create tests. * Revert local mode support for mmctl post create Reverts 20a2b1c per reviewer feedback: remove the local-mode POST /posts and POST /channels/direct API handlers, the --user flag, and the associated audit events. mmctl post create now errors out when run with --local instead of attempting to create posts in local mode. * Retrigger CI after transient Enterprise FIPS npm cache failure The Enterprise CI/tests failure on 8d04b5c was caused by an npm EEXIST cache error during webapp node_modules install — unrelated to this PR's mmctl changes. Co-authored-by: mattermost-code <[email protected]> --------- Co-authored-by: mattermost-code <[email protected]> Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Hanzo Dev <[email protected]>
294 lines
9.1 KiB
Go
294 lines
9.1 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package commands
|
|
|
|
import (
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
|
|
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/client"
|
|
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
)
|
|
|
|
func (s *MmctlE2ETestSuite) TestPostListCmd() {
|
|
s.SetupTestHelper().InitBasic(s.T())
|
|
|
|
var createNewChannelAndPosts = func() (string, *model.Post, *model.Post) {
|
|
channelName := model.NewRandomString(10)
|
|
channelDisplayName := "channelDisplayName"
|
|
|
|
channel, err := s.th.App.CreateChannel(s.th.Context, &model.Channel{Name: channelName, DisplayName: channelDisplayName, Type: model.ChannelTypePrivate, TeamId: s.th.BasicTeam.Id}, false)
|
|
s.Require().Nil(err)
|
|
|
|
post1, _, err := s.th.App.CreatePost(s.th.Context, &model.Post{Message: model.NewRandomString(15), UserId: s.th.BasicUser.Id, ChannelId: channel.Id}, channel, model.CreatePostFlags{})
|
|
s.Require().Nil(err)
|
|
|
|
post2, _, err := s.th.App.CreatePost(s.th.Context, &model.Post{Message: model.NewRandomString(15), UserId: s.th.BasicUser.Id, ChannelId: channel.Id}, channel, model.CreatePostFlags{})
|
|
s.Require().Nil(err)
|
|
|
|
return channelName, post1, post2
|
|
}
|
|
|
|
s.RunForSystemAdminAndLocal("List all posts for a channel", func(c client.Client) {
|
|
printer.Clean()
|
|
|
|
teamName := s.th.BasicTeam.Name
|
|
channelName, post1, post2 := createNewChannelAndPosts()
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().Int("number", 2, "")
|
|
|
|
err := postListCmdF(c, cmd, []string{teamName + ":" + channelName})
|
|
s.Require().Nil(err)
|
|
s.Equal(2, len(printer.GetLines()))
|
|
|
|
printedPost1, ok := printer.GetLines()[0].(*model.Post)
|
|
s.Require().True(ok)
|
|
s.Require().Equal(printedPost1.Message, post1.Message)
|
|
|
|
printedPost2, ok := printer.GetLines()[1].(*model.Post)
|
|
s.Require().True(ok)
|
|
s.Require().Equal(printedPost2.Message, post2.Message)
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.Run("List all posts for a channel without permissions", func() {
|
|
printer.Clean()
|
|
|
|
teamName := s.th.BasicTeam.Name
|
|
channelName, _, _ := createNewChannelAndPosts()
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().Int("number", 2, "")
|
|
|
|
err := postListCmdF(s.th.Client, cmd, []string{teamName + ":" + channelName})
|
|
s.Require().NotNil(err)
|
|
//s.Require().Contains(err.Error(), "You do not have the appropriate permissions.")
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("List all posts for a channel with since flag", func(c client.Client) {
|
|
printer.Clean()
|
|
|
|
ISO8601ValidString := "2006-01-02T15:04:05-07:00"
|
|
teamName := s.th.BasicTeam.Name
|
|
channelName, post1, post2 := createNewChannelAndPosts()
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("since", ISO8601ValidString, "")
|
|
|
|
err := postListCmdF(c, cmd, []string{teamName + ":" + channelName})
|
|
s.Require().Nil(err)
|
|
s.Equal(2, len(printer.GetLines()))
|
|
|
|
printedPost1, ok := printer.GetLines()[0].(*model.Post)
|
|
s.Require().True(ok)
|
|
s.Require().Equal(printedPost1.Message, post1.Message)
|
|
|
|
printedPost2, ok := printer.GetLines()[1].(*model.Post)
|
|
s.Require().True(ok)
|
|
s.Require().Equal(printedPost2.Message, post2.Message)
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.Run("List all posts for a channel with since flag without permissions", func() {
|
|
printer.Clean()
|
|
|
|
ISO8601ValidString := "2006-01-02T15:04:05-07:00"
|
|
teamName := s.th.BasicTeam.Name
|
|
channelName, _, _ := createNewChannelAndPosts()
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("since", ISO8601ValidString, "")
|
|
|
|
err := postListCmdF(s.th.Client, cmd, []string{teamName + ":" + channelName})
|
|
s.Require().NotNil(err)
|
|
//s.Require().Contains(err.Error(), "You do not have the appropriate permissions.")
|
|
})
|
|
}
|
|
|
|
func (s *MmctlE2ETestSuite) TestPostCreateCmd() {
|
|
s.SetupTestHelper().InitBasic(s.T())
|
|
|
|
s.Run("Create a post for System Admin Client", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := "some text"
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
|
|
err := postCreateCmdF(s.th.SystemAdminClient, cmd, []string{s.th.BasicTeam.Name + ":" + s.th.BasicChannel.Name})
|
|
s.Require().Nil(err)
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.Run("Create a post for Client", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := "some text"
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
|
|
err := postCreateCmdF(s.th.Client, cmd, []string{s.th.BasicTeam.Name + ":" + s.th.BasicChannel.Name})
|
|
s.Require().Nil(err)
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.Run("Create a post for Local Client should fail", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := "some text"
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
prevLocal := viper.GetBool("local")
|
|
viper.Set("local", true)
|
|
defer viper.Set("local", prevLocal)
|
|
|
|
err := postCreateCmdF(s.th.LocalClient, cmd, []string{s.th.BasicTeam.Name + ":" + s.th.BasicChannel.Name})
|
|
s.Require().NotNil(err)
|
|
s.Require().Contains(err.Error(), "creating posts is not supported in local mode")
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.Run("Send a direct message for System Admin Client", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := model.NewRandomString(15)
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
|
|
err := postCreateCmdF(s.th.SystemAdminClient, cmd, []string{"@" + s.th.BasicUser2.Username})
|
|
s.Require().Nil(err)
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
|
|
dmChannel, appErr := s.th.App.GetOrCreateDirectChannel(s.th.Context, s.th.SystemAdminUser.Id, s.th.BasicUser2.Id)
|
|
s.Require().Nil(appErr)
|
|
|
|
posts, appErr := s.th.App.GetPosts(s.th.Context, dmChannel.Id, 0, 10)
|
|
s.Require().Nil(appErr)
|
|
|
|
var matched []*model.Post
|
|
for _, post := range posts.Posts {
|
|
if post.Message == msgArg {
|
|
matched = append(matched, post)
|
|
}
|
|
}
|
|
s.Require().Len(matched, 1, "expected exactly one direct message with the sent text")
|
|
s.Require().Equal(s.th.SystemAdminUser.Id, matched[0].UserId)
|
|
s.Require().Equal(dmChannel.Id, matched[0].ChannelId)
|
|
})
|
|
|
|
s.Run("Send a direct message for Client", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := model.NewRandomString(15)
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
|
|
err := postCreateCmdF(s.th.Client, cmd, []string{"@" + s.th.BasicUser2.Username})
|
|
s.Require().Nil(err)
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
|
|
dmChannel, appErr := s.th.App.GetOrCreateDirectChannel(s.th.Context, s.th.BasicUser.Id, s.th.BasicUser2.Id)
|
|
s.Require().Nil(appErr)
|
|
|
|
posts, appErr := s.th.App.GetPosts(s.th.Context, dmChannel.Id, 0, 10)
|
|
s.Require().Nil(appErr)
|
|
|
|
var matched []*model.Post
|
|
for _, post := range posts.Posts {
|
|
if post.Message == msgArg {
|
|
matched = append(matched, post)
|
|
}
|
|
}
|
|
s.Require().Len(matched, 1, "expected exactly one direct message with the sent text")
|
|
s.Require().Equal(s.th.BasicUser.Id, matched[0].UserId)
|
|
s.Require().Equal(dmChannel.Id, matched[0].ChannelId)
|
|
})
|
|
|
|
s.Run("Send a direct message for Local Client should fail", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := model.NewRandomString(15)
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
prevLocal := viper.GetBool("local")
|
|
viper.Set("local", true)
|
|
defer viper.Set("local", prevLocal)
|
|
|
|
err := postCreateCmdF(s.th.LocalClient, cmd, []string{"@" + s.th.BasicUser2.Username})
|
|
s.Require().NotNil(err)
|
|
s.Require().Contains(err.Error(), "creating posts is not supported in local mode")
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.Run("Send a direct message to a non-existing user should fail", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := model.NewRandomString(15)
|
|
missingUsername := model.NewUsername()
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
|
|
err := postCreateCmdF(s.th.SystemAdminClient, cmd, []string{"@" + missingUsername})
|
|
s.Require().NotNil(err)
|
|
s.Require().Contains(err.Error(), missingUsername)
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.Run("Reply to a an existing post for System Admin Client", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := "some text"
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
cmd.Flags().String("reply-to", s.th.BasicPost.Id, "")
|
|
|
|
err := postCreateCmdF(s.th.SystemAdminClient, cmd, []string{s.th.BasicTeam.Name + ":" + s.th.BasicChannel.Name})
|
|
s.Require().Nil(err)
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.Run("Reply to a an existing post for Client", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := "some text"
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
cmd.Flags().String("reply-to", s.th.BasicPost.Id, "")
|
|
|
|
err := postCreateCmdF(s.th.Client, cmd, []string{s.th.BasicTeam.Name + ":" + s.th.BasicChannel.Name})
|
|
s.Require().Nil(err)
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.Run("Reply to a an existing post for Local Client should fail", func() {
|
|
printer.Clean()
|
|
|
|
msgArg := "some text"
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("message", msgArg, "")
|
|
cmd.Flags().String("reply-to", s.th.BasicPost.Id, "")
|
|
prevLocal := viper.GetBool("local")
|
|
viper.Set("local", true)
|
|
defer viper.Set("local", prevLocal)
|
|
|
|
err := postCreateCmdF(s.th.LocalClient, cmd, []string{s.th.BasicTeam.Name + ":" + s.th.BasicChannel.Name})
|
|
s.Require().NotNil(err)
|
|
s.Require().Contains(err.Error(), "creating posts is not supported in local mode")
|
|
s.Len(printer.GetErrorLines(), 0)
|
|
})
|
|
}
|