diff --git a/app/app_iface.go b/app/app_iface.go index 7302cc69a8..3eb8ac9ed9 100644 --- a/app/app_iface.go +++ b/app/app_iface.go @@ -884,8 +884,8 @@ type AppIface interface { SearchUsersNotInTeam(notInTeamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) SearchUsersWithoutTeam(term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) SendAckToPushProxy(ack *model.PushNotificationAck) error - SendAutoResponse(channel *model.Channel, receiver *model.User) (bool, *model.AppError) - SendAutoResponseIfNecessary(channel *model.Channel, sender *model.User) (bool, *model.AppError) + SendAutoResponse(channel *model.Channel, receiver *model.User, post *model.Post) (bool, *model.AppError) + SendAutoResponseIfNecessary(channel *model.Channel, sender *model.User, post *model.Post) (bool, *model.AppError) SendEmailVerification(user *model.User, newEmail, redirect string) *model.AppError SendEphemeralPost(userId string, post *model.Post) *model.Post SendNotifications(post *model.Post, team *model.Team, channel *model.Channel, sender *model.User, parentPostList *model.PostList, setOnline bool) ([]string, error) diff --git a/app/auto_responder.go b/app/auto_responder.go index 56d2d195d5..fd92aa5031 100644 --- a/app/auto_responder.go +++ b/app/auto_responder.go @@ -8,7 +8,7 @@ import ( "github.com/mattermost/mattermost-server/v5/model" ) -func (a *App) SendAutoResponseIfNecessary(channel *model.Channel, sender *model.User) (bool, *model.AppError) { +func (a *App) SendAutoResponseIfNecessary(channel *model.Channel, sender *model.User, post *model.Post) (bool, *model.AppError) { if channel.Type != model.CHANNEL_DIRECT { return false, nil } @@ -28,10 +28,10 @@ func (a *App) SendAutoResponseIfNecessary(channel *model.Channel, sender *model. return false, err } - return a.SendAutoResponse(channel, receiver) + return a.SendAutoResponse(channel, receiver, post) } -func (a *App) SendAutoResponse(channel *model.Channel, receiver *model.User) (bool, *model.AppError) { +func (a *App) SendAutoResponse(channel *model.Channel, receiver *model.User, post *model.Post) (bool, *model.AppError) { if receiver == nil || receiver.NotifyProps == nil { return false, nil } @@ -43,11 +43,15 @@ func (a *App) SendAutoResponse(channel *model.Channel, receiver *model.User) (bo return false, nil } + rootID := post.Id + if post.RootId != "" { + rootID = post.RootId + } + autoResponderPost := &model.Post{ ChannelId: channel.Id, Message: message, - RootId: "", - ParentId: "", + RootId: rootID, Type: model.POST_AUTO_RESPONDER, UserId: receiver.Id, } diff --git a/app/auto_responder_test.go b/app/auto_responder_test.go index 6ed9d674b9..7b61103b25 100644 --- a/app/auto_responder_test.go +++ b/app/auto_responder_test.go @@ -97,7 +97,14 @@ func TestSendAutoResponseIfNecessary(t *testing.T) { channel := th.CreateDmChannel(receiver) - sent, err := th.App.SendAutoResponseIfNecessary(channel, th.BasicUser) + savedPost, _ := th.App.CreatePost(&model.Post{ + ChannelId: channel.Id, + Message: "zz" + model.NewId() + "a", + UserId: th.BasicUser.Id}, + th.BasicChannel, + false, true) + + sent, err := th.App.SendAutoResponseIfNecessary(channel, th.BasicUser, savedPost) assert.Nil(t, err) assert.True(t, sent) @@ -120,7 +127,14 @@ func TestSendAutoResponseIfNecessary(t *testing.T) { channel := th.CreateDmChannel(receiver) - sent, err := th.App.SendAutoResponseIfNecessary(channel, th.BasicUser) + savedPost, _ := th.App.CreatePost(&model.Post{ + ChannelId: channel.Id, + Message: "zz" + model.NewId() + "a", + UserId: th.BasicUser.Id}, + th.BasicChannel, + false, true) + + sent, err := th.App.SendAutoResponseIfNecessary(channel, th.BasicUser, savedPost) assert.Nil(t, err) assert.False(t, sent) @@ -130,7 +144,14 @@ func TestSendAutoResponseIfNecessary(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() - sent, err := th.App.SendAutoResponseIfNecessary(th.BasicChannel, th.BasicUser) + savedPost, _ := th.App.CreatePost(&model.Post{ + ChannelId: th.BasicChannel.Id, + Message: "zz" + model.NewId() + "a", + UserId: th.BasicUser.Id}, + th.BasicChannel, + false, true) + + sent, err := th.App.SendAutoResponseIfNecessary(th.BasicChannel, th.BasicUser, savedPost) assert.Nil(t, err) assert.False(t, sent) @@ -163,7 +184,14 @@ func TestSendAutoResponseIfNecessary(t *testing.T) { botUser, err := th.App.GetUser(bot.UserId) assert.Nil(t, err) - sent, err := th.App.SendAutoResponseIfNecessary(channel, botUser) + savedPost, _ := th.App.CreatePost(&model.Post{ + ChannelId: channel.Id, + Message: "zz" + model.NewId() + "a", + UserId: botUser.Id}, + th.BasicChannel, + false, true) + + sent, err := th.App.SendAutoResponseIfNecessary(channel, botUser, savedPost) assert.Nil(t, err) assert.False(t, sent) @@ -185,29 +213,80 @@ func TestSendAutoResponseSuccess(t *testing.T) { userUpdated1, err := th.App.PatchUser(user.Id, patch, true) require.Nil(t, err) - th.App.CreatePost(&model.Post{ + savedPost, _ := th.App.CreatePost(&model.Post{ ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a", UserId: th.BasicUser.Id}, th.BasicChannel, false, true) - sent, err := th.App.SendAutoResponse(th.BasicChannel, userUpdated1) + sent, err := th.App.SendAutoResponse(th.BasicChannel, userUpdated1, savedPost) assert.Nil(t, err) assert.True(t, sent) - if list, err := th.App.GetPosts(th.BasicChannel.Id, 0, 1); err != nil { - require.Nil(t, err) - } else { - autoResponderPostFound := false - for _, post := range list.Posts { - if post.Type == model.POST_AUTO_RESPONDER { - autoResponderPostFound = true - } + list, err := th.App.GetPosts(th.BasicChannel.Id, 0, 1) + require.Nil(t, err) + + autoResponderPostFound := false + for _, post := range list.Posts { + if post.Type == model.POST_AUTO_RESPONDER { + autoResponderPostFound = true + assert.Equal(t, savedPost.Id, post.RootId) + assert.Equal(t, savedPost.Id, post.ParentId) } - assert.True(t, autoResponderPostFound) } + assert.True(t, autoResponderPostFound) +} + +func TestSendAutoResponseSuccessOnThread(t *testing.T) { + th := Setup(t).InitBasic() + defer th.TearDown() + + user := th.CreateUser() + defer th.App.PermanentDeleteUser(user) + + patch := &model.UserPatch{} + patch.NotifyProps = make(map[string]string) + patch.NotifyProps["auto_responder_active"] = "true" + patch.NotifyProps["auto_responder_message"] = "Hello, I'm unavailable today." + + userUpdated1, err := th.App.PatchUser(user.Id, patch, true) + require.Nil(t, err) + + parentPost, _ := th.App.CreatePost(&model.Post{ + ChannelId: th.BasicChannel.Id, + Message: "zz" + model.NewId() + "a", + UserId: th.BasicUser.Id}, + th.BasicChannel, + false, true) + + savedPost, _ := th.App.CreatePost(&model.Post{ + ChannelId: th.BasicChannel.Id, + Message: "zz" + model.NewId() + "a", + UserId: th.BasicUser.Id, + RootId: parentPost.Id, + ParentId: parentPost.Id}, + th.BasicChannel, + false, true) + + sent, err := th.App.SendAutoResponse(th.BasicChannel, userUpdated1, savedPost) + + assert.Nil(t, err) + assert.True(t, sent) + + list, err := th.App.GetPosts(th.BasicChannel.Id, 0, 1) + require.Nil(t, err) + + autoResponderPostFound := false + for _, post := range list.Posts { + if post.Type == model.POST_AUTO_RESPONDER { + autoResponderPostFound = true + assert.Equal(t, savedPost.RootId, post.RootId) + assert.Equal(t, savedPost.ParentId, post.ParentId) + } + } + assert.True(t, autoResponderPostFound) } func TestSendAutoResponseFailure(t *testing.T) { @@ -225,14 +304,14 @@ func TestSendAutoResponseFailure(t *testing.T) { userUpdated1, err := th.App.PatchUser(user.Id, patch, true) require.Nil(t, err) - th.App.CreatePost(&model.Post{ + savedPost, _ := th.App.CreatePost(&model.Post{ ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a", UserId: th.BasicUser.Id}, th.BasicChannel, false, true) - sent, err := th.App.SendAutoResponse(th.BasicChannel, userUpdated1) + sent, err := th.App.SendAutoResponse(th.BasicChannel, userUpdated1, savedPost) assert.Nil(t, err) assert.False(t, sent) diff --git a/app/opentracing/opentracing_layer.go b/app/opentracing/opentracing_layer.go index 23b18d10b2..8e2f1109b4 100644 --- a/app/opentracing/opentracing_layer.go +++ b/app/opentracing/opentracing_layer.go @@ -12895,7 +12895,7 @@ func (a *OpenTracingAppLayer) SendAckToPushProxy(ack *model.PushNotificationAck) return resultVar0 } -func (a *OpenTracingAppLayer) SendAutoResponse(channel *model.Channel, receiver *model.User) (bool, *model.AppError) { +func (a *OpenTracingAppLayer) SendAutoResponse(channel *model.Channel, receiver *model.User, post *model.Post) (bool, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SendAutoResponse") @@ -12907,7 +12907,7 @@ func (a *OpenTracingAppLayer) SendAutoResponse(channel *model.Channel, receiver }() defer span.Finish() - resultVar0, resultVar1 := a.app.SendAutoResponse(channel, receiver) + resultVar0, resultVar1 := a.app.SendAutoResponse(channel, receiver, post) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) @@ -12917,7 +12917,7 @@ func (a *OpenTracingAppLayer) SendAutoResponse(channel *model.Channel, receiver return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) SendAutoResponseIfNecessary(channel *model.Channel, sender *model.User) (bool, *model.AppError) { +func (a *OpenTracingAppLayer) SendAutoResponseIfNecessary(channel *model.Channel, sender *model.User, post *model.Post) (bool, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SendAutoResponseIfNecessary") @@ -12929,7 +12929,7 @@ func (a *OpenTracingAppLayer) SendAutoResponseIfNecessary(channel *model.Channel }() defer span.Finish() - resultVar0, resultVar1 := a.app.SendAutoResponseIfNecessary(channel, sender) + resultVar0, resultVar1 := a.app.SendAutoResponseIfNecessary(channel, sender, post) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) diff --git a/app/post.go b/app/post.go index da731f8f2a..c24b2857f6 100644 --- a/app/post.go +++ b/app/post.go @@ -451,7 +451,7 @@ func (a *App) handlePostEvents(post *model.Post, user *model.User, channel *mode if post.Type != model.POST_AUTO_RESPONDER { // don't respond to an auto-responder a.Srv().Go(func() { - _, err := a.SendAutoResponseIfNecessary(channel, user) + _, err := a.SendAutoResponseIfNecessary(channel, user, post) if err != nil { mlog.Error("Failed to send auto response", mlog.String("user_id", user.Id), mlog.String("post_id", post.Id), mlog.Err(err)) }