github.com/coincircle/mattermost-server@v4.8.1-0.20180321182714-9d701c704416+incompatible/api4/webhook_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  	"bytes"
     8  	"net/http"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  
    13  	"github.com/mattermost/mattermost-server/model"
    14  )
    15  
    16  func TestCreateIncomingWebhook(t *testing.T) {
    17  	th := Setup().InitBasic().InitSystemAdmin()
    18  	defer th.TearDown()
    19  	Client := th.Client
    20  
    21  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
    22  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
    23  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = true })
    24  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = true })
    25  
    26  	hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
    27  
    28  	rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
    29  	CheckNoError(t, resp)
    30  
    31  	if rhook.ChannelId != hook.ChannelId {
    32  		t.Fatal("channel ids didn't match")
    33  	}
    34  
    35  	if rhook.UserId != th.SystemAdminUser.Id {
    36  		t.Fatal("user ids didn't match")
    37  	}
    38  
    39  	if rhook.TeamId != th.BasicTeam.Id {
    40  		t.Fatal("team ids didn't match")
    41  	}
    42  
    43  	hook.ChannelId = "junk"
    44  	_, resp = th.SystemAdminClient.CreateIncomingWebhook(hook)
    45  	CheckNotFoundStatus(t, resp)
    46  
    47  	hook.ChannelId = th.BasicChannel.Id
    48  	th.LoginTeamAdmin()
    49  	_, resp = Client.CreateIncomingWebhook(hook)
    50  	CheckNoError(t, resp)
    51  
    52  	th.LoginBasic()
    53  	_, resp = Client.CreateIncomingWebhook(hook)
    54  	CheckForbiddenStatus(t, resp)
    55  
    56  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
    57  
    58  	_, resp = Client.CreateIncomingWebhook(hook)
    59  	CheckNoError(t, resp)
    60  
    61  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = false })
    62  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = false })
    63  
    64  	_, resp = Client.CreateIncomingWebhook(hook)
    65  	CheckNoError(t, resp)
    66  
    67  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false })
    68  	_, resp = Client.CreateIncomingWebhook(hook)
    69  	CheckNotImplementedStatus(t, resp)
    70  }
    71  
    72  func TestGetIncomingWebhooks(t *testing.T) {
    73  	th := Setup().InitBasic().InitSystemAdmin()
    74  	defer th.TearDown()
    75  	Client := th.Client
    76  
    77  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
    78  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
    79  
    80  	hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
    81  	rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
    82  	CheckNoError(t, resp)
    83  
    84  	hooks, resp := th.SystemAdminClient.GetIncomingWebhooks(0, 1000, "")
    85  	CheckNoError(t, resp)
    86  
    87  	found := false
    88  	for _, h := range hooks {
    89  		if rhook.Id == h.Id {
    90  			found = true
    91  		}
    92  	}
    93  
    94  	if !found {
    95  		t.Fatal("missing hook")
    96  	}
    97  
    98  	hooks, resp = th.SystemAdminClient.GetIncomingWebhooks(0, 1, "")
    99  	CheckNoError(t, resp)
   100  
   101  	if len(hooks) != 1 {
   102  		t.Fatal("should only be 1")
   103  	}
   104  
   105  	hooks, resp = th.SystemAdminClient.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   106  	CheckNoError(t, resp)
   107  
   108  	found = false
   109  	for _, h := range hooks {
   110  		if rhook.Id == h.Id {
   111  			found = true
   112  		}
   113  	}
   114  
   115  	if !found {
   116  		t.Fatal("missing hook")
   117  	}
   118  
   119  	hooks, resp = th.SystemAdminClient.GetIncomingWebhooksForTeam(model.NewId(), 0, 1000, "")
   120  	CheckNoError(t, resp)
   121  
   122  	if len(hooks) != 0 {
   123  		t.Fatal("no hooks should be returned")
   124  	}
   125  
   126  	_, resp = Client.GetIncomingWebhooks(0, 1000, "")
   127  	CheckForbiddenStatus(t, resp)
   128  
   129  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   130  
   131  	_, resp = Client.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   132  	CheckNoError(t, resp)
   133  
   134  	_, resp = Client.GetIncomingWebhooksForTeam(model.NewId(), 0, 1000, "")
   135  	CheckForbiddenStatus(t, resp)
   136  
   137  	_, resp = Client.GetIncomingWebhooks(0, 1000, "")
   138  	CheckForbiddenStatus(t, resp)
   139  
   140  	Client.Logout()
   141  	_, resp = Client.GetIncomingWebhooks(0, 1000, "")
   142  	CheckUnauthorizedStatus(t, resp)
   143  }
   144  
   145  func TestGetIncomingWebhook(t *testing.T) {
   146  	th := Setup().InitBasic().InitSystemAdmin()
   147  	defer th.TearDown()
   148  	Client := th.SystemAdminClient
   149  
   150  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   151  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   152  
   153  	var resp *model.Response
   154  	var rhook *model.IncomingWebhook
   155  	var hook *model.IncomingWebhook
   156  
   157  	t.Run("WhenHookExists", func(t *testing.T) {
   158  		hook = &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   159  		rhook, resp = Client.CreateIncomingWebhook(hook)
   160  		CheckNoError(t, resp)
   161  
   162  		hook, resp = Client.GetIncomingWebhook(rhook.Id, "")
   163  		CheckOKStatus(t, resp)
   164  	})
   165  
   166  	t.Run("WhenHookDoesNotExist", func(t *testing.T) {
   167  		hook, resp = Client.GetIncomingWebhook(model.NewId(), "")
   168  		CheckNotFoundStatus(t, resp)
   169  	})
   170  
   171  	t.Run("WhenInvalidHookID", func(t *testing.T) {
   172  		hook, resp = Client.GetIncomingWebhook("abc", "")
   173  		CheckBadRequestStatus(t, resp)
   174  	})
   175  
   176  	t.Run("WhenUserDoesNotHavePemissions", func(t *testing.T) {
   177  		th.LoginBasic()
   178  		Client = th.Client
   179  
   180  		_, resp = Client.GetIncomingWebhook(rhook.Id, "")
   181  		CheckForbiddenStatus(t, resp)
   182  	})
   183  }
   184  
   185  func TestDeleteIncomingWebhook(t *testing.T) {
   186  	th := Setup().InitBasic().InitSystemAdmin()
   187  	defer th.TearDown()
   188  	Client := th.SystemAdminClient
   189  
   190  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   191  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   192  
   193  	var resp *model.Response
   194  	var rhook *model.IncomingWebhook
   195  	var hook *model.IncomingWebhook
   196  	var status bool
   197  
   198  	t.Run("WhenInvalidHookID", func(t *testing.T) {
   199  		status, resp = Client.DeleteIncomingWebhook("abc")
   200  		CheckBadRequestStatus(t, resp)
   201  	})
   202  
   203  	t.Run("WhenHookDoesNotExist", func(t *testing.T) {
   204  		status, resp = Client.DeleteIncomingWebhook(model.NewId())
   205  		CheckNotFoundStatus(t, resp)
   206  	})
   207  
   208  	t.Run("WhenHookExists", func(t *testing.T) {
   209  		hook = &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   210  		rhook, resp = Client.CreateIncomingWebhook(hook)
   211  		CheckNoError(t, resp)
   212  
   213  		if status, resp = Client.DeleteIncomingWebhook(rhook.Id); !status {
   214  			t.Fatal("Delete should have succeeded")
   215  		} else {
   216  			CheckOKStatus(t, resp)
   217  		}
   218  
   219  		// Get now should not return this deleted hook
   220  		_, resp = Client.GetIncomingWebhook(rhook.Id, "")
   221  		CheckNotFoundStatus(t, resp)
   222  	})
   223  
   224  	t.Run("WhenUserDoesNotHavePemissions", func(t *testing.T) {
   225  		hook = &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   226  		rhook, resp = Client.CreateIncomingWebhook(hook)
   227  		CheckNoError(t, resp)
   228  
   229  		th.LoginBasic()
   230  		Client = th.Client
   231  
   232  		_, resp = Client.DeleteIncomingWebhook(rhook.Id)
   233  		CheckForbiddenStatus(t, resp)
   234  	})
   235  }
   236  
   237  func TestCreateOutgoingWebhook(t *testing.T) {
   238  	th := Setup().InitBasic().InitSystemAdmin()
   239  	defer th.TearDown()
   240  	Client := th.Client
   241  
   242  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   243  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   244  
   245  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   246  
   247  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   248  	CheckNoError(t, resp)
   249  
   250  	if rhook.ChannelId != hook.ChannelId {
   251  		t.Fatal("channel ids didn't match")
   252  	} else if rhook.CreatorId != th.SystemAdminUser.Id {
   253  		t.Fatal("user ids didn't match")
   254  	} else if rhook.TeamId != th.BasicChannel.TeamId {
   255  		t.Fatal("team ids didn't match")
   256  	}
   257  
   258  	hook.ChannelId = "junk"
   259  	_, resp = th.SystemAdminClient.CreateOutgoingWebhook(hook)
   260  	CheckNotFoundStatus(t, resp)
   261  
   262  	hook.ChannelId = th.BasicChannel.Id
   263  	th.LoginTeamAdmin()
   264  	_, resp = Client.CreateOutgoingWebhook(hook)
   265  	CheckNoError(t, resp)
   266  
   267  	th.LoginBasic()
   268  	_, resp = Client.CreateOutgoingWebhook(hook)
   269  	CheckForbiddenStatus(t, resp)
   270  
   271  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   272  
   273  	_, resp = Client.CreateOutgoingWebhook(hook)
   274  	CheckNoError(t, resp)
   275  
   276  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   277  	_, resp = Client.CreateOutgoingWebhook(hook)
   278  	CheckNotImplementedStatus(t, resp)
   279  }
   280  
   281  func TestGetOutgoingWebhooks(t *testing.T) {
   282  	th := Setup().InitBasic().InitSystemAdmin()
   283  	defer th.TearDown()
   284  	Client := th.Client
   285  
   286  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   287  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   288  
   289  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   290  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   291  	CheckNoError(t, resp)
   292  
   293  	hooks, resp := th.SystemAdminClient.GetOutgoingWebhooks(0, 1000, "")
   294  	CheckNoError(t, resp)
   295  
   296  	found := false
   297  	for _, h := range hooks {
   298  		if rhook.Id == h.Id {
   299  			found = true
   300  		}
   301  	}
   302  
   303  	if !found {
   304  		t.Fatal("missing hook")
   305  	}
   306  
   307  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooks(0, 1, "")
   308  	CheckNoError(t, resp)
   309  
   310  	if len(hooks) != 1 {
   311  		t.Fatal("should only be 1")
   312  	}
   313  
   314  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   315  	CheckNoError(t, resp)
   316  
   317  	found = false
   318  	for _, h := range hooks {
   319  		if rhook.Id == h.Id {
   320  			found = true
   321  		}
   322  	}
   323  
   324  	if !found {
   325  		t.Fatal("missing hook")
   326  	}
   327  
   328  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForTeam(model.NewId(), 0, 1000, "")
   329  	CheckNoError(t, resp)
   330  
   331  	if len(hooks) != 0 {
   332  		t.Fatal("no hooks should be returned")
   333  	}
   334  
   335  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
   336  	CheckNoError(t, resp)
   337  
   338  	found = false
   339  	for _, h := range hooks {
   340  		if rhook.Id == h.Id {
   341  			found = true
   342  		}
   343  	}
   344  
   345  	if !found {
   346  		t.Fatal("missing hook")
   347  	}
   348  
   349  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForChannel(model.NewId(), 0, 1000, "")
   350  	CheckForbiddenStatus(t, resp)
   351  
   352  	_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
   353  	CheckForbiddenStatus(t, resp)
   354  
   355  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   356  
   357  	_, resp = Client.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   358  	CheckNoError(t, resp)
   359  
   360  	_, resp = Client.GetOutgoingWebhooksForTeam(model.NewId(), 0, 1000, "")
   361  	CheckForbiddenStatus(t, resp)
   362  
   363  	_, resp = Client.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
   364  	CheckNoError(t, resp)
   365  
   366  	_, resp = Client.GetOutgoingWebhooksForChannel(model.NewId(), 0, 1000, "")
   367  	CheckForbiddenStatus(t, resp)
   368  
   369  	_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
   370  	CheckForbiddenStatus(t, resp)
   371  
   372  	Client.Logout()
   373  	_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
   374  	CheckUnauthorizedStatus(t, resp)
   375  }
   376  
   377  func TestGetOutgoingWebhook(t *testing.T) {
   378  	th := Setup().InitBasic().InitSystemAdmin()
   379  	defer th.TearDown()
   380  	Client := th.Client
   381  
   382  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   383  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   384  
   385  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   386  
   387  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   388  	CheckNoError(t, resp)
   389  
   390  	getHook, resp := th.SystemAdminClient.GetOutgoingWebhook(rhook.Id)
   391  	CheckNoError(t, resp)
   392  	if getHook.Id != rhook.Id {
   393  		t.Fatal("failed to retrieve the correct outgoing hook")
   394  	}
   395  
   396  	_, resp = Client.GetOutgoingWebhook(rhook.Id)
   397  	CheckForbiddenStatus(t, resp)
   398  
   399  	nonExistentHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id}
   400  	_, resp = th.SystemAdminClient.GetOutgoingWebhook(nonExistentHook.Id)
   401  	CheckNotFoundStatus(t, resp)
   402  
   403  	nonExistentHook.Id = model.NewId()
   404  	_, resp = th.SystemAdminClient.GetOutgoingWebhook(nonExistentHook.Id)
   405  	CheckInternalErrorStatus(t, resp)
   406  }
   407  
   408  func TestUpdateIncomingHook(t *testing.T) {
   409  	th := Setup().InitBasic().InitSystemAdmin()
   410  	defer th.TearDown()
   411  	Client := th.Client
   412  
   413  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   414  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   415  
   416  	hook1 := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   417  
   418  	createdHook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook1)
   419  	CheckNoError(t, resp)
   420  
   421  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = false })
   422  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = false })
   423  
   424  	t.Run("UpdateIncomingHook, overrides disabled", func(t *testing.T) {
   425  		createdHook.DisplayName = "hook2"
   426  		createdHook.Description = "description"
   427  		createdHook.ChannelId = th.BasicChannel2.Id
   428  		createdHook.Username = "username"
   429  		createdHook.IconURL = "icon"
   430  
   431  		updatedHook, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   432  		CheckNoError(t, resp)
   433  		if updatedHook != nil {
   434  			if updatedHook.DisplayName != "hook2" {
   435  				t.Fatal("Hook name is not updated")
   436  			}
   437  
   438  			if updatedHook.Description != "description" {
   439  				t.Fatal("Hook description is not updated")
   440  			}
   441  
   442  			if updatedHook.ChannelId != th.BasicChannel2.Id {
   443  				t.Fatal("Hook channel is not updated")
   444  			}
   445  
   446  			if updatedHook.Username != "" {
   447  				t.Fatal("Hook username was incorrectly updated")
   448  			}
   449  
   450  			if updatedHook.IconURL != "" {
   451  				t.Fatal("Hook icon was incorrectly updated")
   452  			}
   453  		} else {
   454  			t.Fatal("should not be nil")
   455  		}
   456  
   457  		//updatedHook, _ = th.App.GetIncomingWebhook(createdHook.Id)
   458  		assert.Equal(t, updatedHook.ChannelId, createdHook.ChannelId)
   459  	})
   460  
   461  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = true })
   462  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = true })
   463  
   464  	t.Run("UpdateIncomingHook", func(t *testing.T) {
   465  		createdHook.DisplayName = "hook2"
   466  		createdHook.Description = "description"
   467  		createdHook.ChannelId = th.BasicChannel2.Id
   468  		createdHook.Username = "username"
   469  		createdHook.IconURL = "icon"
   470  
   471  		updatedHook, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   472  		CheckNoError(t, resp)
   473  		if updatedHook != nil {
   474  			if updatedHook.DisplayName != "hook2" {
   475  				t.Fatal("Hook name is not updated")
   476  			}
   477  
   478  			if updatedHook.Description != "description" {
   479  				t.Fatal("Hook description is not updated")
   480  			}
   481  
   482  			if updatedHook.ChannelId != th.BasicChannel2.Id {
   483  				t.Fatal("Hook channel is not updated")
   484  			}
   485  
   486  			if updatedHook.Username != "username" {
   487  				t.Fatal("Hook username is not updated")
   488  			}
   489  
   490  			if updatedHook.IconURL != "icon" {
   491  				t.Fatal("Hook icon is not updated")
   492  			}
   493  		} else {
   494  			t.Fatal("should not be nil")
   495  		}
   496  
   497  		//updatedHook, _ = th.App.GetIncomingWebhook(createdHook.Id)
   498  		assert.Equal(t, updatedHook.ChannelId, createdHook.ChannelId)
   499  	})
   500  
   501  	t.Run("RetainCreateAt", func(t *testing.T) {
   502  		hook2 := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, CreateAt: 100}
   503  
   504  		createdHook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook2)
   505  		CheckNoError(t, resp)
   506  
   507  		createdHook.DisplayName = "Name2"
   508  
   509  		updatedHook, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   510  		CheckNoError(t, resp)
   511  		if updatedHook != nil {
   512  			if updatedHook.CreateAt != createdHook.CreateAt {
   513  				t.Fatal("failed - hook create at should not be changed")
   514  			}
   515  		} else {
   516  			t.Fatal("should not be nil")
   517  		}
   518  	})
   519  
   520  	t.Run("ModifyUpdateAt", func(t *testing.T) {
   521  		createdHook.DisplayName = "Name3"
   522  
   523  		updatedHook, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   524  		CheckNoError(t, resp)
   525  		if updatedHook != nil {
   526  			if updatedHook.UpdateAt == createdHook.UpdateAt {
   527  				t.Fatal("failed - hook updateAt is not updated")
   528  			}
   529  		} else {
   530  			t.Fatal("should not be nil")
   531  		}
   532  	})
   533  
   534  	t.Run("UpdateNonExistentHook", func(t *testing.T) {
   535  		nonExistentHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   536  
   537  		_, resp := th.SystemAdminClient.UpdateIncomingWebhook(nonExistentHook)
   538  		CheckNotFoundStatus(t, resp)
   539  
   540  		nonExistentHook.Id = model.NewId()
   541  		_, resp = th.SystemAdminClient.UpdateIncomingWebhook(nonExistentHook)
   542  		CheckNotFoundStatus(t, resp)
   543  	})
   544  
   545  	t.Run("UserIsNotAdminOfTeam", func(t *testing.T) {
   546  		_, resp := Client.UpdateIncomingWebhook(createdHook)
   547  		CheckForbiddenStatus(t, resp)
   548  	})
   549  
   550  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   551  
   552  	t.Run("OnlyAdminIntegrationsDisabled", func(t *testing.T) {
   553  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   554  
   555  		t.Run("UpdateHookOfSameUser", func(t *testing.T) {
   556  			sameUserHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, UserId: th.BasicUser2.Id}
   557  
   558  			sameUserHook, resp := Client.CreateIncomingWebhook(sameUserHook)
   559  			CheckNoError(t, resp)
   560  
   561  			_, resp = Client.UpdateIncomingWebhook(sameUserHook)
   562  			CheckNoError(t, resp)
   563  		})
   564  
   565  		t.Run("UpdateHookOfDifferentUser", func(t *testing.T) {
   566  			_, resp := Client.UpdateIncomingWebhook(createdHook)
   567  			CheckForbiddenStatus(t, resp)
   568  		})
   569  	})
   570  
   571  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   572  
   573  	Client.Logout()
   574  	th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
   575  	th.LoginBasic2()
   576  	t.Run("UpdateByDifferentUser", func(t *testing.T) {
   577  		updatedHook, resp := Client.UpdateIncomingWebhook(createdHook)
   578  		CheckNoError(t, resp)
   579  		if updatedHook.UserId == th.BasicUser2.Id {
   580  			t.Fatal("Hook's creator userId is not retained")
   581  		}
   582  	})
   583  
   584  	t.Run("IncomingHooksDisabled", func(t *testing.T) {
   585  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false })
   586  		_, resp := Client.UpdateIncomingWebhook(createdHook)
   587  		CheckNotImplementedStatus(t, resp)
   588  		CheckErrorMessage(t, resp, "api.incoming_webhook.disabled.app_error")
   589  	})
   590  
   591  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   592  
   593  	t.Run("PrivateChannel", func(t *testing.T) {
   594  		privateChannel := th.CreatePrivateChannel()
   595  		Client.Logout()
   596  		th.LoginBasic()
   597  		createdHook.ChannelId = privateChannel.Id
   598  
   599  		_, resp := Client.UpdateIncomingWebhook(createdHook)
   600  		CheckForbiddenStatus(t, resp)
   601  	})
   602  
   603  	t.Run("UpdateToNonExistentChannel", func(t *testing.T) {
   604  		createdHook.ChannelId = "junk"
   605  		_, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   606  		CheckNotFoundStatus(t, resp)
   607  	})
   608  
   609  	team := th.CreateTeamWithClient(Client)
   610  	user := th.CreateUserWithClient(Client)
   611  	th.LinkUserToTeam(user, team)
   612  	Client.Logout()
   613  	Client.Login(user.Id, user.Password)
   614  	t.Run("UpdateToADifferentTeam", func(t *testing.T) {
   615  		_, resp := Client.UpdateIncomingWebhook(createdHook)
   616  		CheckUnauthorizedStatus(t, resp)
   617  	})
   618  }
   619  
   620  func TestRegenOutgoingHookToken(t *testing.T) {
   621  	th := Setup().InitBasic().InitSystemAdmin()
   622  	defer th.TearDown()
   623  	Client := th.Client
   624  
   625  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   626  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   627  
   628  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   629  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   630  	CheckNoError(t, resp)
   631  
   632  	_, resp = th.SystemAdminClient.RegenOutgoingHookToken("junk")
   633  	CheckBadRequestStatus(t, resp)
   634  
   635  	//investigate why is act weird on jenkins
   636  	// _, resp = th.SystemAdminClient.RegenOutgoingHookToken("")
   637  	// CheckNotFoundStatus(t, resp)
   638  
   639  	regenHookToken, resp := th.SystemAdminClient.RegenOutgoingHookToken(rhook.Id)
   640  	CheckNoError(t, resp)
   641  	if regenHookToken.Token == rhook.Token {
   642  		t.Fatal("regen didn't work properly")
   643  	}
   644  
   645  	_, resp = Client.RegenOutgoingHookToken(rhook.Id)
   646  	CheckForbiddenStatus(t, resp)
   647  
   648  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   649  	_, resp = th.SystemAdminClient.RegenOutgoingHookToken(rhook.Id)
   650  	CheckNotImplementedStatus(t, resp)
   651  }
   652  
   653  func TestUpdateOutgoingHook(t *testing.T) {
   654  	th := Setup().InitBasic().InitSystemAdmin()
   655  	defer th.TearDown()
   656  	Client := th.Client
   657  
   658  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   659  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   660  
   661  	createdHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   662  		CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"cats"}}
   663  
   664  	createdHook, resp := th.SystemAdminClient.CreateOutgoingWebhook(createdHook)
   665  	CheckNoError(t, resp)
   666  
   667  	t.Run("UpdateOutgoingWebhook", func(t *testing.T) {
   668  		createdHook.DisplayName = "Cats"
   669  		createdHook.Description = "Get me some cats"
   670  
   671  		updatedHook, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   672  		CheckNoError(t, resp)
   673  		if updatedHook.DisplayName != "Cats" {
   674  			t.Fatal("did not update")
   675  		}
   676  		if updatedHook.Description != "Get me some cats" {
   677  			t.Fatal("did not update")
   678  		}
   679  	})
   680  
   681  	t.Run("OutgoingHooksDisabled", func(t *testing.T) {
   682  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   683  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   684  		CheckNotImplementedStatus(t, resp)
   685  	})
   686  
   687  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   688  	t.Run("RetainCreateAt", func(t *testing.T) {
   689  		hook2 := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   690  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats"}}
   691  
   692  		createdHook2, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook2)
   693  		CheckNoError(t, resp)
   694  		createdHook2.DisplayName = "Name2"
   695  
   696  		updatedHook2, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook2)
   697  		CheckNoError(t, resp)
   698  
   699  		if updatedHook2.CreateAt != createdHook2.CreateAt {
   700  			t.Fatal("failed - hook create at should not be changed")
   701  		}
   702  	})
   703  
   704  	t.Run("ModifyUpdateAt", func(t *testing.T) {
   705  		createdHook.DisplayName = "Name3"
   706  
   707  		updatedHook2, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   708  		CheckNoError(t, resp)
   709  
   710  		if updatedHook2.UpdateAt == createdHook.UpdateAt {
   711  			t.Fatal("failed - hook updateAt is not updated")
   712  		}
   713  	})
   714  
   715  	t.Run("UpdateNonExistentHook", func(t *testing.T) {
   716  		nonExistentHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   717  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats"}}
   718  
   719  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(nonExistentHook)
   720  		CheckNotFoundStatus(t, resp)
   721  
   722  		nonExistentHook.Id = model.NewId()
   723  		_, resp = th.SystemAdminClient.UpdateOutgoingWebhook(nonExistentHook)
   724  		CheckInternalErrorStatus(t, resp)
   725  	})
   726  
   727  	t.Run("UserIsNotAdminOfTeam", func(t *testing.T) {
   728  		_, resp := Client.UpdateOutgoingWebhook(createdHook)
   729  		CheckForbiddenStatus(t, resp)
   730  	})
   731  
   732  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   733  	hook2 := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   734  		CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats2"}}
   735  
   736  	createdHook2, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook2)
   737  	CheckNoError(t, resp)
   738  
   739  	_, resp = Client.UpdateOutgoingWebhook(createdHook2)
   740  	CheckForbiddenStatus(t, resp)
   741  
   742  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   743  
   744  	Client.Logout()
   745  	th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
   746  	th.LoginBasic2()
   747  	t.Run("RetainHookCreator", func(t *testing.T) {
   748  		createdHook.DisplayName = "Basic user 2"
   749  		updatedHook, resp := Client.UpdateOutgoingWebhook(createdHook)
   750  		CheckNoError(t, resp)
   751  		if updatedHook.DisplayName != "Basic user 2" {
   752  			t.Fatal("should apply the change")
   753  		}
   754  		if updatedHook.CreatorId != th.SystemAdminUser.Id {
   755  			t.Fatal("hook creator should not be changed")
   756  		}
   757  	})
   758  
   759  	t.Run("UpdateToExistingTriggerWordAndCallback", func(t *testing.T) {
   760  		t.Run("OnSameChannel", func(t *testing.T) {
   761  			createdHook.TriggerWords = []string{"rats"}
   762  
   763  			_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   764  			CheckBadRequestStatus(t, resp)
   765  		})
   766  
   767  		t.Run("OnDifferentChannel", func(t *testing.T) {
   768  			createdHook.TriggerWords = []string{"cats"}
   769  			createdHook.ChannelId = th.BasicChannel2.Id
   770  
   771  			_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   772  			CheckNoError(t, resp)
   773  		})
   774  	})
   775  
   776  	t.Run("UpdateToNonExistentChannel", func(t *testing.T) {
   777  		createdHook.ChannelId = "junk"
   778  
   779  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   780  		CheckNotFoundStatus(t, resp)
   781  	})
   782  
   783  	t.Run("UpdateToPrivateChannel", func(t *testing.T) {
   784  		privateChannel := th.CreatePrivateChannel()
   785  		createdHook.ChannelId = privateChannel.Id
   786  
   787  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   788  		CheckForbiddenStatus(t, resp)
   789  	})
   790  
   791  	t.Run("UpdateToBlankTriggerWordAndChannel", func(t *testing.T) {
   792  		createdHook.ChannelId = ""
   793  		createdHook.TriggerWords = nil
   794  
   795  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   796  		CheckInternalErrorStatus(t, resp)
   797  	})
   798  
   799  	team := th.CreateTeamWithClient(Client)
   800  	user := th.CreateUserWithClient(Client)
   801  	th.LinkUserToTeam(user, team)
   802  	Client.Logout()
   803  	Client.Login(user.Id, user.Password)
   804  	t.Run("UpdateToADifferentTeam", func(t *testing.T) {
   805  		_, resp := Client.UpdateOutgoingWebhook(createdHook)
   806  		CheckUnauthorizedStatus(t, resp)
   807  	})
   808  }
   809  
   810  func TestDeleteOutgoingHook(t *testing.T) {
   811  	th := Setup().InitBasic().InitSystemAdmin()
   812  	defer th.TearDown()
   813  	Client := th.SystemAdminClient
   814  
   815  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   816  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   817  
   818  	var resp *model.Response
   819  	var rhook *model.OutgoingWebhook
   820  	var hook *model.OutgoingWebhook
   821  	var status bool
   822  
   823  	t.Run("WhenInvalidHookID", func(t *testing.T) {
   824  		status, resp = Client.DeleteOutgoingWebhook("abc")
   825  		CheckBadRequestStatus(t, resp)
   826  	})
   827  
   828  	t.Run("WhenHookDoesNotExist", func(t *testing.T) {
   829  		status, resp = Client.DeleteOutgoingWebhook(model.NewId())
   830  		CheckInternalErrorStatus(t, resp)
   831  	})
   832  
   833  	t.Run("WhenHookExists", func(t *testing.T) {
   834  		hook = &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   835  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"cats"}}
   836  		rhook, resp = Client.CreateOutgoingWebhook(hook)
   837  		CheckNoError(t, resp)
   838  
   839  		if status, resp = Client.DeleteOutgoingWebhook(rhook.Id); !status {
   840  			t.Fatal("Delete should have succeeded")
   841  		} else {
   842  			CheckOKStatus(t, resp)
   843  		}
   844  
   845  		// Get now should not return this deleted hook
   846  		_, resp = Client.GetIncomingWebhook(rhook.Id, "")
   847  		CheckNotFoundStatus(t, resp)
   848  	})
   849  
   850  	t.Run("WhenUserDoesNotHavePemissions", func(t *testing.T) {
   851  		hook = &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   852  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"dogs"}}
   853  		rhook, resp = Client.CreateOutgoingWebhook(hook)
   854  		CheckNoError(t, resp)
   855  
   856  		th.LoginBasic()
   857  		Client = th.Client
   858  
   859  		_, resp = Client.DeleteOutgoingWebhook(rhook.Id)
   860  		CheckForbiddenStatus(t, resp)
   861  	})
   862  }
   863  
   864  func TestCommandWebhooks(t *testing.T) {
   865  	th := Setup().InitBasic().InitSystemAdmin()
   866  	defer th.TearDown()
   867  
   868  	Client := th.SystemAdminClient
   869  
   870  	cmd := &model.Command{
   871  		CreatorId: th.BasicUser.Id,
   872  		TeamId:    th.BasicTeam.Id,
   873  		URL:       "http://nowhere.com",
   874  		Method:    model.COMMAND_METHOD_POST,
   875  		Trigger:   "delayed"}
   876  
   877  	cmd, _ = Client.CreateCommand(cmd)
   878  	args := &model.CommandArgs{
   879  		TeamId:    th.BasicTeam.Id,
   880  		UserId:    th.BasicUser.Id,
   881  		ChannelId: th.BasicChannel.Id,
   882  	}
   883  	hook, err := th.App.CreateCommandWebhook(cmd.Id, args)
   884  	if err != nil {
   885  		t.Fatal(err)
   886  	}
   887  
   888  	if resp, _ := http.Post(Client.Url+"/hooks/commands/123123123123", "application/json", bytes.NewBufferString("{\"text\":\"this is a test\"}")); resp.StatusCode != http.StatusNotFound {
   889  		t.Fatal("expected not-found for non-existent hook")
   890  	}
   891  
   892  	for i := 0; i < 5; i++ {
   893  		if resp, err := http.Post(Client.Url+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString("{\"text\":\"this is a test\"}")); err != nil || resp.StatusCode != http.StatusOK {
   894  			t.Fatal(err)
   895  		}
   896  	}
   897  
   898  	if resp, _ := http.Post(Client.Url+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString("{\"text\":\"this is a test\"}")); resp.StatusCode != http.StatusBadRequest {
   899  		t.Fatal("expected error for sixth usage")
   900  	}
   901  }