github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/cmd/mattermost/commands/webhook_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package commands
     5  
     6  import (
     7  	"strconv"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/mattermost/mattermost-server/v5/api4"
    15  	"github.com/mattermost/mattermost-server/v5/model"
    16  )
    17  
    18  func TestListWebhooks(t *testing.T) {
    19  	th := Setup(t).InitBasic()
    20  	defer th.TearDown()
    21  	adminClient := th.SystemAdminClient
    22  
    23  	config := th.Config()
    24  	*config.ServiceSettings.EnableCommands = true
    25  	*config.ServiceSettings.EnableIncomingWebhooks = true
    26  	*config.ServiceSettings.EnableOutgoingWebhooks = true
    27  	*config.ServiceSettings.EnablePostUsernameOverride = true
    28  	*config.ServiceSettings.EnablePostIconOverride = true
    29  	th.SetConfig(config)
    30  
    31  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
    32  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
    33  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = true })
    34  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = true })
    35  
    36  	defaultRolePermissions := th.SaveDefaultRolePermissions()
    37  	defer func() {
    38  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
    39  	}()
    40  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
    41  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
    42  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
    43  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
    44  
    45  	dispName := "myhookinc"
    46  	hook := &model.IncomingWebhook{DisplayName: dispName, ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId}
    47  	_, resp := adminClient.CreateIncomingWebhook(hook)
    48  	api4.CheckNoError(t, resp)
    49  
    50  	dispName2 := "myhookout"
    51  	outHook := &model.OutgoingWebhook{DisplayName: dispName2, ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}, Username: "some-user-name", IconURL: "http://some-icon-url/"}
    52  	_, resp = adminClient.CreateOutgoingWebhook(outHook)
    53  	api4.CheckNoError(t, resp)
    54  
    55  	output := th.CheckCommand(t, "webhook", "list", th.BasicTeam.Name)
    56  
    57  	assert.Contains(t, output, dispName, "should have incoming webhooks")
    58  	assert.Contains(t, output, dispName2, "should have outgoing webhooks")
    59  }
    60  
    61  func TestShowWebhook(t *testing.T) {
    62  	th := Setup(t).InitBasic()
    63  	defer th.TearDown()
    64  	adminClient := th.SystemAdminClient
    65  
    66  	config := th.Config()
    67  	*config.ServiceSettings.EnableCommands = true
    68  	*config.ServiceSettings.EnableIncomingWebhooks = true
    69  	*config.ServiceSettings.EnableOutgoingWebhooks = true
    70  	*config.ServiceSettings.EnablePostUsernameOverride = true
    71  	*config.ServiceSettings.EnablePostIconOverride = true
    72  	th.SetConfig(config)
    73  
    74  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
    75  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
    76  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = true })
    77  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = true })
    78  
    79  	defaultRolePermissions := th.SaveDefaultRolePermissions()
    80  	defer func() {
    81  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
    82  	}()
    83  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
    84  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
    85  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
    86  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
    87  
    88  	dispName := "incominghook"
    89  	hook := &model.IncomingWebhook{
    90  		DisplayName: dispName,
    91  		ChannelId:   th.BasicChannel.Id,
    92  		TeamId:      th.BasicChannel.TeamId,
    93  	}
    94  	incomingWebhook, resp := adminClient.CreateIncomingWebhook(hook)
    95  	api4.CheckNoError(t, resp)
    96  
    97  	// should return an error when no webhookid is provided
    98  	require.Error(t, th.RunCommand(t, "webhook", "show"))
    99  
   100  	// invalid webhook should return error
   101  	require.Error(t, th.RunCommand(t, "webhook", "show", "invalid-webhook"))
   102  
   103  	// valid incoming webhook should return webhook data
   104  	output := th.CheckCommand(t, "webhook", "show", incomingWebhook.Id)
   105  	assert.Contains(t, output, "DisplayName: \""+dispName+"\"", "incoming: should have incominghook as displayname")
   106  	assert.Contains(t, output, "ChannelId: \""+hook.ChannelId+"\"", "incoming: should have a valid channelId")
   107  
   108  	dispName = "outgoinghook"
   109  	outgoingHook := &model.OutgoingWebhook{
   110  		DisplayName:  dispName,
   111  		ChannelId:    th.BasicChannel.Id,
   112  		TeamId:       th.BasicChannel.TeamId,
   113  		CallbackURLs: []string{"http://nowhere.com"},
   114  		Username:     "some-user-name",
   115  		IconURL:      "http://some-icon-url/",
   116  	}
   117  	outgoingWebhook, resp := adminClient.CreateOutgoingWebhook(outgoingHook)
   118  	api4.CheckNoError(t, resp)
   119  
   120  	// valid outgoing webhook should return webhook data
   121  	output = th.CheckCommand(t, "webhook", "show", outgoingWebhook.Id)
   122  
   123  	assert.Contains(t, output, "DisplayName: \""+dispName+"\"", "outgoing: should have outgoinghook as displayname")
   124  	assert.Contains(t, output, "ChannelId: \""+hook.ChannelId+"\"", "outgoing: should have a valid channelId")
   125  }
   126  
   127  func TestCreateIncomingWebhook(t *testing.T) {
   128  	th := Setup(t).InitBasic()
   129  	defer th.TearDown()
   130  
   131  	config := th.Config()
   132  	*config.ServiceSettings.EnableCommands = true
   133  	*config.ServiceSettings.EnableIncomingWebhooks = true
   134  	*config.ServiceSettings.EnableOutgoingWebhooks = true
   135  	*config.ServiceSettings.EnablePostUsernameOverride = true
   136  	*config.ServiceSettings.EnablePostIconOverride = true
   137  	th.SetConfig(config)
   138  
   139  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   140  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   141  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = true })
   142  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = true })
   143  
   144  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   145  	defer func() {
   146  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   147  	}()
   148  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   149  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   150  
   151  	// should fail because you need to specify valid channel
   152  	require.Error(t, th.RunCommand(t, "webhook", "create-incoming"))
   153  	require.Error(t, th.RunCommand(t, "webhook", "create-incoming", "--channel", th.BasicTeam.Name+":doesnotexist"))
   154  
   155  	// should fail because you need to specify valid user
   156  	require.Error(t, th.RunCommand(t, "webhook", "create-incoming", "--channel", th.BasicChannel.Id))
   157  	require.Error(t, th.RunCommand(t, "webhook", "create-incoming", "--channel", th.BasicChannel.Id, "--user", "doesnotexist"))
   158  
   159  	description := "myhookinc"
   160  	displayName := "myhookinc"
   161  	th.CheckCommand(t, "webhook", "create-incoming", "--channel", th.BasicChannel.Id, "--user", th.BasicUser.Email, "--description", description, "--display-name", displayName)
   162  
   163  	webhooks, err := th.App.GetIncomingWebhooksPage(0, 1000)
   164  	require.Nil(t, err, "unable to retrieve incoming webhooks")
   165  
   166  	found := false
   167  	for _, webhook := range webhooks {
   168  		if webhook.Description == description && webhook.UserId == th.BasicUser.Id {
   169  			found = true
   170  		}
   171  	}
   172  	require.True(t, found, "Failed to create incoming webhook")
   173  }
   174  
   175  func TestModifyIncomingWebhook(t *testing.T) {
   176  	th := Setup(t).InitBasic()
   177  	defer th.TearDown()
   178  
   179  	config := th.Config()
   180  	*config.ServiceSettings.EnableCommands = true
   181  	*config.ServiceSettings.EnableIncomingWebhooks = true
   182  	*config.ServiceSettings.EnableOutgoingWebhooks = true
   183  	*config.ServiceSettings.EnablePostUsernameOverride = true
   184  	*config.ServiceSettings.EnablePostIconOverride = true
   185  	th.SetConfig(config)
   186  
   187  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   188  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   189  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = true })
   190  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = true })
   191  
   192  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   193  	defer func() {
   194  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   195  	}()
   196  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   197  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   198  
   199  	description := "myhookincdesc"
   200  	displayName := "myhookincname"
   201  
   202  	incomingWebhook := &model.IncomingWebhook{
   203  		ChannelId:   th.BasicChannel.Id,
   204  		DisplayName: displayName,
   205  		Description: description,
   206  	}
   207  
   208  	oldHook, err := th.App.CreateIncomingWebhookForChannel(th.BasicUser.Id, th.BasicChannel, incomingWebhook)
   209  	require.Nil(t, err, "unable to create incoming webhooks")
   210  
   211  	defer func() {
   212  		th.App.DeleteIncomingWebhook(oldHook.Id)
   213  	}()
   214  
   215  	// should fail because you need to specify valid incoming webhook
   216  	require.Error(t, th.RunCommand(t, "webhook", "modify-incoming", "doesnotexist"))
   217  	// should fail because you need to specify valid channel
   218  	require.Error(t, th.RunCommand(t, "webhook", "modify-incoming", oldHook.Id, "--channel", th.BasicTeam.Name+":doesnotexist"))
   219  
   220  	modifiedDescription := "myhookincdesc2"
   221  	modifiedDisplayName := "myhookincname2"
   222  	modifiedIconUrl := "myhookincicon2"
   223  	modifiedChannelLocked := true
   224  	modifiedChannelId := th.BasicChannel2.Id
   225  
   226  	th.CheckCommand(t, "webhook", "modify-incoming", oldHook.Id, "--channel", modifiedChannelId, "--description", modifiedDescription, "--display-name", modifiedDisplayName, "--icon", modifiedIconUrl, "--lock-to-channel", strconv.FormatBool(modifiedChannelLocked))
   227  
   228  	modifiedHook, err := th.App.GetIncomingWebhook(oldHook.Id)
   229  	require.Nil(t, err, "unable to retrieve modified incoming webhook")
   230  
   231  	successUpdate := modifiedHook.DisplayName != modifiedDisplayName ||
   232  		modifiedHook.Description != modifiedDescription ||
   233  		modifiedHook.IconURL != modifiedIconUrl ||
   234  		modifiedHook.ChannelLocked != modifiedChannelLocked ||
   235  		modifiedHook.ChannelId != modifiedChannelId
   236  	require.False(t, successUpdate, "Failed to update incoming webhook")
   237  }
   238  
   239  func TestCreateOutgoingWebhook(t *testing.T) {
   240  	th := Setup(t).InitBasic()
   241  	defer th.TearDown()
   242  
   243  	config := th.Config()
   244  	*config.ServiceSettings.EnableCommands = true
   245  	*config.ServiceSettings.EnableIncomingWebhooks = true
   246  	*config.ServiceSettings.EnableOutgoingWebhooks = true
   247  	*config.ServiceSettings.EnablePostUsernameOverride = true
   248  	*config.ServiceSettings.EnablePostIconOverride = true
   249  	th.SetConfig(config)
   250  
   251  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   252  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   253  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = true })
   254  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = true })
   255  
   256  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   257  	defer func() {
   258  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   259  	}()
   260  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   261  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   262  
   263  	// team, user, display name, trigger words, callback urls are required
   264  	team := th.BasicTeam.Id
   265  	user := th.BasicUser.Id
   266  	displayName := "totally radical webhook"
   267  	triggerWord1 := "build"
   268  	triggerWord2 := "defenestrate"
   269  	callbackURL1 := "http://localhost:8000/my-webhook-handler"
   270  	callbackURL2 := "http://localhost:8000/my-webhook-handler2"
   271  
   272  	// should fail because team is not specified
   273  	require.Error(t, th.RunCommand(t, "webhook", "create-outgoing", "--display-name", displayName, "--trigger-word", triggerWord1, "--trigger-word", triggerWord2, "--url", callbackURL1, "--url", callbackURL2, "--user", user))
   274  
   275  	// should fail because user is not specified
   276  	require.Error(t, th.RunCommand(t, "webhook", "create-outgoing", "--team", team, "--display-name", displayName, "--trigger-word", triggerWord1, "--trigger-word", triggerWord2, "--url", callbackURL1, "--url", callbackURL2))
   277  
   278  	// should fail because display name is not specified
   279  	require.Error(t, th.RunCommand(t, "webhook", "create-outgoing", "--team", team, "--trigger-word", triggerWord1, "--trigger-word", triggerWord2, "--url", callbackURL1, "--url", callbackURL2, "--user", user))
   280  
   281  	// should fail because trigger words are not specified
   282  	require.Error(t, th.RunCommand(t, "webhook", "create-outgoing", "--team", team, "--display-name", displayName, "--url", callbackURL1, "--url", callbackURL2, "--user", user))
   283  
   284  	// should fail because callback URLs are not specified
   285  	require.Error(t, th.RunCommand(t, "webhook", "create-outgoing", "--team", team, "--display-name", displayName, "--trigger-word", triggerWord1, "--trigger-word", triggerWord2, "--user", user))
   286  
   287  	// should fail because outgoing webhooks cannot be made for private channels
   288  	require.Error(t, th.RunCommand(t, "webhook", "create-outgoing", "--team", team, "--channel", th.BasicPrivateChannel.Id, "--display-name", displayName, "--trigger-word", triggerWord1, "--trigger-word", triggerWord2, "--url", callbackURL1, "--url", callbackURL2, "--user", user))
   289  
   290  	th.CheckCommand(t, "webhook", "create-outgoing", "--team", team, "--channel", th.BasicChannel.Id, "--display-name", displayName, "--trigger-word", triggerWord1, "--trigger-word", triggerWord2, "--url", callbackURL1, "--url", callbackURL2, "--user", user)
   291  
   292  	webhooks, err := th.App.GetOutgoingWebhooksPage(0, 1000)
   293  	require.Nil(t, err, "Unable to retrieve outgoing webhooks")
   294  
   295  	found := false
   296  	for _, webhook := range webhooks {
   297  		if webhook.DisplayName == displayName && webhook.CreatorId == th.BasicUser.Id {
   298  			found = true
   299  		}
   300  	}
   301  	require.True(t, found, "Failed to create incoming webhook")
   302  }
   303  
   304  func TestModifyOutgoingWebhook(t *testing.T) {
   305  	th := Setup(t).InitBasic()
   306  	defer th.TearDown()
   307  
   308  	config := th.Config()
   309  	*config.ServiceSettings.EnableOutgoingWebhooks = true
   310  	th.SetConfig(config)
   311  
   312  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   313  	defer func() {
   314  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   315  	}()
   316  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   317  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   318  
   319  	description := "myhookoutdesc"
   320  	displayName := "myhookoutname"
   321  	triggerWords := model.StringArray{"myhookoutword1"}
   322  	triggerWhen := 0
   323  	callbackURLs := model.StringArray{"http://myhookouturl1"}
   324  	iconURL := "myhookicon1"
   325  	contentType := "myhookcontent1"
   326  
   327  	outgoingWebhook := &model.OutgoingWebhook{
   328  		CreatorId:    th.BasicUser.Id,
   329  		Username:     th.BasicUser.Username,
   330  		TeamId:       th.BasicTeam.Id,
   331  		ChannelId:    th.BasicChannel.Id,
   332  		DisplayName:  displayName,
   333  		Description:  description,
   334  		TriggerWords: triggerWords,
   335  		TriggerWhen:  triggerWhen,
   336  		CallbackURLs: callbackURLs,
   337  		IconURL:      iconURL,
   338  		ContentType:  contentType,
   339  	}
   340  
   341  	oldHook, err := th.App.CreateOutgoingWebhook(outgoingWebhook)
   342  	require.Nil(t, err, "unable to create outgoing webhooks: ")
   343  
   344  	defer func() {
   345  		th.App.DeleteOutgoingWebhook(oldHook.Id)
   346  	}()
   347  
   348  	// should fail because you need to specify valid outgoing webhook
   349  	require.Error(t, th.RunCommand(t, "webhook", "modify-outgoing", "doesnotexist"))
   350  	// should fail because you need to specify valid channel
   351  	require.Error(t, th.RunCommand(t, "webhook", "modify-outgoing", oldHook.Id, "--channel", th.BasicTeam.Name+":doesnotexist"))
   352  	// should fail because you need to specify valid trigger when
   353  	require.Error(t, th.RunCommand(t, "webhook", "modify-outgoing", oldHook.Id, "--channel", th.BasicTeam.Name+th.BasicChannel.Id, "--trigger-when", "invalid"))
   354  	// should fail because you need to specify a valid callback URL
   355  	require.Error(t, th.RunCommand(t, "webhook", "modify-outgoing", oldHook.Id, "--channel", th.BasicTeam.Name+th.BasicChannel.Id, "--callback-url", "invalid"))
   356  
   357  	modifiedChannelID := th.BasicChannel2.Id
   358  	modifiedDisplayName := "myhookoutname2"
   359  	modifiedDescription := "myhookoutdesc2"
   360  	modifiedTriggerWords := model.StringArray{"myhookoutword2A", "myhookoutword2B"}
   361  	modifiedTriggerWhen := "start"
   362  	modifiedIconURL := "myhookouticon2"
   363  	modifiedContentType := "myhookcontent2"
   364  	modifiedCallbackURLs := model.StringArray{"http://myhookouturl2A", "http://myhookouturl2B"}
   365  
   366  	th.CheckCommand(t, "webhook", "modify-outgoing", oldHook.Id,
   367  		"--channel", modifiedChannelID,
   368  		"--display-name", modifiedDisplayName,
   369  		"--description", modifiedDescription,
   370  		"--trigger-word", modifiedTriggerWords[0],
   371  		"--trigger-word", modifiedTriggerWords[1],
   372  		"--trigger-when", modifiedTriggerWhen,
   373  		"--icon", modifiedIconURL,
   374  		"--content-type", modifiedContentType,
   375  		"--url", modifiedCallbackURLs[0],
   376  		"--url", modifiedCallbackURLs[1],
   377  	)
   378  
   379  	modifiedHook, err := th.App.GetOutgoingWebhook(oldHook.Id)
   380  	require.Nil(t, err, "unable to retrieve modified outgoing webhook")
   381  
   382  	updateFailed := modifiedHook.ChannelId != modifiedChannelID ||
   383  		modifiedHook.DisplayName != modifiedDisplayName ||
   384  		modifiedHook.Description != modifiedDescription ||
   385  		len(modifiedHook.TriggerWords) != len(modifiedTriggerWords) ||
   386  		modifiedHook.TriggerWords[0] != modifiedTriggerWords[0] ||
   387  		modifiedHook.TriggerWords[1] != modifiedTriggerWords[1] ||
   388  		modifiedHook.TriggerWhen != 1 ||
   389  		modifiedHook.IconURL != modifiedIconURL ||
   390  		modifiedHook.ContentType != modifiedContentType ||
   391  		len(modifiedHook.CallbackURLs) != len(modifiedCallbackURLs) ||
   392  		modifiedHook.CallbackURLs[0] != modifiedCallbackURLs[0] ||
   393  		modifiedHook.CallbackURLs[1] != modifiedCallbackURLs[1]
   394  
   395  	require.False(t, updateFailed, "Failed to update outgoing webhook")
   396  }
   397  
   398  func TestDeleteWebhooks(t *testing.T) {
   399  	th := Setup(t).InitBasic()
   400  	defer th.TearDown()
   401  	adminClient := th.SystemAdminClient
   402  
   403  	config := th.Config()
   404  	*config.ServiceSettings.EnableCommands = true
   405  	*config.ServiceSettings.EnableIncomingWebhooks = true
   406  	*config.ServiceSettings.EnableOutgoingWebhooks = true
   407  	*config.ServiceSettings.EnablePostUsernameOverride = true
   408  	*config.ServiceSettings.EnablePostIconOverride = true
   409  	th.SetConfig(config)
   410  
   411  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   412  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   413  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = true })
   414  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = true })
   415  
   416  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   417  	defer func() {
   418  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   419  	}()
   420  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   421  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   422  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   423  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   424  
   425  	dispName := "myhookinc"
   426  	inHookStruct := &model.IncomingWebhook{DisplayName: dispName, ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId}
   427  	incomingHook, resp := adminClient.CreateIncomingWebhook(inHookStruct)
   428  	api4.CheckNoError(t, resp)
   429  
   430  	dispName2 := "myhookout"
   431  	outHookStruct := &model.OutgoingWebhook{DisplayName: dispName2, ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}, Username: "some-user-name", IconURL: "http://some-icon-url/"}
   432  	outgoingHook, resp := adminClient.CreateOutgoingWebhook(outHookStruct)
   433  	api4.CheckNoError(t, resp)
   434  
   435  	hooksBeforeDeletion := th.CheckCommand(t, "webhook", "list", th.BasicTeam.Name)
   436  
   437  	assert.Contains(t, hooksBeforeDeletion, dispName, "should have incoming webhooks")
   438  	assert.Contains(t, hooksBeforeDeletion, dispName2, "Should have outgoing webhooks")
   439  
   440  	th.CheckCommand(t, "webhook", "delete", incomingHook.Id)
   441  	th.CheckCommand(t, "webhook", "delete", outgoingHook.Id)
   442  
   443  	hooksAfterDeletion := th.CheckCommand(t, "webhook", "list", th.BasicTeam.Name)
   444  
   445  	assert.NotContains(t, hooksAfterDeletion, dispName, "Should not have incoming webhooks")
   446  	assert.NotContains(t, hooksAfterDeletion, dispName2, "Should not have outgoing webhooks")
   447  }
   448  
   449  func TestMoveOutgoingWebhook(t *testing.T) {
   450  	th := Setup(t).InitBasic()
   451  	defer th.TearDown()
   452  
   453  	config := th.Config()
   454  	*config.ServiceSettings.EnableOutgoingWebhooks = true
   455  	th.SetConfig(config)
   456  
   457  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   458  	defer th.RestoreDefaultRolePermissions(defaultRolePermissions)
   459  
   460  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   461  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   462  
   463  	description := "myhookoutdesc"
   464  	displayName := "myhookoutname"
   465  	triggerWords := model.StringArray{"myhookoutword1"}
   466  	triggerWhen := 0
   467  	callbackURLs := model.StringArray{"http://myhookouturl1"}
   468  	iconURL := "myhookicon1"
   469  	contentType := "myhookcontent1"
   470  
   471  	outgoingWebhookWithChannel := &model.OutgoingWebhook{
   472  		CreatorId:    th.BasicUser.Id,
   473  		Username:     th.BasicUser.Username,
   474  		TeamId:       th.BasicTeam.Id,
   475  		ChannelId:    th.BasicChannel.Id,
   476  		DisplayName:  displayName,
   477  		Description:  description,
   478  		TriggerWords: triggerWords,
   479  		TriggerWhen:  triggerWhen,
   480  		CallbackURLs: callbackURLs,
   481  		IconURL:      iconURL,
   482  		ContentType:  contentType,
   483  	}
   484  
   485  	oldHook, err := th.App.CreateOutgoingWebhook(outgoingWebhookWithChannel)
   486  	require.Nil(t, err)
   487  	defer th.App.DeleteOutgoingWebhook(oldHook.Id)
   488  
   489  	require.Error(t, th.RunCommand(t, "webhook", "move-outgoing"))
   490  	require.Error(t, th.RunCommand(t, "webhook", "move-outgoing", th.BasicTeam.Id))
   491  	require.Error(t, th.RunCommand(t, "webhook", "move-outgoing", "invalid-team", "webhook"))
   492  	require.Error(t, th.RunCommand(t, "webhook", "move-outgoing", "invalid-team", "webhook", "--channel"))
   493  
   494  	newTeam := th.CreateTeam()
   495  
   496  	webhookInformation := "oldTeam" + ":" + "webhookId"
   497  	require.Error(t, th.RunCommand(t, "webhook", "move-outgoing", newTeam.Id, webhookInformation))
   498  
   499  	webhookInformation = th.BasicTeam.Id + ":" + "webhookId"
   500  	require.Error(t, th.RunCommand(t, "webhook", "move-outgoing", newTeam.Id, webhookInformation))
   501  
   502  	require.Error(t, th.RunCommand(t, "webhook", "move-outgoing", newTeam.Id, th.BasicTeam.Id+":"+oldHook.Id, "--channel", "invalid"))
   503  
   504  	channel := th.CreateChannelWithClientAndTeam(th.SystemAdminClient, model.CHANNEL_OPEN, newTeam.Id)
   505  	th.CheckCommand(t, "webhook", "move-outgoing", newTeam.Id, th.BasicTeam.Id+":"+oldHook.Id, "--channel", channel.Name)
   506  
   507  	_, webhookErr := th.App.GetOutgoingWebhook(oldHook.Id)
   508  	assert.Error(t, webhookErr)
   509  
   510  	output := th.CheckCommand(t, "webhook", "list", newTeam.Name)
   511  	assert.True(t, strings.Contains(output, displayName))
   512  
   513  	outgoingWebhookWithoutChannel := &model.OutgoingWebhook{
   514  		CreatorId:    th.BasicUser.Id,
   515  		Username:     th.BasicUser.Username,
   516  		TeamId:       th.BasicTeam.Id,
   517  		DisplayName:  displayName + "2",
   518  		Description:  description,
   519  		TriggerWords: triggerWords,
   520  		TriggerWhen:  triggerWhen,
   521  		CallbackURLs: callbackURLs,
   522  		IconURL:      iconURL,
   523  		ContentType:  contentType,
   524  	}
   525  
   526  	oldHook2, err := th.App.CreateOutgoingWebhook(outgoingWebhookWithoutChannel)
   527  	require.Nil(t, err)
   528  	defer th.App.DeleteOutgoingWebhook(oldHook2.Id)
   529  
   530  	th.CheckCommand(t, "webhook", "move-outgoing", newTeam.Id, th.BasicTeam.Id+":"+oldHook2.Id)
   531  	output = th.CheckCommand(t, "webhook", "list", newTeam.Name)
   532  	assert.True(t, strings.Contains(output, displayName+"2"))
   533  }