MM-31339: Send only one direct message reply within one calendar day. (#17181)
* don't send auto response if already responded today * update query to get posts from channel for given user and Updatetime requires value in milli seconds * regenerate mocks and layers * update function to return true/false on existence of auto responded post in channel and add tests * add store tests * bubble up error and propagate upstream * fix error handling logic * use require instead of assert Co-authored-by: Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> * rename variable for better redability and logging fixes * update comment explaining function * use new function to generate test ids * add comments to clarify NewTestId copies * add translations for error id * fix translation Co-authored-by: Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> Co-authored-by: Mattermod <mattermod@users.noreply.github.com> Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
Этот коммит содержится в:
@@ -4,9 +4,22 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
)
|
||||
|
||||
// check if there is any auto_response type post in channel by the user in a calender day
|
||||
func (a *App) checkIfRespondedToday(createdAt int64, channelId, userId string) (bool, error) {
|
||||
y, m, d := time.Unix(createdAt, 0).Date()
|
||||
since := model.GetMillisForTime(time.Date(y, m, d, 0, 0, 0, 0, time.UTC))
|
||||
return a.Srv().Store.Post().HasAutoResponsePostByUserSince(
|
||||
model.GetPostsSinceOptions{ChannelId: channelId, Time: since},
|
||||
userId,
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
@@ -22,9 +35,17 @@ func (a *App) SendAutoResponseIfNecessary(channel *model.Channel, sender *model.
|
||||
receiverId = sender.Id
|
||||
}
|
||||
|
||||
receiver, err := a.GetUser(receiverId)
|
||||
receiver, aErr := a.GetUser(receiverId)
|
||||
if aErr != nil {
|
||||
return false, aErr
|
||||
}
|
||||
|
||||
autoResponded, err := a.checkIfRespondedToday(post.CreateAt, post.ChannelId, receiverId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, model.NewAppError("SendAutoResponseIfNecessary", "app.user.send_auto_response.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
if autoResponded {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return a.SendAutoResponse(channel, receiver, post)
|
||||
|
||||
@@ -197,6 +197,43 @@ func TestSendAutoResponseIfNecessary(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.False(t, sent)
|
||||
})
|
||||
|
||||
t.Run("should send auto response in dm channel if not already sent today", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
receiver := th.CreateUser()
|
||||
|
||||
patch := &model.UserPatch{
|
||||
NotifyProps: map[string]string{
|
||||
"auto_responder_active": "true",
|
||||
"auto_responder_message": "Hello, I'm unavailable today.",
|
||||
},
|
||||
}
|
||||
receiver, err := th.App.PatchUser(receiver.Id, patch, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
channel := th.CreateDmChannel(receiver)
|
||||
|
||||
savedPost, err := th.App.CreatePost(&model.Post{
|
||||
ChannelId: channel.Id,
|
||||
Message: NewTestId(),
|
||||
UserId: th.BasicUser.Id},
|
||||
th.BasicChannel,
|
||||
false, true)
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
sent, err := th.App.SendAutoResponseIfNecessary(channel, th.BasicUser, savedPost)
|
||||
|
||||
require.Nil(t, err)
|
||||
assert.True(t, sent)
|
||||
|
||||
sent, err = th.App.SendAutoResponseIfNecessary(channel, th.BasicUser, savedPost)
|
||||
|
||||
require.Nil(t, err)
|
||||
assert.False(t, sent)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSendAutoResponseSuccess(t *testing.T) {
|
||||
|
||||
@@ -708,3 +708,16 @@ func (th *TestHelper) AddPermissionToRole(permission string, roleName string) {
|
||||
|
||||
utils.EnableDebugLogForTest()
|
||||
}
|
||||
|
||||
// This function is copy of storetest/NewTestId
|
||||
// NewTestId is used for testing as a replacement for model.NewId(). It is a [A-Z0-9] string 26
|
||||
// characters long. It replaces every odd character with a digit.
|
||||
func NewTestId() string {
|
||||
newId := []byte(model.NewId())
|
||||
|
||||
for i := 1; i < len(newId); i = i + 2 {
|
||||
newId[i] = 48 + newId[i-1]%10
|
||||
}
|
||||
|
||||
return string(newId)
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user