github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+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().InitSystemAdmin()
    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  
   177  func TestGetReactions(t *testing.T) {
   178  	th := Setup().InitBasic().InitSystemAdmin()
   179  	defer th.TearDown()
   180  	Client := th.Client
   181  	userId := th.BasicUser.Id
   182  	user2Id := th.BasicUser2.Id
   183  	postId := th.BasicPost.Id
   184  
   185  	userReactions := []*model.Reaction{
   186  		{
   187  			UserId:    userId,
   188  			PostId:    postId,
   189  			EmojiName: "smile",
   190  		},
   191  		{
   192  			UserId:    userId,
   193  			PostId:    postId,
   194  			EmojiName: "happy",
   195  		},
   196  		{
   197  			UserId:    userId,
   198  			PostId:    postId,
   199  			EmojiName: "sad",
   200  		},
   201  		{
   202  			UserId:    user2Id,
   203  			PostId:    postId,
   204  			EmojiName: "smile",
   205  		},
   206  		{
   207  			UserId:    user2Id,
   208  			PostId:    postId,
   209  			EmojiName: "sad",
   210  		},
   211  	}
   212  
   213  	var reactions []*model.Reaction
   214  
   215  	for _, userReaction := range userReactions {
   216  		if result := <-th.App.Srv.Store.Reaction().Save(userReaction); result.Err != nil {
   217  			t.Fatal(result.Err)
   218  		} else {
   219  			reactions = append(reactions, result.Data.(*model.Reaction))
   220  		}
   221  	}
   222  
   223  	t.Run("get-reactions", func(t *testing.T) {
   224  		rr, resp := Client.GetReactions(postId)
   225  		CheckNoError(t, resp)
   226  
   227  		assert.Len(t, rr, 5)
   228  		for _, r := range reactions {
   229  			assert.Contains(t, reactions, r)
   230  		}
   231  	})
   232  
   233  	t.Run("get-reactions-of-invalid-post-id", func(t *testing.T) {
   234  		rr, resp := Client.GetReactions("junk")
   235  		CheckBadRequestStatus(t, resp)
   236  
   237  		assert.Empty(t, rr)
   238  	})
   239  
   240  	t.Run("get-reactions-of-not-existing-post-id", func(t *testing.T) {
   241  		_, resp := Client.GetReactions(GenerateTestId())
   242  		CheckForbiddenStatus(t, resp)
   243  	})
   244  
   245  	t.Run("get-reactions-as-anonymous-user", func(t *testing.T) {
   246  		Client.Logout()
   247  
   248  		_, resp := Client.GetReactions(postId)
   249  		CheckUnauthorizedStatus(t, resp)
   250  	})
   251  
   252  	t.Run("get-reactions-as-system-admin", func(t *testing.T) {
   253  		_, resp := th.SystemAdminClient.GetReactions(postId)
   254  		CheckNoError(t, resp)
   255  	})
   256  }
   257  
   258  func TestDeleteReaction(t *testing.T) {
   259  	th := Setup().InitBasic().InitSystemAdmin()
   260  	defer th.TearDown()
   261  	Client := th.Client
   262  	userId := th.BasicUser.Id
   263  	user2Id := th.BasicUser2.Id
   264  	postId := th.BasicPost.Id
   265  
   266  	r1 := &model.Reaction{
   267  		UserId:    userId,
   268  		PostId:    postId,
   269  		EmojiName: "smile",
   270  	}
   271  
   272  	r2 := &model.Reaction{
   273  		UserId:    userId,
   274  		PostId:    postId,
   275  		EmojiName: "smile-",
   276  	}
   277  
   278  	r3 := &model.Reaction{
   279  		UserId:    userId,
   280  		PostId:    postId,
   281  		EmojiName: "+1",
   282  	}
   283  
   284  	r4 := &model.Reaction{
   285  		UserId:    user2Id,
   286  		PostId:    postId,
   287  		EmojiName: "smile_",
   288  	}
   289  
   290  	// Check the appropriate permissions are enforced.
   291  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   292  	defer func() {
   293  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   294  	}()
   295  
   296  	t.Run("delete-reaction", func(t *testing.T) {
   297  		th.App.SaveReactionForPost(r1)
   298  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
   299  			t.Fatal("didn't save reaction correctly")
   300  		}
   301  
   302  		ok, resp := Client.DeleteReaction(r1)
   303  		CheckNoError(t, resp)
   304  
   305  		if !ok {
   306  			t.Fatal("should have returned true")
   307  		}
   308  
   309  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 0 {
   310  			t.Fatal("should have deleted reaction")
   311  		}
   312  	})
   313  
   314  	t.Run("delete-reaction-when-post-has-multiple-reactions", func(t *testing.T) {
   315  		th.App.SaveReactionForPost(r1)
   316  		th.App.SaveReactionForPost(r2)
   317  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
   318  			t.Fatal("didn't save reactions correctly")
   319  		}
   320  
   321  		_, resp := Client.DeleteReaction(r2)
   322  		CheckNoError(t, resp)
   323  
   324  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 || *reactions[0] != *r1 {
   325  			t.Fatal("should have deleted 1 reaction only")
   326  		}
   327  	})
   328  
   329  	t.Run("delete-reaction-when-plus-one-reaction-name", func(t *testing.T) {
   330  		th.App.SaveReactionForPost(r3)
   331  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
   332  			t.Fatal("didn't save reactions correctly")
   333  		}
   334  
   335  		_, resp := Client.DeleteReaction(r3)
   336  		CheckNoError(t, resp)
   337  
   338  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 || *reactions[0] != *r1 {
   339  			t.Fatal("should have deleted 1 reaction only")
   340  		}
   341  	})
   342  
   343  	t.Run("delete-reaction-made-by-another-user", func(t *testing.T) {
   344  		th.LoginBasic2()
   345  		th.App.SaveReactionForPost(r4)
   346  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
   347  			t.Fatal("didn't save reaction correctly")
   348  		}
   349  
   350  		th.LoginBasic()
   351  
   352  		ok, resp := Client.DeleteReaction(r4)
   353  		CheckForbiddenStatus(t, resp)
   354  
   355  		if ok {
   356  			t.Fatal("should have returned false")
   357  		}
   358  
   359  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
   360  			t.Fatal("should have not deleted a reaction")
   361  		}
   362  	})
   363  
   364  	t.Run("delete-reaction-from-not-existing-post-id", func(t *testing.T) {
   365  		r1.PostId = GenerateTestId()
   366  		_, resp := Client.DeleteReaction(r1)
   367  		CheckForbiddenStatus(t, resp)
   368  	})
   369  
   370  	t.Run("delete-reaction-from-not-valid-post-id", func(t *testing.T) {
   371  		r1.PostId = "junk"
   372  
   373  		_, resp := Client.DeleteReaction(r1)
   374  		CheckBadRequestStatus(t, resp)
   375  	})
   376  
   377  	t.Run("delete-reaction-from-not-existing-user-id", func(t *testing.T) {
   378  		r1.PostId = postId
   379  		r1.UserId = GenerateTestId()
   380  
   381  		_, resp := Client.DeleteReaction(r1)
   382  		CheckForbiddenStatus(t, resp)
   383  	})
   384  
   385  	t.Run("delete-reaction-from-not-valid-user-id", func(t *testing.T) {
   386  		r1.UserId = "junk"
   387  
   388  		_, resp := Client.DeleteReaction(r1)
   389  		CheckBadRequestStatus(t, resp)
   390  	})
   391  
   392  	t.Run("delete-reaction-with-empty-name", func(t *testing.T) {
   393  		r1.UserId = userId
   394  		r1.EmojiName = ""
   395  
   396  		_, resp := Client.DeleteReaction(r1)
   397  		CheckNotFoundStatus(t, resp)
   398  	})
   399  
   400  	t.Run("delete-reaction-with-not-existing-name", func(t *testing.T) {
   401  		r1.EmojiName = strings.Repeat("a", 65)
   402  
   403  		_, resp := Client.DeleteReaction(r1)
   404  		CheckBadRequestStatus(t, resp)
   405  	})
   406  
   407  	t.Run("delete-reaction-as-anonymous-user", func(t *testing.T) {
   408  		Client.Logout()
   409  		r1.EmojiName = "smile"
   410  
   411  		_, resp := Client.DeleteReaction(r1)
   412  		CheckUnauthorizedStatus(t, resp)
   413  	})
   414  
   415  	t.Run("delete-reaction-as-system-admin", func(t *testing.T) {
   416  		_, resp := th.SystemAdminClient.DeleteReaction(r1)
   417  		CheckNoError(t, resp)
   418  
   419  		_, resp = th.SystemAdminClient.DeleteReaction(r4)
   420  		CheckNoError(t, resp)
   421  
   422  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 0 {
   423  			t.Fatal("should have deleted both reactions")
   424  		}
   425  	})
   426  
   427  	t.Run("unable-to-delete-reaction-without-permissions", func(t *testing.T) {
   428  		th.LoginBasic()
   429  
   430  		th.RemovePermissionFromRole(model.PERMISSION_REMOVE_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
   431  		th.App.SaveReactionForPost(r1)
   432  
   433  		_, resp := Client.DeleteReaction(r1)
   434  		CheckForbiddenStatus(t, resp)
   435  
   436  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
   437  			t.Fatal("should have not deleted a reactions")
   438  		}
   439  		th.AddPermissionToRole(model.PERMISSION_REMOVE_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
   440  	})
   441  
   442  	t.Run("unable-to-delete-others-reactions-without-permissions", func(t *testing.T) {
   443  		th.RemovePermissionFromRole(model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id, model.SYSTEM_ADMIN_ROLE_ID)
   444  		th.App.SaveReactionForPost(r1)
   445  
   446  		_, resp := th.SystemAdminClient.DeleteReaction(r1)
   447  		CheckForbiddenStatus(t, resp)
   448  
   449  		if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
   450  			t.Fatal("should have not deleted a reactions")
   451  		}
   452  		th.AddPermissionToRole(model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id, model.SYSTEM_ADMIN_ROLE_ID)
   453  	})
   454  }