github.com/mad-app/mattermost-server@v5.11.1+incompatible/api4/reaction_test.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	"github.com/mattermost/mattermost-server/model"
    13  )
    14  
    15  func TestSaveReaction(t *testing.T) {
    16  	th := Setup().InitBasic()
    17  	defer th.TearDown()
    18  	Client := th.Client
    19  	userId := th.BasicUser.Id
    20  	postId := th.BasicPost.Id
    21  
    22  	// Check the appropriate permissions are enforced.
    23  	defaultRolePermissions := th.SaveDefaultRolePermissions()
    24  	defer func() {
    25  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
    26  	}()
    27  
    28  	reaction := &model.Reaction{
    29  		UserId:    userId,
    30  		PostId:    postId,
    31  		EmojiName: "smile",
    32  	}
    33  
    34  	t.Run("successful-reaction", func(t *testing.T) {
    35  		rr, resp := Client.SaveReaction(reaction)
    36  		CheckNoError(t, resp)
    37  
    38  		if rr.UserId != reaction.UserId {
    39  			t.Fatal("UserId did not match")
    40  		}
    41  
    42  		if rr.PostId != reaction.PostId {
    43  			t.Fatal("PostId did not match")
    44  		}
    45  
    46  		if rr.EmojiName != reaction.EmojiName {
    47  			t.Fatal("EmojiName did not match")
    48  		}
    49  
    50  		if rr.CreateAt == 0 {
    51  			t.Fatal("CreateAt should exist")
    52  		}
    53  
    54  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 1 {
    55  			t.Fatal("didn't save reaction correctly")
    56  		}
    57  	})
    58  
    59  	t.Run("duplicated-reaction", func(t *testing.T) {
    60  		_, resp := Client.SaveReaction(reaction)
    61  		CheckNoError(t, resp)
    62  
    63  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 1 {
    64  			t.Fatal("should have not save duplicated reaction")
    65  		}
    66  	})
    67  
    68  	t.Run("save-second-reaction", func(t *testing.T) {
    69  		reaction.EmojiName = "sad"
    70  
    71  		rr, resp := Client.SaveReaction(reaction)
    72  		CheckNoError(t, resp)
    73  
    74  		if rr.EmojiName != reaction.EmojiName {
    75  			t.Fatal("EmojiName did not match")
    76  		}
    77  
    78  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 2 {
    79  			t.Fatal("should have save multiple reactions")
    80  		}
    81  	})
    82  
    83  	t.Run("saving-special-case", func(t *testing.T) {
    84  		reaction.EmojiName = "+1"
    85  
    86  		rr, resp := Client.SaveReaction(reaction)
    87  		CheckNoError(t, resp)
    88  
    89  		if rr.EmojiName != reaction.EmojiName {
    90  			t.Fatal("EmojiName did not match")
    91  		}
    92  
    93  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 3 {
    94  			t.Fatal("should have save multiple reactions")
    95  		}
    96  	})
    97  
    98  	t.Run("react-to-not-existing-post-id", func(t *testing.T) {
    99  		reaction.PostId = GenerateTestId()
   100  
   101  		_, resp := Client.SaveReaction(reaction)
   102  		CheckForbiddenStatus(t, resp)
   103  	})
   104  
   105  	t.Run("react-to-not-valid-post-id", func(t *testing.T) {
   106  		reaction.PostId = "junk"
   107  
   108  		_, resp := Client.SaveReaction(reaction)
   109  		CheckBadRequestStatus(t, resp)
   110  	})
   111  
   112  	t.Run("react-as-not-existing-user-id", func(t *testing.T) {
   113  		reaction.PostId = postId
   114  		reaction.UserId = GenerateTestId()
   115  
   116  		_, resp := Client.SaveReaction(reaction)
   117  		CheckForbiddenStatus(t, resp)
   118  	})
   119  
   120  	t.Run("react-as-not-valid-user-id", func(t *testing.T) {
   121  		reaction.UserId = "junk"
   122  
   123  		_, resp := Client.SaveReaction(reaction)
   124  		CheckBadRequestStatus(t, resp)
   125  	})
   126  
   127  	t.Run("react-as-empty-emoji-name", func(t *testing.T) {
   128  		reaction.UserId = userId
   129  		reaction.EmojiName = ""
   130  
   131  		_, resp := Client.SaveReaction(reaction)
   132  		CheckBadRequestStatus(t, resp)
   133  	})
   134  
   135  	t.Run("react-as-not-valid-emoji-name", func(t *testing.T) {
   136  		reaction.EmojiName = strings.Repeat("a", 65)
   137  
   138  		_, resp := Client.SaveReaction(reaction)
   139  		CheckBadRequestStatus(t, resp)
   140  	})
   141  
   142  	t.Run("react-as-other-user", func(t *testing.T) {
   143  		reaction.EmojiName = "smile"
   144  		otherUser := th.CreateUser()
   145  		Client.Logout()
   146  		Client.Login(otherUser.Email, otherUser.Password)
   147  
   148  		_, resp := Client.SaveReaction(reaction)
   149  		CheckForbiddenStatus(t, resp)
   150  	})
   151  
   152  	t.Run("react-being-not-logged-in", func(t *testing.T) {
   153  		Client.Logout()
   154  		_, resp := Client.SaveReaction(reaction)
   155  		CheckUnauthorizedStatus(t, resp)
   156  	})
   157  
   158  	t.Run("react-as-other-user-being-system-admin", func(t *testing.T) {
   159  		_, resp := th.SystemAdminClient.SaveReaction(reaction)
   160  		CheckForbiddenStatus(t, resp)
   161  	})
   162  
   163  	t.Run("unable-to-create-reaction-without-permissions", func(t *testing.T) {
   164  		th.LoginBasic()
   165  
   166  		th.RemovePermissionFromRole(model.PERMISSION_ADD_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
   167  		_, resp := Client.SaveReaction(reaction)
   168  		CheckForbiddenStatus(t, resp)
   169  
   170  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 3 {
   171  			t.Fatal("should have not created a reactions")
   172  		}
   173  		th.AddPermissionToRole(model.PERMISSION_ADD_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
   174  	})
   175  
   176  	t.Run("unable-to-react-in-read-only-town-square", func(t *testing.T) {
   177  		th.LoginBasic()
   178  
   179  		channel, err := th.App.GetChannelByName("town-square", th.BasicTeam.Id, true)
   180  		assert.Nil(t, err)
   181  		post := th.CreatePostWithClient(th.Client, channel)
   182  
   183  		th.App.SetLicense(model.NewTestLicense())
   184  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true })
   185  
   186  		reaction := &model.Reaction{
   187  			UserId:    userId,
   188  			PostId:    post.Id,
   189  			EmojiName: "smile",
   190  		}
   191  
   192  		_, resp := Client.SaveReaction(reaction)
   193  		CheckForbiddenStatus(t, resp)
   194  
   195  		if reactions, err := th.App.GetReactionsForPost(post.Id); err != nil || len(reactions) != 0 {
   196  			t.Fatal("should have not created a reaction")
   197  		}
   198  
   199  		th.App.RemoveLicense()
   200  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = false })
   201  	})
   202  
   203  	t.Run("unable-to-react-in-an-archived-channel", func(t *testing.T) {
   204  		th.LoginBasic()
   205  
   206  		channel := th.CreatePublicChannel()
   207  		post := th.CreatePostWithClient(th.Client, channel)
   208  
   209  		reaction := &model.Reaction{
   210  			UserId:    userId,
   211  			PostId:    post.Id,
   212  			EmojiName: "smile",
   213  		}
   214  
   215  		err := th.App.DeleteChannel(channel, userId)
   216  		assert.Nil(t, err)
   217  
   218  		_, resp := Client.SaveReaction(reaction)
   219  		CheckForbiddenStatus(t, resp)
   220  
   221  		if reactions, err := th.App.GetReactionsForPost(post.Id); err != nil || len(reactions) != 0 {
   222  			t.Fatal("should have not created a reaction")
   223  		}
   224  	})
   225  }
   226  
   227  func TestGetReactions(t *testing.T) {
   228  	th := Setup().InitBasic()
   229  	defer th.TearDown()
   230  	Client := th.Client
   231  	userId := th.BasicUser.Id
   232  	user2Id := th.BasicUser2.Id
   233  	postId := th.BasicPost.Id
   234  
   235  	userReactions := []*model.Reaction{
   236  		{
   237  			UserId:    userId,
   238  			PostId:    postId,
   239  			EmojiName: "smile",
   240  		},
   241  		{
   242  			UserId:    userId,
   243  			PostId:    postId,
   244  			EmojiName: "happy",
   245  		},
   246  		{
   247  			UserId:    userId,
   248  			PostId:    postId,
   249  			EmojiName: "sad",
   250  		},
   251  		{
   252  			UserId:    user2Id,
   253  			PostId:    postId,
   254  			EmojiName: "smile",
   255  		},
   256  		{
   257  			UserId:    user2Id,
   258  			PostId:    postId,
   259  			EmojiName: "sad",
   260  		},
   261  	}
   262  
   263  	var reactions []*model.Reaction
   264  
   265  	for _, userReaction := range userReactions {
   266  		if result := <-th.App.Srv.Store.Reaction().Save(userReaction); result.Err != nil {
   267  			t.Fatal(result.Err)
   268  		} else {
   269  			reactions = append(reactions, result.Data.(*model.Reaction))
   270  		}
   271  	}
   272  
   273  	t.Run("get-reactions", func(t *testing.T) {
   274  		rr, resp := Client.GetReactions(postId)
   275  		CheckNoError(t, resp)
   276  
   277  		assert.Len(t, rr, 5)
   278  		for _, r := range reactions {
   279  			assert.Contains(t, reactions, r)
   280  		}
   281  	})
   282  
   283  	t.Run("get-reactions-of-invalid-post-id", func(t *testing.T) {
   284  		rr, resp := Client.GetReactions("junk")
   285  		CheckBadRequestStatus(t, resp)
   286  
   287  		assert.Empty(t, rr)
   288  	})
   289  
   290  	t.Run("get-reactions-of-not-existing-post-id", func(t *testing.T) {
   291  		_, resp := Client.GetReactions(GenerateTestId())
   292  		CheckForbiddenStatus(t, resp)
   293  	})
   294  
   295  	t.Run("get-reactions-as-anonymous-user", func(t *testing.T) {
   296  		Client.Logout()
   297  
   298  		_, resp := Client.GetReactions(postId)
   299  		CheckUnauthorizedStatus(t, resp)
   300  	})
   301  
   302  	t.Run("get-reactions-as-system-admin", func(t *testing.T) {
   303  		_, resp := th.SystemAdminClient.GetReactions(postId)
   304  		CheckNoError(t, resp)
   305  	})
   306  }
   307  
   308  func TestDeleteReaction(t *testing.T) {
   309  	th := Setup().InitBasic()
   310  	defer th.TearDown()
   311  	Client := th.Client
   312  	userId := th.BasicUser.Id
   313  	user2Id := th.BasicUser2.Id
   314  	postId := th.BasicPost.Id
   315  
   316  	r1 := &model.Reaction{
   317  		UserId:    userId,
   318  		PostId:    postId,
   319  		EmojiName: "smile",
   320  	}
   321  
   322  	r2 := &model.Reaction{
   323  		UserId:    userId,
   324  		PostId:    postId,
   325  		EmojiName: "smile-",
   326  	}
   327  
   328  	r3 := &model.Reaction{
   329  		UserId:    userId,
   330  		PostId:    postId,
   331  		EmojiName: "+1",
   332  	}
   333  
   334  	r4 := &model.Reaction{
   335  		UserId:    user2Id,
   336  		PostId:    postId,
   337  		EmojiName: "smile_",
   338  	}
   339  
   340  	// Check the appropriate permissions are enforced.
   341  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   342  	defer func() {
   343  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   344  	}()
   345  
   346  	t.Run("delete-reaction", func(t *testing.T) {
   347  		th.App.SaveReactionForPost(r1)
   348  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
   349  			t.Fatal("didn't save reaction correctly")
   350  		}
   351  
   352  		ok, resp := Client.DeleteReaction(r1)
   353  		CheckNoError(t, resp)
   354  
   355  		if !ok {
   356  			t.Fatal("should have returned true")
   357  		}
   358  
   359  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 0 {
   360  			t.Fatal("should have deleted reaction")
   361  		}
   362  	})
   363  
   364  	t.Run("delete-reaction-when-post-has-multiple-reactions", func(t *testing.T) {
   365  		th.App.SaveReactionForPost(r1)
   366  		th.App.SaveReactionForPost(r2)
   367  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
   368  			t.Fatal("didn't save reactions correctly")
   369  		}
   370  
   371  		_, resp := Client.DeleteReaction(r2)
   372  		CheckNoError(t, resp)
   373  
   374  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 || *reactions[0] != *r1 {
   375  			t.Fatal("should have deleted 1 reaction only")
   376  		}
   377  	})
   378  
   379  	t.Run("delete-reaction-when-plus-one-reaction-name", func(t *testing.T) {
   380  		th.App.SaveReactionForPost(r3)
   381  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
   382  			t.Fatal("didn't save reactions correctly")
   383  		}
   384  
   385  		_, resp := Client.DeleteReaction(r3)
   386  		CheckNoError(t, resp)
   387  
   388  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 || *reactions[0] != *r1 {
   389  			t.Fatal("should have deleted 1 reaction only")
   390  		}
   391  	})
   392  
   393  	t.Run("delete-reaction-made-by-another-user", func(t *testing.T) {
   394  		th.LoginBasic2()
   395  		th.App.SaveReactionForPost(r4)
   396  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
   397  			t.Fatal("didn't save reaction correctly")
   398  		}
   399  
   400  		th.LoginBasic()
   401  
   402  		ok, resp := Client.DeleteReaction(r4)
   403  		CheckForbiddenStatus(t, resp)
   404  
   405  		if ok {
   406  			t.Fatal("should have returned false")
   407  		}
   408  
   409  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
   410  			t.Fatal("should have not deleted a reaction")
   411  		}
   412  	})
   413  
   414  	t.Run("delete-reaction-from-not-existing-post-id", func(t *testing.T) {
   415  		r1.PostId = GenerateTestId()
   416  		_, resp := Client.DeleteReaction(r1)
   417  		CheckForbiddenStatus(t, resp)
   418  	})
   419  
   420  	t.Run("delete-reaction-from-not-valid-post-id", func(t *testing.T) {
   421  		r1.PostId = "junk"
   422  
   423  		_, resp := Client.DeleteReaction(r1)
   424  		CheckBadRequestStatus(t, resp)
   425  	})
   426  
   427  	t.Run("delete-reaction-from-not-existing-user-id", func(t *testing.T) {
   428  		r1.PostId = postId
   429  		r1.UserId = GenerateTestId()
   430  
   431  		_, resp := Client.DeleteReaction(r1)
   432  		CheckForbiddenStatus(t, resp)
   433  	})
   434  
   435  	t.Run("delete-reaction-from-not-valid-user-id", func(t *testing.T) {
   436  		r1.UserId = "junk"
   437  
   438  		_, resp := Client.DeleteReaction(r1)
   439  		CheckBadRequestStatus(t, resp)
   440  	})
   441  
   442  	t.Run("delete-reaction-with-empty-name", func(t *testing.T) {
   443  		r1.UserId = userId
   444  		r1.EmojiName = ""
   445  
   446  		_, resp := Client.DeleteReaction(r1)
   447  		CheckNotFoundStatus(t, resp)
   448  	})
   449  
   450  	t.Run("delete-reaction-with-not-existing-name", func(t *testing.T) {
   451  		r1.EmojiName = strings.Repeat("a", 65)
   452  
   453  		_, resp := Client.DeleteReaction(r1)
   454  		CheckBadRequestStatus(t, resp)
   455  	})
   456  
   457  	t.Run("delete-reaction-as-anonymous-user", func(t *testing.T) {
   458  		Client.Logout()
   459  		r1.EmojiName = "smile"
   460  
   461  		_, resp := Client.DeleteReaction(r1)
   462  		CheckUnauthorizedStatus(t, resp)
   463  	})
   464  
   465  	t.Run("delete-reaction-as-system-admin", func(t *testing.T) {
   466  		_, resp := th.SystemAdminClient.DeleteReaction(r1)
   467  		CheckNoError(t, resp)
   468  
   469  		_, resp = th.SystemAdminClient.DeleteReaction(r4)
   470  		CheckNoError(t, resp)
   471  
   472  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 0 {
   473  			t.Fatal("should have deleted both reactions")
   474  		}
   475  	})
   476  
   477  	t.Run("unable-to-delete-reaction-without-permissions", func(t *testing.T) {
   478  		th.LoginBasic()
   479  
   480  		th.RemovePermissionFromRole(model.PERMISSION_REMOVE_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
   481  		th.App.SaveReactionForPost(r1)
   482  
   483  		_, resp := Client.DeleteReaction(r1)
   484  		CheckForbiddenStatus(t, resp)
   485  
   486  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
   487  			t.Fatal("should have not deleted a reactions")
   488  		}
   489  		th.AddPermissionToRole(model.PERMISSION_REMOVE_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
   490  	})
   491  
   492  	t.Run("unable-to-delete-others-reactions-without-permissions", func(t *testing.T) {
   493  		th.RemovePermissionFromRole(model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id, model.SYSTEM_ADMIN_ROLE_ID)
   494  		th.App.SaveReactionForPost(r1)
   495  
   496  		_, resp := th.SystemAdminClient.DeleteReaction(r1)
   497  		CheckForbiddenStatus(t, resp)
   498  
   499  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
   500  			t.Fatal("should have not deleted a reactions")
   501  		}
   502  		th.AddPermissionToRole(model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id, model.SYSTEM_ADMIN_ROLE_ID)
   503  	})
   504  
   505  	t.Run("unable-to-delete-reactions-in-read-only-town-square", func(t *testing.T) {
   506  		th.LoginBasic()
   507  
   508  		channel, err := th.App.GetChannelByName("town-square", th.BasicTeam.Id, true)
   509  		assert.Nil(t, err)
   510  		post := th.CreatePostWithClient(th.Client, channel)
   511  
   512  		th.App.SetLicense(model.NewTestLicense())
   513  
   514  		reaction := &model.Reaction{
   515  			UserId:    userId,
   516  			PostId:    post.Id,
   517  			EmojiName: "smile",
   518  		}
   519  
   520  		r1, resp := Client.SaveReaction(reaction)
   521  		CheckNoError(t, resp)
   522  
   523  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
   524  			t.Fatal("should have created a reaction")
   525  		}
   526  
   527  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true })
   528  
   529  		_, resp = th.SystemAdminClient.DeleteReaction(r1)
   530  		CheckForbiddenStatus(t, resp)
   531  
   532  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
   533  			t.Fatal("should have not deleted a reaction")
   534  		}
   535  
   536  		th.App.RemoveLicense()
   537  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = false })
   538  	})
   539  
   540  	t.Run("unable-to-delete-reactions-in-an-archived-channel", func(t *testing.T) {
   541  		th.LoginBasic()
   542  
   543  		channel := th.CreatePublicChannel()
   544  		post := th.CreatePostWithClient(th.Client, channel)
   545  
   546  		reaction := &model.Reaction{
   547  			UserId:    userId,
   548  			PostId:    post.Id,
   549  			EmojiName: "smile",
   550  		}
   551  
   552  		r1, resp := Client.SaveReaction(reaction)
   553  		CheckNoError(t, resp)
   554  
   555  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
   556  			t.Fatal("should have created a reaction")
   557  		}
   558  
   559  		err := th.App.DeleteChannel(channel, userId)
   560  		assert.Nil(t, err)
   561  
   562  		_, resp = Client.SaveReaction(r1)
   563  		CheckForbiddenStatus(t, resp)
   564  
   565  		if reactions, err := th.App.GetReactionsForPost(post.Id); err != nil || len(reactions) != 1 {
   566  			t.Fatal("should have not deleted a reaction")
   567  		}
   568  	})
   569  }
   570  
   571  func TestGetBulkReactions(t *testing.T) {
   572  	th := Setup().InitBasic()
   573  	defer th.TearDown()
   574  	Client := th.Client
   575  	userId := th.BasicUser.Id
   576  	user2Id := th.BasicUser2.Id
   577  	post1 := &model.Post{UserId: userId, ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a"}
   578  	post2 := &model.Post{UserId: userId, ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a"}
   579  	post3 := &model.Post{UserId: userId, ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a"}
   580  
   581  	post4 := &model.Post{UserId: user2Id, ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a"}
   582  	post5 := &model.Post{UserId: user2Id, ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a"}
   583  
   584  	post1, _ = Client.CreatePost(post1)
   585  	post2, _ = Client.CreatePost(post2)
   586  	post3, _ = Client.CreatePost(post3)
   587  	post4, _ = Client.CreatePost(post4)
   588  	post5, _ = Client.CreatePost(post5)
   589  
   590  	expectedPostIdsReactionsMap := make(map[string][]*model.Reaction)
   591  	expectedPostIdsReactionsMap[post1.Id] = []*model.Reaction{}
   592  	expectedPostIdsReactionsMap[post2.Id] = []*model.Reaction{}
   593  	expectedPostIdsReactionsMap[post3.Id] = []*model.Reaction{}
   594  	expectedPostIdsReactionsMap[post5.Id] = []*model.Reaction{}
   595  
   596  	userReactions := []*model.Reaction{
   597  		{
   598  			UserId:    userId,
   599  			PostId:    post1.Id,
   600  			EmojiName: "happy",
   601  		},
   602  		{
   603  			UserId:    userId,
   604  			PostId:    post1.Id,
   605  			EmojiName: "sad",
   606  		},
   607  		{
   608  			UserId:    userId,
   609  			PostId:    post2.Id,
   610  			EmojiName: "smile",
   611  		},
   612  		{
   613  			UserId:    user2Id,
   614  			PostId:    post4.Id,
   615  			EmojiName: "smile",
   616  		},
   617  	}
   618  
   619  	for _, userReaction := range userReactions {
   620  		reactions := expectedPostIdsReactionsMap[userReaction.PostId]
   621  		if result := <-th.App.Srv.Store.Reaction().Save(userReaction); result.Err != nil {
   622  			t.Fatal(result.Err)
   623  		} else {
   624  			reactions = append(reactions, result.Data.(*model.Reaction))
   625  
   626  		}
   627  		expectedPostIdsReactionsMap[userReaction.PostId] = reactions
   628  	}
   629  
   630  	postIds := []string{post1.Id, post2.Id, post3.Id, post4.Id, post5.Id}
   631  
   632  	t.Run("get-reactions", func(t *testing.T) {
   633  		postIdsReactionsMap, resp := Client.GetBulkReactions(postIds)
   634  		CheckNoError(t, resp)
   635  
   636  		assert.ElementsMatch(t, expectedPostIdsReactionsMap[post1.Id], postIdsReactionsMap[post1.Id])
   637  		assert.ElementsMatch(t, expectedPostIdsReactionsMap[post2.Id], postIdsReactionsMap[post2.Id])
   638  		assert.ElementsMatch(t, expectedPostIdsReactionsMap[post3.Id], postIdsReactionsMap[post3.Id])
   639  		assert.ElementsMatch(t, expectedPostIdsReactionsMap[post4.Id], postIdsReactionsMap[post4.Id])
   640  		assert.ElementsMatch(t, expectedPostIdsReactionsMap[post5.Id], postIdsReactionsMap[post5.Id])
   641  		assert.Equal(t, expectedPostIdsReactionsMap, postIdsReactionsMap)
   642  
   643  	})
   644  
   645  	t.Run("get-reactions-as-anonymous-user", func(t *testing.T) {
   646  		Client.Logout()
   647  
   648  		_, resp := Client.GetBulkReactions(postIds)
   649  		CheckUnauthorizedStatus(t, resp)
   650  	})
   651  }