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>
Этот коммит содержится в:
darkLord19
2021-04-22 10:03:45 +05:30
коммит произвёл GitHub
родитель f14b0097dd
Коммит f6505e1ee6
15 изменённых файлов: 740 добавлений и 514 удалений

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

@@ -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)
}