From 7bd298ceaa24c0721e0acd65692cb2d1ca4983f3 Mon Sep 17 00:00:00 2001 From: Vordimous Date: Wed, 7 Feb 2018 09:17:18 -0500 Subject: PLT-7537: Move channel CLI command posts system message to channel. (#8161) * [PTL-7537] implement feature and test * [PTL-7537] Update feature to post the the room requiring a username flag to be used * [PTL-7537] update tests with username * update test to remove changes to the test helper struct * use the basic team and user --- app/channel.go | 30 ++++++++++++++++++++++++++++-- app/channel_test.go | 4 ++-- cmd/platform/channel.go | 17 +++++++++++++---- cmd/platform/channel_test.go | 27 +++++++++++++++++++++++++++ i18n/en.json | 8 ++++++++ model/post.go | 2 ++ 6 files changed, 80 insertions(+), 8 deletions(-) diff --git a/app/channel.go b/app/channel.go index e4bf48654..8ac1f421c 100644 --- a/app/channel.go +++ b/app/channel.go @@ -1359,7 +1359,7 @@ func (a *App) PermanentDeleteChannel(channel *model.Channel) *model.AppError { // This function is intended for use from the CLI. It is not robust against people joining the channel while the move // is in progress, and therefore should not be used from the API without first fixing this potential race condition. -func (a *App) MoveChannel(team *model.Team, channel *model.Channel) *model.AppError { +func (a *App) MoveChannel(team *model.Team, channel *model.Channel, user *model.User) *model.AppError { // Check that all channel members are in the destination team. if channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000); err != nil { return err @@ -1378,11 +1378,37 @@ func (a *App) MoveChannel(team *model.Team, channel *model.Channel) *model.AppEr } } - // Change the Team ID of the channel. + // keep instance of the previous team + var previousTeam *model.Team + if result := <-a.Srv.Store.Team().Get(channel.TeamId); result.Err != nil { + return result.Err + } else { + previousTeam = result.Data.(*model.Team) + } channel.TeamId = team.Id if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil { return result.Err } + a.postChannelMoveMessage(user, channel, previousTeam) + + return nil +} + +func (a *App) postChannelMoveMessage(user *model.User, channel *model.Channel, previousTeam *model.Team) *model.AppError { + + post := &model.Post{ + ChannelId: channel.Id, + Message: fmt.Sprintf(utils.T("api.team.move_channel.success"), previousTeam.Name), + Type: model.POST_MOVE_CHANNEL, + UserId: user.Id, + Props: model.StringInterface{ + "username": user.Username, + }, + } + + if _, err := a.CreatePost(post, channel, false); err != nil { + return model.NewAppError("postChannelMoveMessage", "api.team.move_channel.post.error", nil, err.Error(), http.StatusInternalServerError) + } return nil } diff --git a/app/channel_test.go b/app/channel_test.go index a414fbb35..d315fbae6 100644 --- a/app/channel_test.go +++ b/app/channel_test.go @@ -97,7 +97,7 @@ func TestMoveChannel(t *testing.T) { t.Fatal(err) } - if err := th.App.MoveChannel(targetTeam, channel1); err == nil { + if err := th.App.MoveChannel(targetTeam, channel1, th.BasicUser); err == nil { t.Fatal("Should have failed due to mismatched members.") } @@ -105,7 +105,7 @@ func TestMoveChannel(t *testing.T) { t.Fatal(err) } - if err := th.App.MoveChannel(targetTeam, channel1); err != nil { + if err := th.App.MoveChannel(targetTeam, channel1, th.BasicUser); err != nil { t.Fatal(err) } } diff --git a/cmd/platform/channel.go b/cmd/platform/channel.go index 98bdcebb8..5d86ad9da 100644 --- a/cmd/platform/channel.go +++ b/cmd/platform/channel.go @@ -106,6 +106,8 @@ func init() { channelCreateCmd.Flags().String("purpose", "", "Channel purpose") channelCreateCmd.Flags().Bool("private", false, "Create a private channel.") + moveChannelsCmd.Flags().String("username", "", "Required. Username who is moving the channel.") + deleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.") modifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel") @@ -319,26 +321,33 @@ func moveChannelsCmdF(cmd *cobra.Command, args []string) error { return errors.New("Unable to find destination team '" + args[0] + "'") } + username, erru := cmd.Flags().GetString("username") + if erru != nil || username == "" { + return errors.New("Username is required") + } + user := getUserFromUserArg(a, username) + channels := getChannelsFromChannelArgs(a, args[1:]) for i, channel := range channels { if channel == nil { CommandPrintErrorln("Unable to find channel '" + args[i] + "'") continue } - if err := moveChannel(a, team, channel); err != nil { + originTeamID := channel.TeamId + if err := moveChannel(a, team, channel, user); err != nil { CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error()) } else { - CommandPrettyPrintln("Moved channel '" + channel.Name + "'") + CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".") } } return nil } -func moveChannel(a *app.App, team *model.Team, channel *model.Channel) *model.AppError { +func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *model.User) *model.AppError { oldTeamId := channel.TeamId - if err := a.MoveChannel(team, channel); err != nil { + if err := a.MoveChannel(team, channel, user); err != nil { return err } diff --git a/cmd/platform/channel_test.go b/cmd/platform/channel_test.go index 1e6915679..cf8603cf3 100644 --- a/cmd/platform/channel_test.go +++ b/cmd/platform/channel_test.go @@ -44,6 +44,33 @@ func TestRemoveChannel(t *testing.T) { checkCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) } +func TestMoveChannel(t *testing.T) { + th := api.Setup().InitBasic() + defer th.TearDown() + + client := th.BasicClient + team1 := th.BasicTeam + team2 := th.CreateTeam(client) + user1 := th.BasicUser + th.LinkUserToTeam(user1, team2) + channel := th.BasicChannel + + th.LinkUserToTeam(user1, team1) + th.LinkUserToTeam(user1, team2) + + adminEmail := user1.Email + adminUsername := user1.Username + origin := team1.Name + ":" + channel.Name + dest := team2.Name + + checkCommand(t, "channel", "add", origin, adminEmail) + + // should fail with nill because errors are logged instead of returned when a channel does not exist + require.Nil(t, runCommand(t, "channel", "move", dest, team1.Name+":doesnotexist", "--username", adminUsername)) + + checkCommand(t, "channel", "move", dest, origin, "--username", adminUsername) +} + func TestListChannels(t *testing.T) { th := api.Setup().InitBasic() defer th.TearDown() diff --git a/i18n/en.json b/i18n/en.json index 1a04aeeed..21f0661cc 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -3130,6 +3130,14 @@ "id": "app.channel.move_channel.members_do_not_match.error", "translation": "Cannot move a channel unless all its members are already members of the destination team." }, + { + "id": "api.team.move_channel.success", + "translation": "This channel has been moved to this team from %v." + }, + { + "id": "api.team.move_channel.post.error", + "translation": "Failed to post channel move message." + }, { "id": "app.channel.post_update_channel_purpose_message.post.error", "translation": "Failed to post channel purpose message" diff --git a/model/post.go b/model/post.go index 391b948f4..7cf0f1b35 100644 --- a/model/post.go +++ b/model/post.go @@ -28,6 +28,7 @@ const ( POST_ADD_REMOVE = "system_add_remove" // Deprecated, use POST_ADD_TO_CHANNEL or POST_REMOVE_FROM_CHANNEL instead POST_ADD_TO_CHANNEL = "system_add_to_channel" POST_REMOVE_FROM_CHANNEL = "system_remove_from_channel" + POST_MOVE_CHANNEL = "system_move_channel" POST_ADD_TO_TEAM = "system_add_to_team" POST_REMOVE_FROM_TEAM = "system_remove_from_team" POST_HEADER_CHANGE = "system_header_change" @@ -196,6 +197,7 @@ func (o *Post) IsValid() *AppError { POST_LEAVE_TEAM, POST_ADD_TO_CHANNEL, POST_REMOVE_FROM_CHANNEL, + POST_MOVE_CHANNEL, POST_ADD_TO_TEAM, POST_REMOVE_FROM_TEAM, POST_SLACK_ATTACHMENT, -- cgit v1.2.3-1-g7c22