summaryrefslogtreecommitdiffstats
path: root/store/storetest/reaction_store.go
diff options
context:
space:
mode:
authorChris <ccbrown112@gmail.com>2017-10-06 11:08:59 -0700
committerGitHub <noreply@github.com>2017-10-06 11:08:59 -0700
commit70e5f00241473c27a3008959ce08832c75e76ba8 (patch)
tree3afd074964c9220cc4a87210286a13dfd38c61d0 /store/storetest/reaction_store.go
parentd1958bdc49cd10277ca2e27bb2eea499c5994954 (diff)
downloadchat-70e5f00241473c27a3008959ce08832c75e76ba8.tar.gz
chat-70e5f00241473c27a3008959ce08832c75e76ba8.tar.bz2
chat-70e5f00241473c27a3008959ce08832c75e76ba8.zip
store/storetest package (#7588)
* prerequisites * storetest package
Diffstat (limited to 'store/storetest/reaction_store.go')
-rw-r--r--store/storetest/reaction_store.go350
1 files changed, 350 insertions, 0 deletions
diff --git a/store/storetest/reaction_store.go b/store/storetest/reaction_store.go
new file mode 100644
index 000000000..1b5128426
--- /dev/null
+++ b/store/storetest/reaction_store.go
@@ -0,0 +1,350 @@
+// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package storetest
+
+import (
+ "testing"
+
+ "github.com/mattermost/mattermost-server/model"
+ "github.com/mattermost/mattermost-server/store"
+)
+
+func TestReactionStore(t *testing.T, ss store.Store) {
+ 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("PermanentDeleteBatch", func(t *testing.T) { testReactionStorePermanentDeleteBatch(t, ss) })
+}
+
+func testReactionSave(t *testing.T, ss store.Store) {
+ post := store.Must(ss.Post().Save(&model.Post{
+ ChannelId: model.NewId(),
+ UserId: model.NewId(),
+ })).(*model.Post)
+ firstUpdateAt := post.UpdateAt
+
+ reaction1 := &model.Reaction{
+ UserId: model.NewId(),
+ PostId: post.Id,
+ EmojiName: model.NewId(),
+ }
+ if result := <-ss.Reaction().Save(reaction1); result.Err != nil {
+ t.Fatal(result.Err)
+ } else if saved := result.Data.(*model.Reaction); saved.UserId != reaction1.UserId ||
+ saved.PostId != reaction1.PostId || saved.EmojiName != reaction1.EmojiName {
+ t.Fatal("should've saved reaction and returned it")
+ }
+
+ var secondUpdateAt int64
+ if postList := store.Must(ss.Post().Get(reaction1.PostId)).(*model.PostList); !postList.Posts[post.Id].HasReactions {
+ t.Fatal("should've set HasReactions = true on post")
+ } else if postList.Posts[post.Id].UpdateAt == firstUpdateAt {
+ t.Fatal("should've marked post as updated when HasReactions changed")
+ } else {
+ secondUpdateAt = postList.Posts[post.Id].UpdateAt
+ }
+
+ if result := <-ss.Reaction().Save(reaction1); result.Err != nil {
+ t.Log(result.Err)
+ t.Fatal("should've allowed saving a duplicate reaction")
+ }
+
+ // different user
+ reaction2 := &model.Reaction{
+ UserId: model.NewId(),
+ PostId: reaction1.PostId,
+ EmojiName: reaction1.EmojiName,
+ }
+ if result := <-ss.Reaction().Save(reaction2); result.Err != nil {
+ t.Fatal(result.Err)
+ }
+
+ if postList := store.Must(ss.Post().Get(reaction2.PostId)).(*model.PostList); postList.Posts[post.Id].UpdateAt != secondUpdateAt {
+ t.Fatal("shouldn't mark as updated when HasReactions hasn't changed")
+ }
+
+ // different post
+ reaction3 := &model.Reaction{
+ UserId: reaction1.UserId,
+ PostId: model.NewId(),
+ EmojiName: reaction1.EmojiName,
+ }
+ if result := <-ss.Reaction().Save(reaction3); result.Err != nil {
+ t.Fatal(result.Err)
+ }
+
+ // different emoji
+ reaction4 := &model.Reaction{
+ UserId: reaction1.UserId,
+ PostId: reaction1.PostId,
+ EmojiName: model.NewId(),
+ }
+ if result := <-ss.Reaction().Save(reaction4); result.Err != nil {
+ t.Fatal(result.Err)
+ }
+
+ // invalid reaction
+ reaction5 := &model.Reaction{
+ UserId: reaction1.UserId,
+ PostId: reaction1.PostId,
+ }
+ if result := <-ss.Reaction().Save(reaction5); result.Err == nil {
+ t.Fatal("should've failed for invalid reaction")
+ }
+}
+
+func testReactionDelete(t *testing.T, ss store.Store) {
+ post := store.Must(ss.Post().Save(&model.Post{
+ ChannelId: model.NewId(),
+ UserId: model.NewId(),
+ })).(*model.Post)
+
+ reaction := &model.Reaction{
+ UserId: model.NewId(),
+ PostId: post.Id,
+ EmojiName: model.NewId(),
+ }
+
+ store.Must(ss.Reaction().Save(reaction))
+ firstUpdateAt := store.Must(ss.Post().Get(reaction.PostId)).(*model.PostList).Posts[post.Id].UpdateAt
+
+ if result := <-ss.Reaction().Delete(reaction); result.Err != nil {
+ t.Fatal(result.Err)
+ }
+
+ if result := <-ss.Reaction().GetForPost(post.Id, false); result.Err != nil {
+ t.Fatal(result.Err)
+ } else if len(result.Data.([]*model.Reaction)) != 0 {
+ t.Fatal("should've deleted reaction")
+ }
+
+ if postList := store.Must(ss.Post().Get(post.Id)).(*model.PostList); postList.Posts[post.Id].HasReactions {
+ t.Fatal("should've set HasReactions = false on post")
+ } else if postList.Posts[post.Id].UpdateAt == firstUpdateAt {
+ t.Fatal("shouldn't mark as updated when HasReactions has changed after deleting reactions")
+ }
+}
+
+func testReactionGetForPost(t *testing.T, ss store.Store) {
+ postId := model.NewId()
+
+ userId := model.NewId()
+
+ reactions := []*model.Reaction{
+ {
+ UserId: userId,
+ PostId: postId,
+ EmojiName: "smile",
+ },
+ {
+ UserId: model.NewId(),
+ PostId: postId,
+ EmojiName: "smile",
+ },
+ {
+ UserId: userId,
+ PostId: postId,
+ EmojiName: "sad",
+ },
+ {
+ UserId: userId,
+ PostId: model.NewId(),
+ EmojiName: "angry",
+ },
+ }
+
+ for _, reaction := range reactions {
+ store.Must(ss.Reaction().Save(reaction))
+ }
+
+ if result := <-ss.Reaction().GetForPost(postId, false); result.Err != nil {
+ t.Fatal(result.Err)
+ } else if returned := result.Data.([]*model.Reaction); len(returned) != 3 {
+ t.Fatal("should've returned 3 reactions")
+ } else {
+ for _, reaction := range reactions {
+ found := false
+
+ for _, returnedReaction := range returned {
+ if returnedReaction.UserId == reaction.UserId && returnedReaction.PostId == reaction.PostId &&
+ returnedReaction.EmojiName == reaction.EmojiName {
+ found = true
+ break
+ }
+ }
+
+ if !found && reaction.PostId == postId {
+ t.Fatalf("should've returned reaction for post %v", reaction)
+ } else if found && reaction.PostId != postId {
+ t.Fatal("shouldn't have returned reaction for another post")
+ }
+ }
+ }
+
+ // Should return cached item
+ if result := <-ss.Reaction().GetForPost(postId, true); result.Err != nil {
+ t.Fatal(result.Err)
+ } else if returned := result.Data.([]*model.Reaction); len(returned) != 3 {
+ t.Fatal("should've returned 3 reactions")
+ } else {
+ for _, reaction := range reactions {
+ found := false
+
+ for _, returnedReaction := range returned {
+ if returnedReaction.UserId == reaction.UserId && returnedReaction.PostId == reaction.PostId &&
+ returnedReaction.EmojiName == reaction.EmojiName {
+ found = true
+ break
+ }
+ }
+
+ if !found && reaction.PostId == postId {
+ t.Fatalf("should've returned reaction for post %v", reaction)
+ } else if found && reaction.PostId != postId {
+ t.Fatal("shouldn't have returned reaction for another post")
+ }
+ }
+ }
+}
+
+func testReactionDeleteAllWithEmojiName(t *testing.T, ss store.Store) {
+ emojiToDelete := model.NewId()
+
+ post := store.Must(ss.Post().Save(&model.Post{
+ ChannelId: model.NewId(),
+ UserId: model.NewId(),
+ })).(*model.Post)
+ post2 := store.Must(ss.Post().Save(&model.Post{
+ ChannelId: model.NewId(),
+ UserId: model.NewId(),
+ })).(*model.Post)
+ post3 := store.Must(ss.Post().Save(&model.Post{
+ ChannelId: model.NewId(),
+ UserId: model.NewId(),
+ })).(*model.Post)
+
+ userId := model.NewId()
+
+ reactions := []*model.Reaction{
+ {
+ UserId: userId,
+ PostId: post.Id,
+ EmojiName: emojiToDelete,
+ },
+ {
+ UserId: model.NewId(),
+ PostId: post.Id,
+ EmojiName: emojiToDelete,
+ },
+ {
+ UserId: userId,
+ PostId: post.Id,
+ EmojiName: "sad",
+ },
+ {
+ UserId: userId,
+ PostId: post2.Id,
+ EmojiName: "angry",
+ },
+ {
+ UserId: userId,
+ PostId: post3.Id,
+ EmojiName: emojiToDelete,
+ },
+ }
+
+ for _, reaction := range reactions {
+ store.Must(ss.Reaction().Save(reaction))
+ }
+
+ if result := <-ss.Reaction().DeleteAllWithEmojiName(emojiToDelete); result.Err != nil {
+ t.Fatal(result.Err)
+ }
+
+ // check that the reactions were deleted
+ if returned := store.Must(ss.Reaction().GetForPost(post.Id, false)).([]*model.Reaction); len(returned) != 1 {
+ t.Fatal("should've only removed reactions with emoji name")
+ } else {
+ for _, reaction := range returned {
+ if reaction.EmojiName == "smile" {
+ t.Fatal("should've removed reaction with emoji name")
+ }
+ }
+ }
+
+ if returned := store.Must(ss.Reaction().GetForPost(post2.Id, false)).([]*model.Reaction); len(returned) != 1 {
+ t.Fatal("should've only removed reactions with emoji name")
+ }
+
+ if returned := store.Must(ss.Reaction().GetForPost(post3.Id, false)).([]*model.Reaction); len(returned) != 0 {
+ t.Fatal("should've only removed reactions with emoji name")
+ }
+
+ // check that the posts are updated
+ if postList := store.Must(ss.Post().Get(post.Id)).(*model.PostList); !postList.Posts[post.Id].HasReactions {
+ t.Fatal("post should still have reactions")
+ }
+
+ if postList := store.Must(ss.Post().Get(post2.Id)).(*model.PostList); !postList.Posts[post2.Id].HasReactions {
+ t.Fatal("post should still have reactions")
+ }
+
+ if postList := store.Must(ss.Post().Get(post3.Id)).(*model.PostList); postList.Posts[post3.Id].HasReactions {
+ t.Fatal("post shouldn't have reactions any more")
+ }
+}
+
+func testReactionStorePermanentDeleteBatch(t *testing.T, ss store.Store) {
+ post := store.Must(ss.Post().Save(&model.Post{
+ ChannelId: model.NewId(),
+ UserId: model.NewId(),
+ })).(*model.Post)
+
+ reactions := []*model.Reaction{
+ {
+ UserId: model.NewId(),
+ PostId: post.Id,
+ EmojiName: "sad",
+ CreateAt: 1000,
+ },
+ {
+ UserId: model.NewId(),
+ PostId: post.Id,
+ EmojiName: "sad",
+ CreateAt: 1500,
+ },
+ {
+ UserId: model.NewId(),
+ PostId: post.Id,
+ EmojiName: "sad",
+ CreateAt: 2000,
+ },
+ {
+ UserId: model.NewId(),
+ PostId: post.Id,
+ EmojiName: "sad",
+ CreateAt: 2000,
+ },
+ }
+
+ // Need to hang on to a reaction to delete later in order to clear the cache, as "allowFromCache" isn't honoured any more.
+ var lastReaction *model.Reaction
+ for _, reaction := range reactions {
+ lastReaction = store.Must(ss.Reaction().Save(reaction)).(*model.Reaction)
+ }
+
+ if returned := store.Must(ss.Reaction().GetForPost(post.Id, false)).([]*model.Reaction); len(returned) != 4 {
+ t.Fatal("expected 4 reactions")
+ }
+
+ store.Must(ss.Reaction().PermanentDeleteBatch(1800, 1000))
+
+ // This is to force a clear of the cache.
+ store.Must(ss.Reaction().Delete(lastReaction))
+
+ if returned := store.Must(ss.Reaction().GetForPost(post.Id, false)).([]*model.Reaction); len(returned) != 1 {
+ t.Fatalf("expected 1 reaction. Got: %v", len(returned))
+ }
+}