- soft delete reaction by setting new field Reactions.DeleteAt to non-zero.
- include new field Reactions.UpdateAt
Этот коммит содержится в:
Doug Lauder
2021-01-20 10:09:23 -05:00
коммит произвёл GitHub
родитель 11c6d07d6a
Коммит dbbf985e61
9 изменённых файлов: 227 добавлений и 55 удалений

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

@@ -16,11 +16,11 @@ import (
"github.com/mattermost/mattermost-server/v5/store/retrylayer"
)
func TestReactionStore(t *testing.T, ss store.Store) {
func TestReactionStore(t *testing.T, ss store.Store, s SqlStore) {
t.Run("ReactionSave", func(t *testing.T) { testReactionSave(t, ss) })
t.Run("ReactionDelete", func(t *testing.T) { testReactionDelete(t, ss) })
t.Run("ReactionGetForPost", func(t *testing.T) { testReactionGetForPost(t, ss) })
t.Run("ReactionDeleteAllWithEmojiName", func(t *testing.T) { testReactionDeleteAllWithEmojiName(t, ss) })
t.Run("ReactionDeleteAllWithEmojiName", func(t *testing.T) { testReactionDeleteAllWithEmojiName(t, ss, s) })
t.Run("PermanentDeleteBatch", func(t *testing.T) { testReactionStorePermanentDeleteBatch(t, ss) })
t.Run("ReactionBulkGetForPosts", func(t *testing.T) { testReactionBulkGetForPosts(t, ss) })
t.Run("ReactionDeadlock", func(t *testing.T) { testReactionDeadlock(t, ss) })
@@ -48,6 +48,8 @@ func testReactionSave(t *testing.T, ss store.Store) {
assert.Equal(t, saved.UserId, reaction1.UserId, "should've saved reaction user_id and returned it")
assert.Equal(t, saved.PostId, reaction1.PostId, "should've saved reaction post_id and returned it")
assert.Equal(t, saved.EmojiName, reaction1.EmojiName, "should've saved reaction emoji_name and returned it")
assert.NotZero(t, saved.UpdateAt, "should've saved reaction update_at and returned it")
assert.Zero(t, saved.DeleteAt, "should've saved reaction delete_at with zero value and returned it")
var secondUpdateAt int64
postList, err := ss.Post().Get(reaction1.PostId, false, false, false)
@@ -108,39 +110,73 @@ func testReactionSave(t *testing.T, ss store.Store) {
}
func testReactionDelete(t *testing.T, ss store.Store) {
post, err := ss.Post().Save(&model.Post{
ChannelId: model.NewId(),
UserId: model.NewId(),
t.Run("Delete", func(t *testing.T) {
post, err := ss.Post().Save(&model.Post{
ChannelId: model.NewId(),
UserId: model.NewId(),
})
require.Nil(t, err)
reaction := &model.Reaction{
UserId: model.NewId(),
PostId: post.Id,
EmojiName: model.NewId(),
}
_, nErr := ss.Reaction().Save(reaction)
require.Nil(t, nErr)
result, err := ss.Post().Get(reaction.PostId, false, false, false)
require.Nil(t, err)
firstUpdateAt := result.Posts[post.Id].UpdateAt
_, nErr = ss.Reaction().Delete(reaction)
require.Nil(t, nErr)
reactions, rErr := ss.Reaction().GetForPost(post.Id, false)
require.Nil(t, rErr)
assert.Empty(t, reactions, "should've deleted reaction")
postList, err := ss.Post().Get(post.Id, false, false, false)
require.Nil(t, err)
assert.False(t, postList.Posts[post.Id].HasReactions, "should've set HasReactions = false on post")
assert.NotEqual(t, postList.Posts[post.Id].UpdateAt, firstUpdateAt, "should mark post as updated after deleting reactions")
})
require.Nil(t, err)
reaction := &model.Reaction{
UserId: model.NewId(),
PostId: post.Id,
EmojiName: model.NewId(),
}
t.Run("Undelete", func(t *testing.T) {
post, err := ss.Post().Save(&model.Post{
ChannelId: model.NewId(),
UserId: model.NewId(),
})
require.Nil(t, err)
_, nErr := ss.Reaction().Save(reaction)
require.Nil(t, nErr)
reaction := &model.Reaction{
UserId: model.NewId(),
PostId: post.Id,
EmojiName: model.NewId(),
}
result, err := ss.Post().Get(reaction.PostId, false, false, false)
require.Nil(t, err)
savedReaction, nErr := ss.Reaction().Save(reaction)
require.Nil(t, nErr)
firstUpdateAt := result.Posts[post.Id].UpdateAt
updateAt := savedReaction.UpdateAt
_, nErr = ss.Reaction().Delete(reaction)
require.Nil(t, nErr)
_, nErr = ss.Reaction().Delete(savedReaction)
require.Nil(t, nErr)
reactions, rErr := ss.Reaction().GetForPost(post.Id, false)
require.Nil(t, rErr)
// add same reaction back and ensure update_at is set
_, nErr = ss.Reaction().Save(savedReaction)
require.Nil(t, nErr)
assert.Empty(t, reactions, "should've deleted reaction")
reactions, err := ss.Reaction().GetForPost(post.Id, false)
require.Nil(t, err)
postList, err := ss.Post().Get(post.Id, false, false, false)
require.Nil(t, err)
assert.False(t, postList.Posts[post.Id].HasReactions, "should've set HasReactions = false on post")
assert.NotEqual(t, postList.Posts[post.Id].UpdateAt, firstUpdateAt, "should mark post as updated after deleting reactions")
assert.Len(t, reactions, 1)
assert.GreaterOrEqual(t, reactions[0].UpdateAt, updateAt)
})
}
func testReactionGetForPost(t *testing.T, ss store.Store) {
@@ -176,6 +212,17 @@ func testReactionGetForPost(t *testing.T, ss store.Store) {
require.Nil(t, err)
}
// save and delete an additional reaction to test soft deletion
temp := &model.Reaction{
UserId: userId,
PostId: postId,
EmojiName: "grin",
}
savedTmp, err := ss.Reaction().Save(temp)
require.Nil(t, err)
_, err = ss.Reaction().Delete(savedTmp)
require.Nil(t, err)
returned, err := ss.Reaction().GetForPost(postId, false)
require.Nil(t, err)
require.Len(t, returned, 3, "should've returned 3 reactions")
@@ -185,7 +232,7 @@ func testReactionGetForPost(t *testing.T, ss store.Store) {
for _, returnedReaction := range returned {
if returnedReaction.UserId == reaction.UserId && returnedReaction.PostId == reaction.PostId &&
returnedReaction.EmojiName == reaction.EmojiName {
returnedReaction.EmojiName == reaction.EmojiName && returnedReaction.UpdateAt > 0 {
found = true
break
}
@@ -222,7 +269,7 @@ func testReactionGetForPost(t *testing.T, ss store.Store) {
}
}
func testReactionDeleteAllWithEmojiName(t *testing.T, ss store.Store) {
func testReactionDeleteAllWithEmojiName(t *testing.T, ss store.Store, s SqlStore) {
emojiToDelete := model.NewId()
post, err1 := ss.Post().Save(&model.Post{
@@ -276,7 +323,25 @@ func testReactionDeleteAllWithEmojiName(t *testing.T, ss store.Store) {
require.Nil(t, err)
}
err := ss.Reaction().DeleteAllWithEmojiName(emojiToDelete)
// make at least one Reaction record contain NULL for Update and DeleteAt to simulate post schema upgrade case.
sqlResult, err := s.GetMaster().Exec(`
UPDATE
Reactions
SET
UpdateAt=NULL, DeleteAt=NULL
WHERE
UserId = :UserId AND PostId = :PostId AND EmojiName = :EmojiName`,
map[string]interface{}{
"UserId": userId,
"PostId": post.Id,
"EmojiName": emojiToDelete,
})
require.Nil(t, err)
rowsAffected, err := sqlResult.RowsAffected()
require.Nil(t, err)
require.NotZero(t, rowsAffected)
err = ss.Reaction().DeleteAllWithEmojiName(emojiToDelete)
require.Nil(t, err)
// check that the reactions were deleted