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
Этот коммит содержится в:
Vordimous
2018-02-07 09:17:18 -05:00
коммит произвёл George Goldberg
родитель d3e934d07a
Коммит 7bd298ceaa
6 изменённых файлов: 80 добавлений и 8 удалений

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

@@ -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 // 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. // 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. // Check that all channel members are in the destination team.
if channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000); err != nil { if channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000); err != nil {
return err 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 channel.TeamId = team.Id
if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil { if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil {
return result.Err 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 return nil
} }

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

@@ -97,7 +97,7 @@ func TestMoveChannel(t *testing.T) {
t.Fatal(err) 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.") t.Fatal("Should have failed due to mismatched members.")
} }
@@ -105,7 +105,7 @@ func TestMoveChannel(t *testing.T) {
t.Fatal(err) 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) t.Fatal(err)
} }
} }

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

@@ -106,6 +106,8 @@ func init() {
channelCreateCmd.Flags().String("purpose", "", "Channel purpose") channelCreateCmd.Flags().String("purpose", "", "Channel purpose")
channelCreateCmd.Flags().Bool("private", false, "Create a private channel.") 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.") 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") 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] + "'") 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:]) channels := getChannelsFromChannelArgs(a, args[1:])
for i, channel := range channels { for i, channel := range channels {
if channel == nil { if channel == nil {
CommandPrintErrorln("Unable to find channel '" + args[i] + "'") CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
continue 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()) CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error())
} else { } else {
CommandPrettyPrintln("Moved channel '" + channel.Name + "'") CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".")
} }
} }
return nil 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 oldTeamId := channel.TeamId
if err := a.MoveChannel(team, channel); err != nil { if err := a.MoveChannel(team, channel, user); err != nil {
return err return err
} }

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

@@ -44,6 +44,33 @@ func TestRemoveChannel(t *testing.T) {
checkCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) 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) { func TestListChannels(t *testing.T) {
th := api.Setup().InitBasic() th := api.Setup().InitBasic()
defer th.TearDown() defer th.TearDown()

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

@@ -3130,6 +3130,14 @@
"id": "app.channel.move_channel.members_do_not_match.error", "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." "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", "id": "app.channel.post_update_channel_purpose_message.post.error",
"translation": "Failed to post channel purpose message" "translation": "Failed to post channel purpose message"

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

@@ -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_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_ADD_TO_CHANNEL = "system_add_to_channel"
POST_REMOVE_FROM_CHANNEL = "system_remove_from_channel" POST_REMOVE_FROM_CHANNEL = "system_remove_from_channel"
POST_MOVE_CHANNEL = "system_move_channel"
POST_ADD_TO_TEAM = "system_add_to_team" POST_ADD_TO_TEAM = "system_add_to_team"
POST_REMOVE_FROM_TEAM = "system_remove_from_team" POST_REMOVE_FROM_TEAM = "system_remove_from_team"
POST_HEADER_CHANGE = "system_header_change" POST_HEADER_CHANGE = "system_header_change"
@@ -196,6 +197,7 @@ func (o *Post) IsValid() *AppError {
POST_LEAVE_TEAM, POST_LEAVE_TEAM,
POST_ADD_TO_CHANNEL, POST_ADD_TO_CHANNEL,
POST_REMOVE_FROM_CHANNEL, POST_REMOVE_FROM_CHANNEL,
POST_MOVE_CHANNEL,
POST_ADD_TO_TEAM, POST_ADD_TO_TEAM,
POST_REMOVE_FROM_TEAM, POST_REMOVE_FROM_TEAM,
POST_SLACK_ATTACHMENT, POST_SLACK_ATTACHMENT,