github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+incompatible/api/webhook_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api
     5  
     6  import (
     7  	"fmt"
     8  	"net/http"
     9  	"testing"
    10  
    11  	"github.com/mattermost/mattermost-server/model"
    12  	"github.com/mattermost/mattermost-server/utils"
    13  )
    14  
    15  func TestCreateIncomingHook(t *testing.T) {
    16  	th := Setup().InitSystemAdmin()
    17  	defer th.TearDown()
    18  
    19  	Client := th.SystemAdminClient
    20  	user := th.SystemAdminUser
    21  	team := th.SystemAdminTeam
    22  	channel1 := th.CreateChannel(Client, team)
    23  	channel2 := th.CreatePrivateChannel(Client, team)
    24  	channel3 := th.CreateChannel(Client, team)
    25  	user2 := th.CreateUser(Client)
    26  	th.LinkUserToTeam(user2, team)
    27  
    28  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
    29  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
    30  
    31  	hook := &model.IncomingWebhook{ChannelId: channel1.Id}
    32  
    33  	var rhook *model.IncomingWebhook
    34  	if result, err := Client.CreateIncomingWebhook(hook); err != nil {
    35  		t.Fatal(err)
    36  	} else {
    37  		rhook = result.Data.(*model.IncomingWebhook)
    38  	}
    39  
    40  	if hook.ChannelId != rhook.ChannelId {
    41  		t.Fatal("channel ids didn't match")
    42  	}
    43  
    44  	if rhook.UserId != user.Id {
    45  		t.Fatal("user ids didn't match")
    46  	}
    47  
    48  	if rhook.TeamId != team.Id {
    49  		t.Fatal("team ids didn't match")
    50  	}
    51  
    52  	hook = &model.IncomingWebhook{ChannelId: "junk"}
    53  	if _, err := Client.CreateIncomingWebhook(hook); err == nil {
    54  		t.Fatal("should have failed - bad channel id")
    55  	}
    56  
    57  	hook = &model.IncomingWebhook{ChannelId: channel2.Id, UserId: "123", TeamId: "456"}
    58  	if result, err := Client.CreateIncomingWebhook(hook); err != nil {
    59  		t.Fatal(err)
    60  	} else {
    61  		if result.Data.(*model.IncomingWebhook).UserId != user.Id {
    62  			t.Fatal("bad user id wasn't overwritten")
    63  		}
    64  		if result.Data.(*model.IncomingWebhook).TeamId != team.Id {
    65  			t.Fatal("bad team id wasn't overwritten")
    66  		}
    67  	}
    68  
    69  	Client.Must(Client.LeaveChannel(channel3.Id))
    70  
    71  	hook = &model.IncomingWebhook{ChannelId: channel3.Id, UserId: user.Id, TeamId: team.Id}
    72  	if _, err := Client.CreateIncomingWebhook(hook); err != nil {
    73  		t.Fatal(err)
    74  	}
    75  
    76  	Client.Logout()
    77  	Client.Must(Client.LoginById(user2.Id, user2.Password))
    78  	Client.SetTeamId(team.Id)
    79  
    80  	hook = &model.IncomingWebhook{ChannelId: channel1.Id}
    81  
    82  	if _, err := Client.CreateIncomingWebhook(hook); err == nil {
    83  		t.Fatal("should have failed - not system/team admin")
    84  	}
    85  
    86  	Client.Logout()
    87  	th.UpdateUserToTeamAdmin(user2, team)
    88  	Client.Must(Client.LoginById(user2.Id, user2.Password))
    89  	Client.SetTeamId(team.Id)
    90  
    91  	if _, err := Client.CreateIncomingWebhook(hook); err != nil {
    92  		t.Fatal(err)
    93  	}
    94  
    95  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
    96  	th.App.SetDefaultRolesBasedOnConfig()
    97  
    98  	if _, err := Client.CreateIncomingWebhook(hook); err != nil {
    99  		t.Fatal(err)
   100  	}
   101  
   102  	hook = &model.IncomingWebhook{ChannelId: channel2.Id}
   103  
   104  	if _, err := Client.CreateIncomingWebhook(hook); err == nil {
   105  		t.Fatal("should have failed - channel is private and not a member")
   106  	}
   107  
   108  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false })
   109  
   110  	if _, err := Client.CreateIncomingWebhook(hook); err == nil {
   111  		t.Fatal("should have errored - webhooks turned off")
   112  	}
   113  }
   114  
   115  func TestUpdateIncomingHook(t *testing.T) {
   116  	th := Setup().InitSystemAdmin()
   117  	defer th.TearDown()
   118  
   119  	Client := th.SystemAdminClient
   120  	team := th.SystemAdminTeam
   121  
   122  	channel1 := th.CreateChannel(Client, team)
   123  	channel2 := th.CreatePrivateChannel(Client, team)
   124  	channel3 := th.CreateChannel(Client, team)
   125  
   126  	user2 := th.CreateUser(Client)
   127  	th.LinkUserToTeam(user2, team)
   128  
   129  	team2 := th.CreateTeam(Client)
   130  	user3 := th.CreateUser(Client)
   131  	th.LinkUserToTeam(user3, team2)
   132  	th.UpdateUserToTeamAdmin(user3, team2)
   133  
   134  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   135  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   136  	th.App.SetDefaultRolesBasedOnConfig()
   137  
   138  	hook := createIncomingWebhook(channel1.Id, Client, t)
   139  
   140  	t.Run("UpdateIncomingHook", func(t *testing.T) {
   141  		hook.DisplayName = "hook2"
   142  		hook.Description = "description"
   143  		hook.ChannelId = channel3.Id
   144  
   145  		if result, err := Client.UpdateIncomingWebhook(hook); err != nil {
   146  			t.Fatal("Update hook should not fail")
   147  		} else {
   148  			updatedHook := result.Data.(*model.IncomingWebhook)
   149  
   150  			if updatedHook.DisplayName != "hook2" {
   151  				t.Fatal("Hook name is not updated")
   152  			}
   153  
   154  			if updatedHook.Description != "description" {
   155  				t.Fatal("Hook description is not updated")
   156  			}
   157  
   158  			if updatedHook.ChannelId != channel3.Id {
   159  				t.Fatal("Hook channel is not updated")
   160  			}
   161  		}
   162  	})
   163  
   164  	t.Run("RetainCreateAt", func(t *testing.T) {
   165  		hook2 := &model.IncomingWebhook{ChannelId: channel1.Id, CreateAt: 100}
   166  
   167  		if result, err := Client.CreateIncomingWebhook(hook2); err != nil {
   168  			t.Fatal("hook creation failed")
   169  		} else {
   170  			createdHook := result.Data.(*model.IncomingWebhook)
   171  			createdHook.DisplayName = "Name2"
   172  
   173  			if result, err := Client.UpdateIncomingWebhook(createdHook); err != nil {
   174  				t.Fatal("Update hook should not fail")
   175  			} else {
   176  				updatedHook := result.Data.(*model.IncomingWebhook)
   177  
   178  				if updatedHook.CreateAt != createdHook.CreateAt {
   179  					t.Fatal("failed - hook create at should not be changed")
   180  				}
   181  			}
   182  		}
   183  	})
   184  
   185  	t.Run("ModifyUpdateAt", func(t *testing.T) {
   186  		hook.DisplayName = "Name3"
   187  
   188  		if result, err := Client.UpdateIncomingWebhook(hook); err != nil {
   189  			t.Fatal("Update hook should not fail")
   190  		} else {
   191  			updatedHook := result.Data.(*model.IncomingWebhook)
   192  
   193  			if updatedHook.UpdateAt == hook.UpdateAt {
   194  				t.Fatal("failed - hook updateAt is not updated")
   195  			}
   196  		}
   197  	})
   198  
   199  	t.Run("UpdateNonExistentHook", func(t *testing.T) {
   200  		nonExistentHook := &model.IncomingWebhook{ChannelId: channel1.Id}
   201  
   202  		if _, err := Client.UpdateIncomingWebhook(nonExistentHook); err == nil {
   203  			t.Fatal("should have failed - update a non-existent hook")
   204  		}
   205  	})
   206  
   207  	Client.Logout()
   208  	Client.Must(Client.LoginById(user2.Id, user2.Password))
   209  	Client.SetTeamId(team.Id)
   210  	t.Run("UserIsNotAdminOfTeam", func(t *testing.T) {
   211  		if _, err := Client.UpdateIncomingWebhook(hook); err == nil {
   212  			t.Fatal("should have failed - user is not admin of team")
   213  		}
   214  	})
   215  
   216  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   217  
   218  	t.Run("OnlyAdminIntegrationsDisabled", func(t *testing.T) {
   219  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   220  		th.App.SetDefaultRolesBasedOnConfig()
   221  
   222  		t.Run("UpdateHookOfSameUser", func(t *testing.T) {
   223  			sameUserHook := &model.IncomingWebhook{ChannelId: channel1.Id, UserId: user2.Id}
   224  			if result, err := Client.CreateIncomingWebhook(sameUserHook); err != nil {
   225  				t.Fatal("Hook creation failed")
   226  			} else {
   227  				sameUserHook = result.Data.(*model.IncomingWebhook)
   228  			}
   229  
   230  			if _, err := Client.UpdateIncomingWebhook(sameUserHook); err != nil {
   231  				t.Fatal("should not fail - only admin integrations are disabled & hook of same user")
   232  			}
   233  		})
   234  
   235  		t.Run("UpdateHookOfDifferentUser", func(t *testing.T) {
   236  			if _, err := Client.UpdateIncomingWebhook(hook); err == nil {
   237  				t.Fatal("should have failed - user does not have permissions to update other user's hooks")
   238  			}
   239  		})
   240  	})
   241  
   242  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   243  	th.App.SetDefaultRolesBasedOnConfig()
   244  
   245  	Client.Logout()
   246  	th.UpdateUserToTeamAdmin(user2, team)
   247  	Client.Must(Client.LoginById(user2.Id, user2.Password))
   248  	Client.SetTeamId(team.Id)
   249  	t.Run("UpdateByDifferentUser", func(t *testing.T) {
   250  		if result, err := Client.UpdateIncomingWebhook(hook); err != nil {
   251  			t.Fatal("Update hook should not fail")
   252  		} else {
   253  			updatedHook := result.Data.(*model.IncomingWebhook)
   254  
   255  			if updatedHook.UserId == user2.Id {
   256  				t.Fatal("Hook's creator userId is not retained")
   257  			}
   258  		}
   259  	})
   260  
   261  	t.Run("IncomingHooksDisabled", func(t *testing.T) {
   262  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false })
   263  		if _, err := Client.UpdateIncomingWebhook(hook); err == nil {
   264  			t.Fatal("should have failed - incoming hooks are disabled")
   265  		}
   266  	})
   267  
   268  	t.Run("PrivateChannel", func(t *testing.T) {
   269  		hook.ChannelId = channel2.Id
   270  
   271  		if _, err := Client.UpdateIncomingWebhook(hook); err == nil {
   272  			t.Fatal("should have failed - updating to a private channel where the user is not a member")
   273  		}
   274  	})
   275  
   276  	t.Run("UpdateToNonExistentChannel", func(t *testing.T) {
   277  		hook.ChannelId = "junk"
   278  		if _, err := Client.UpdateIncomingWebhook(hook); err == nil {
   279  			t.Fatal("should have failed - bad channel id")
   280  		}
   281  	})
   282  
   283  	Client.Logout()
   284  	Client.Must(Client.LoginById(user3.Id, user3.Password))
   285  	Client.SetTeamId(team2.Id)
   286  	t.Run("UpdateToADifferentTeam", func(t *testing.T) {
   287  		if _, err := Client.UpdateIncomingWebhook(hook); err == nil {
   288  			t.Fatal("should have failed - update to a different team is not allowed")
   289  		}
   290  	})
   291  }
   292  
   293  func createIncomingWebhook(channelID string, Client *model.Client, t *testing.T) *model.IncomingWebhook {
   294  	hook := &model.IncomingWebhook{ChannelId: channelID}
   295  	if result, err := Client.CreateIncomingWebhook(hook); err != nil {
   296  		t.Fatal("Hook creation failed")
   297  	} else {
   298  		hook = result.Data.(*model.IncomingWebhook)
   299  	}
   300  
   301  	return hook
   302  }
   303  
   304  func createOutgoingWebhook(channelID string, callbackURLs []string, triggerWords []string, Client *model.Client, t *testing.T) *model.OutgoingWebhook {
   305  	hook := &model.OutgoingWebhook{ChannelId: channelID, CallbackURLs: callbackURLs, TriggerWords: triggerWords}
   306  	if result, err := Client.CreateOutgoingWebhook(hook); err != nil {
   307  		t.Fatal("Hook creation failed")
   308  	} else {
   309  		hook = result.Data.(*model.OutgoingWebhook)
   310  	}
   311  
   312  	return hook
   313  }
   314  
   315  func TestListIncomingHooks(t *testing.T) {
   316  	th := Setup().InitSystemAdmin()
   317  	defer th.TearDown()
   318  
   319  	Client := th.SystemAdminClient
   320  	team := th.SystemAdminTeam
   321  	channel1 := th.CreateChannel(Client, team)
   322  	user2 := th.CreateUser(Client)
   323  	th.LinkUserToTeam(user2, team)
   324  
   325  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   326  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   327  	th.App.SetDefaultRolesBasedOnConfig()
   328  
   329  	hook1 := &model.IncomingWebhook{ChannelId: channel1.Id}
   330  	hook1 = Client.Must(Client.CreateIncomingWebhook(hook1)).Data.(*model.IncomingWebhook)
   331  
   332  	hook2 := &model.IncomingWebhook{ChannelId: channel1.Id}
   333  	hook2 = Client.Must(Client.CreateIncomingWebhook(hook2)).Data.(*model.IncomingWebhook)
   334  
   335  	if result, err := Client.ListIncomingWebhooks(); err != nil {
   336  		t.Fatal(err)
   337  	} else {
   338  		hooks := result.Data.([]*model.IncomingWebhook)
   339  
   340  		if len(hooks) != 2 {
   341  			t.Fatal("incorrect number of hooks")
   342  		}
   343  	}
   344  
   345  	Client.Logout()
   346  	Client.Must(Client.LoginById(user2.Id, user2.Password))
   347  	Client.SetTeamId(team.Id)
   348  
   349  	if _, err := Client.ListIncomingWebhooks(); err == nil {
   350  		t.Fatal("should have errored - not system/team admin")
   351  	}
   352  
   353  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   354  	th.App.SetDefaultRolesBasedOnConfig()
   355  
   356  	if _, err := Client.ListIncomingWebhooks(); err != nil {
   357  		t.Fatal(err)
   358  	}
   359  
   360  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false })
   361  
   362  	if _, err := Client.ListIncomingWebhooks(); err == nil {
   363  		t.Fatal("should have errored - webhooks turned off")
   364  	}
   365  }
   366  
   367  func TestDeleteIncomingHook(t *testing.T) {
   368  	th := Setup().InitSystemAdmin()
   369  	defer th.TearDown()
   370  
   371  	Client := th.SystemAdminClient
   372  	team := th.SystemAdminTeam
   373  	channel1 := th.CreateChannel(Client, team)
   374  	user2 := th.CreateUser(Client)
   375  	th.LinkUserToTeam(user2, team)
   376  
   377  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   378  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   379  	th.App.SetDefaultRolesBasedOnConfig()
   380  
   381  	hook := &model.IncomingWebhook{ChannelId: channel1.Id}
   382  	hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
   383  
   384  	if _, err := Client.DeleteIncomingWebhook(hook.Id); err != nil {
   385  		t.Fatal(err)
   386  	}
   387  
   388  	if _, err := Client.DeleteIncomingWebhook("junk"); err == nil {
   389  		t.Fatal("should have failed - bad id")
   390  	}
   391  
   392  	if _, err := Client.DeleteIncomingWebhook(""); err == nil {
   393  		t.Fatal("should have failed - empty id")
   394  	}
   395  
   396  	hooks := Client.Must(Client.ListIncomingWebhooks()).Data.([]*model.IncomingWebhook)
   397  	if len(hooks) != 0 {
   398  		t.Fatal("delete didn't work properly")
   399  	}
   400  
   401  	hook = &model.IncomingWebhook{ChannelId: channel1.Id}
   402  	hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
   403  
   404  	Client.Logout()
   405  	Client.Must(Client.LoginById(user2.Id, user2.Password))
   406  	Client.SetTeamId(team.Id)
   407  
   408  	if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil {
   409  		t.Fatal("should have failed - not system/team admin")
   410  	}
   411  
   412  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   413  	th.App.SetDefaultRolesBasedOnConfig()
   414  
   415  	if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil {
   416  		t.Fatal("should have failed - not creator or team admin")
   417  	}
   418  
   419  	hook = &model.IncomingWebhook{ChannelId: channel1.Id}
   420  	hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
   421  
   422  	if _, err := Client.DeleteIncomingWebhook(hook.Id); err != nil {
   423  		t.Fatal(err)
   424  	}
   425  
   426  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false })
   427  
   428  	if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil {
   429  		t.Fatal("should have errored - webhooks turned off")
   430  	}
   431  }
   432  
   433  func TestCreateOutgoingHook(t *testing.T) {
   434  	th := Setup().InitSystemAdmin()
   435  	defer th.TearDown()
   436  
   437  	Client := th.SystemAdminClient
   438  	user := th.SystemAdminUser
   439  	team := th.SystemAdminTeam
   440  	team2 := th.CreateTeam(Client)
   441  	channel1 := th.CreateChannel(Client, team)
   442  	channel2 := th.CreatePrivateChannel(Client, team)
   443  	user2 := th.CreateUser(Client)
   444  	th.LinkUserToTeam(user2, team)
   445  	user3 := th.CreateUser(Client)
   446  	th.LinkUserToTeam(user3, team2)
   447  
   448  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   449  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   450  	th.App.SetDefaultRolesBasedOnConfig()
   451  
   452  	hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
   453  
   454  	var rhook *model.OutgoingWebhook
   455  	if result, err := Client.CreateOutgoingWebhook(hook); err != nil {
   456  		t.Fatal(err)
   457  	} else {
   458  		rhook = result.Data.(*model.OutgoingWebhook)
   459  	}
   460  
   461  	if hook.ChannelId != rhook.ChannelId {
   462  		t.Fatal("channel ids didn't match")
   463  	}
   464  
   465  	if rhook.CreatorId != user.Id {
   466  		t.Fatal("user ids didn't match")
   467  	}
   468  
   469  	if rhook.TeamId != team.Id {
   470  		t.Fatal("team ids didn't match")
   471  	}
   472  
   473  	hook = &model.OutgoingWebhook{ChannelId: channel1.Id, TriggerWords: []string{"cats", "dogs"}, CallbackURLs: []string{"http://nowhere.com", "http://cats.com"}}
   474  	hook1 := &model.OutgoingWebhook{ChannelId: channel1.Id, TriggerWords: []string{"cats"}, CallbackURLs: []string{"http://nowhere.com"}}
   475  
   476  	if _, err := Client.CreateOutgoingWebhook(hook); err != nil {
   477  		t.Fatal("multiple trigger words and urls failed")
   478  	}
   479  
   480  	if _, err := Client.CreateOutgoingWebhook(hook1); err == nil {
   481  		t.Fatal("should have failed - duplicate trigger words and urls")
   482  	}
   483  
   484  	hook = &model.OutgoingWebhook{ChannelId: "junk", CallbackURLs: []string{"http://nowhere.com"}}
   485  	if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
   486  		t.Fatal("should have failed - bad channel id")
   487  	}
   488  
   489  	hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CreatorId: "123", TeamId: "456", CallbackURLs: []string{"http://nowhere.com"}}
   490  	if result, err := Client.CreateOutgoingWebhook(hook); err != nil {
   491  		t.Fatal(err)
   492  	} else {
   493  		if result.Data.(*model.OutgoingWebhook).CreatorId != user.Id {
   494  			t.Fatal("bad user id wasn't overwritten")
   495  		}
   496  		if result.Data.(*model.OutgoingWebhook).TeamId != team.Id {
   497  			t.Fatal("bad team id wasn't overwritten")
   498  		}
   499  	}
   500  
   501  	hook = &model.OutgoingWebhook{ChannelId: channel2.Id, CallbackURLs: []string{"http://nowhere.com"}}
   502  	if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
   503  		t.Fatal("should have failed - private channel")
   504  	}
   505  
   506  	hook = &model.OutgoingWebhook{CallbackURLs: []string{"http://nowhere.com"}}
   507  	if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
   508  		t.Fatal("should have failed - blank channel and trigger words")
   509  	}
   510  
   511  	Client.Logout()
   512  	Client.Must(Client.LoginById(user2.Id, user2.Password))
   513  	Client.SetTeamId(team.Id)
   514  
   515  	hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
   516  	if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
   517  		t.Fatal("should have failed - not system/team admin")
   518  	}
   519  
   520  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   521  	th.App.SetDefaultRolesBasedOnConfig()
   522  
   523  	if _, err := Client.CreateOutgoingWebhook(hook); err != nil {
   524  		t.Fatal(err)
   525  	}
   526  
   527  	Client.Logout()
   528  	Client.Must(Client.LoginById(user3.Id, user3.Password))
   529  	Client.SetTeamId(team2.Id)
   530  
   531  	if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
   532  		t.Fatal("should have failed - wrong team")
   533  	}
   534  
   535  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   536  
   537  	if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
   538  		t.Fatal("should have errored - webhooks turned off")
   539  	}
   540  }
   541  
   542  func TestListOutgoingHooks(t *testing.T) {
   543  	th := Setup().InitSystemAdmin()
   544  	defer th.TearDown()
   545  
   546  	Client := th.SystemAdminClient
   547  	team := th.SystemAdminTeam
   548  	channel1 := th.CreateChannel(Client, team)
   549  	user2 := th.CreateUser(Client)
   550  	th.LinkUserToTeam(user2, team)
   551  
   552  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   553  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   554  	th.App.SetDefaultRolesBasedOnConfig()
   555  
   556  	hook1 := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
   557  	hook1 = Client.Must(Client.CreateOutgoingWebhook(hook1)).Data.(*model.OutgoingWebhook)
   558  
   559  	hook2 := &model.OutgoingWebhook{TriggerWords: []string{"trigger"}, CallbackURLs: []string{"http://nowhere.com"}}
   560  	hook2 = Client.Must(Client.CreateOutgoingWebhook(hook2)).Data.(*model.OutgoingWebhook)
   561  
   562  	if result, err := Client.ListOutgoingWebhooks(); err != nil {
   563  		t.Fatal(err)
   564  	} else {
   565  		hooks := result.Data.([]*model.OutgoingWebhook)
   566  
   567  		if len(hooks) != 2 {
   568  			t.Fatal("incorrect number of hooks")
   569  		}
   570  	}
   571  
   572  	Client.Logout()
   573  	Client.Must(Client.LoginById(user2.Id, user2.Password))
   574  	Client.SetTeamId(team.Id)
   575  
   576  	if _, err := Client.ListOutgoingWebhooks(); err == nil {
   577  		t.Fatal("should have failed - not system/team admin")
   578  	}
   579  
   580  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   581  	th.App.SetDefaultRolesBasedOnConfig()
   582  
   583  	if _, err := Client.ListOutgoingWebhooks(); err != nil {
   584  		t.Fatal(err)
   585  	}
   586  
   587  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   588  
   589  	if _, err := Client.ListOutgoingWebhooks(); err == nil {
   590  		t.Fatal("should have errored - webhooks turned off")
   591  	}
   592  }
   593  
   594  func TestUpdateOutgoingHook(t *testing.T) {
   595  	th := Setup().InitSystemAdmin()
   596  	defer th.TearDown()
   597  
   598  	Client := th.SystemAdminClient
   599  	user := th.SystemAdminUser
   600  	team := th.SystemAdminTeam
   601  	team2 := th.CreateTeam(Client)
   602  	channel1 := th.CreateChannel(Client, team)
   603  	channel2 := th.CreatePrivateChannel(Client, team)
   604  	channel3 := th.CreateChannel(Client, team)
   605  	user2 := th.CreateUser(Client)
   606  	th.LinkUserToTeam(user2, team)
   607  	user3 := th.CreateUser(Client)
   608  	th.LinkUserToTeam(user3, team2)
   609  
   610  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   611  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   612  	th.App.SetDefaultRolesBasedOnConfig()
   613  
   614  	hook := createOutgoingWebhook(channel1.Id, []string{"http://nowhere.com"}, []string{"cats"}, Client, t)
   615  	createOutgoingWebhook(channel1.Id, []string{"http://nowhere.com"}, []string{"dogs"}, Client, t)
   616  
   617  	hook.DisplayName = "Cats"
   618  	hook.Description = "Get me some cats"
   619  	t.Run("OutgoingHooksDisabled", func(t *testing.T) {
   620  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   621  		if _, err := Client.UpdateOutgoingWebhook(hook); err == nil {
   622  			t.Fatal("should have failed - outgoing webhooks disabled")
   623  		}
   624  	})
   625  
   626  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   627  	t.Run("UpdateOutgoingWebhook", func(t *testing.T) {
   628  		if result, err := Client.UpdateOutgoingWebhook(hook); err != nil {
   629  			t.Fatal("failed to update outgoing web hook")
   630  		} else {
   631  			updatedHook := result.Data.(*model.OutgoingWebhook)
   632  
   633  			if updatedHook.DisplayName != hook.DisplayName {
   634  				t.Fatal("Hook display name did not get updated")
   635  			}
   636  
   637  			if updatedHook.Description != hook.Description {
   638  				t.Fatal("Hook description did not get updated")
   639  			}
   640  		}
   641  	})
   642  
   643  	t.Run("RetainCreateAt", func(t *testing.T) {
   644  		hook2 := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats"}}
   645  
   646  		if result, err := Client.CreateOutgoingWebhook(hook2); err != nil {
   647  			t.Fatal("hook creation failed")
   648  		} else {
   649  			createdHook := result.Data.(*model.OutgoingWebhook)
   650  			createdHook.DisplayName = "Name2"
   651  
   652  			if result, err := Client.UpdateOutgoingWebhook(createdHook); err != nil {
   653  				t.Fatal("Update hook should not fail")
   654  			} else {
   655  				updatedHook := result.Data.(*model.OutgoingWebhook)
   656  
   657  				if updatedHook.CreateAt != createdHook.CreateAt {
   658  					t.Fatal("failed - hook create at should not be changed")
   659  				}
   660  			}
   661  		}
   662  	})
   663  
   664  	t.Run("ModifyUpdateAt", func(t *testing.T) {
   665  		hook.DisplayName = "Name3"
   666  
   667  		if result, err := Client.UpdateOutgoingWebhook(hook); err != nil {
   668  			t.Fatal("Update hook should not fail")
   669  		} else {
   670  			updatedHook := result.Data.(*model.OutgoingWebhook)
   671  
   672  			if updatedHook.UpdateAt == hook.UpdateAt {
   673  				t.Fatal("failed - hook updateAt is not updated")
   674  			}
   675  		}
   676  	})
   677  
   678  	Client.Logout()
   679  	Client.Must(Client.LoginById(user2.Id, user2.Password))
   680  	Client.SetTeamId(team.Id)
   681  	if _, err := Client.UpdateOutgoingWebhook(hook); err == nil {
   682  		t.Fatal("should have failed - user does not have permissions to manage webhooks")
   683  	}
   684  
   685  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   686  	th.App.SetDefaultRolesBasedOnConfig()
   687  	hook2 := createOutgoingWebhook(channel1.Id, []string{"http://nowhereelse.com"}, []string{"dogs"}, Client, t)
   688  
   689  	if _, err := Client.UpdateOutgoingWebhook(hook2); err != nil {
   690  		t.Fatal("update webhook failed when admin only integrations is turned off")
   691  	}
   692  
   693  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   694  	th.App.SetDefaultRolesBasedOnConfig()
   695  
   696  	Client.Logout()
   697  	th.LinkUserToTeam(user3, team)
   698  	th.UpdateUserToTeamAdmin(user3, team)
   699  	Client.Must(Client.LoginById(user3.Id, user3.Password))
   700  	Client.SetTeamId(team.Id)
   701  	t.Run("RetainHookCreator", func(t *testing.T) {
   702  		if result, err := Client.UpdateOutgoingWebhook(hook); err != nil {
   703  			t.Fatal("failed to update outgoing web hook")
   704  		} else {
   705  			updatedHook := result.Data.(*model.OutgoingWebhook)
   706  
   707  			if updatedHook.CreatorId != user.Id {
   708  				t.Fatal("hook creator should not be changed")
   709  			}
   710  		}
   711  	})
   712  
   713  	Client.Logout()
   714  	Client.Must(Client.LoginById(user.Id, user.Password))
   715  	Client.SetTeamId(team.Id)
   716  	t.Run("UpdateToExistingTriggerWordAndCallback", func(t *testing.T) {
   717  		t.Run("OnSameChannel", func(t *testing.T) {
   718  			hook.TriggerWords = []string{"dogs"}
   719  
   720  			if _, err := Client.UpdateOutgoingWebhook(hook); err == nil {
   721  				t.Fatal("should have failed - duplicate trigger words & channel urls")
   722  			}
   723  		})
   724  
   725  		t.Run("OnDifferentChannel", func(t *testing.T) {
   726  			hook.TriggerWords = []string{"dogs"}
   727  			hook.ChannelId = channel3.Id
   728  
   729  			if _, err := Client.UpdateOutgoingWebhook(hook); err != nil {
   730  				t.Fatal("update of hook failed with duplicate trigger word but different channel")
   731  			}
   732  		})
   733  	})
   734  
   735  	t.Run("UpdateToNonExistentChannel", func(t *testing.T) {
   736  		hook.ChannelId = "junk"
   737  
   738  		if _, err := Client.UpdateOutgoingWebhook(hook); err == nil {
   739  			t.Fatal("should have failed - non existent channel")
   740  		}
   741  	})
   742  
   743  	t.Run("UpdateToPrivateChannel", func(t *testing.T) {
   744  		hook.ChannelId = channel2.Id
   745  
   746  		if _, err := Client.UpdateOutgoingWebhook(hook); err == nil {
   747  			t.Fatal("should have failed - update to a private channel")
   748  		}
   749  	})
   750  
   751  	t.Run("UpdateToBlankTriggerWordAndChannel", func(t *testing.T) {
   752  		hook.ChannelId = ""
   753  		hook.TriggerWords = nil
   754  
   755  		if _, err := Client.UpdateOutgoingWebhook(hook); err == nil {
   756  			t.Fatal("should have failed - update to blank trigger words & channel")
   757  		}
   758  	})
   759  
   760  	Client.Logout()
   761  	Client.Must(Client.LoginById(user3.Id, user3.Password))
   762  	Client.SetTeamId(team2.Id)
   763  	t.Run("UpdateToADifferentTeam", func(t *testing.T) {
   764  		if _, err := Client.UpdateOutgoingWebhook(hook); err == nil {
   765  			t.Fatal("should have failed - update to a different team is not allowed")
   766  		}
   767  	})
   768  }
   769  
   770  func TestDeleteOutgoingHook(t *testing.T) {
   771  	th := Setup().InitSystemAdmin()
   772  	defer th.TearDown()
   773  
   774  	Client := th.SystemAdminClient
   775  	team := th.SystemAdminTeam
   776  	channel1 := th.CreateChannel(Client, team)
   777  	user2 := th.CreateUser(Client)
   778  	th.LinkUserToTeam(user2, team)
   779  
   780  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   781  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   782  	th.App.SetDefaultRolesBasedOnConfig()
   783  
   784  	hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
   785  	hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
   786  
   787  	if _, err := Client.DeleteOutgoingWebhook("junk"); err == nil {
   788  		t.Fatal("should have failed - bad hook id")
   789  	}
   790  
   791  	if _, err := Client.DeleteOutgoingWebhook(""); err == nil {
   792  		t.Fatal("should have failed - empty hook id")
   793  	}
   794  
   795  	if _, err := Client.DeleteOutgoingWebhook(hook.Id); err != nil {
   796  		t.Fatal(err)
   797  	}
   798  
   799  	hooks := Client.Must(Client.ListOutgoingWebhooks()).Data.([]*model.OutgoingWebhook)
   800  	if len(hooks) != 0 {
   801  		t.Fatal("delete didn't work properly")
   802  	}
   803  
   804  	hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
   805  	hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
   806  
   807  	Client.Logout()
   808  	Client.Must(Client.LoginById(user2.Id, user2.Password))
   809  	Client.SetTeamId(team.Id)
   810  
   811  	if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil {
   812  		t.Fatal("should have failed - not system/team admin")
   813  	}
   814  
   815  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   816  	th.App.SetDefaultRolesBasedOnConfig()
   817  
   818  	if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil {
   819  		t.Fatal("should have failed - not creator or team admin")
   820  	}
   821  
   822  	hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
   823  	hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
   824  
   825  	if _, err := Client.DeleteOutgoingWebhook(hook.Id); err != nil {
   826  		t.Fatal(err)
   827  	}
   828  
   829  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   830  
   831  	if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil {
   832  		t.Fatal("should have errored - webhooks turned off")
   833  	}
   834  }
   835  
   836  func TestRegenOutgoingHookToken(t *testing.T) {
   837  	th := Setup().InitSystemAdmin()
   838  	defer th.TearDown()
   839  
   840  	Client := th.SystemAdminClient
   841  	team := th.SystemAdminTeam
   842  	team2 := th.CreateTeam(Client)
   843  	channel1 := th.CreateChannel(Client, team)
   844  	user2 := th.CreateUser(Client)
   845  	th.LinkUserToTeam(user2, team)
   846  	user3 := th.CreateUser(Client)
   847  	th.LinkUserToTeam(user3, team2)
   848  
   849  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   850  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
   851  	th.App.SetDefaultRolesBasedOnConfig()
   852  
   853  	hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
   854  	hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
   855  
   856  	if _, err := Client.RegenOutgoingWebhookToken("junk"); err == nil {
   857  		t.Fatal("should have failed - bad id")
   858  	}
   859  
   860  	if _, err := Client.RegenOutgoingWebhookToken(""); err == nil {
   861  		t.Fatal("should have failed - empty id")
   862  	}
   863  
   864  	if result, err := Client.RegenOutgoingWebhookToken(hook.Id); err != nil {
   865  		t.Fatal(err)
   866  	} else {
   867  		if result.Data.(*model.OutgoingWebhook).Token == hook.Token {
   868  			t.Fatal("regen didn't work properly")
   869  		}
   870  	}
   871  
   872  	Client.SetTeamId(model.NewId())
   873  	if _, err := Client.RegenOutgoingWebhookToken(hook.Id); err == nil {
   874  		t.Fatal("should have failed - wrong team id")
   875  	}
   876  
   877  	Client.Logout()
   878  	Client.Must(Client.LoginById(user2.Id, user2.Password))
   879  	Client.SetTeamId(team.Id)
   880  
   881  	if _, err := Client.RegenOutgoingWebhookToken(hook.Id); err == nil {
   882  		t.Fatal("should have failed - not system/team admin")
   883  	}
   884  
   885  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
   886  	th.App.SetDefaultRolesBasedOnConfig()
   887  
   888  	hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
   889  	hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
   890  
   891  	if _, err := Client.RegenOutgoingWebhookToken(hook.Id); err != nil {
   892  		t.Fatal(err)
   893  	}
   894  
   895  	Client.Logout()
   896  	Client.Must(Client.LoginById(user3.Id, user3.Password))
   897  	Client.SetTeamId(team2.Id)
   898  
   899  	if _, err := Client.RegenOutgoingWebhookToken(hook.Id); err == nil {
   900  		t.Fatal("should have failed - wrong team")
   901  	}
   902  
   903  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   904  
   905  	if _, err := Client.RegenOutgoingWebhookToken(hook.Id); err == nil {
   906  		t.Fatal("should have errored - webhooks turned off")
   907  	}
   908  }
   909  
   910  func TestIncomingWebhooks(t *testing.T) {
   911  	th := Setup().InitBasic().InitSystemAdmin()
   912  	defer th.TearDown()
   913  
   914  	Client := th.SystemAdminClient
   915  	team := th.SystemAdminTeam
   916  	channel1 := th.CreateChannel(Client, team)
   917  	user2 := th.CreateUser(Client)
   918  	th.LinkUserToTeam(user2, team)
   919  
   920  	enableIncomingHooks := th.App.Config().ServiceSettings.EnableIncomingWebhooks
   921  	defer func() {
   922  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks })
   923  	}()
   924  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   925  
   926  	hook := &model.IncomingWebhook{ChannelId: channel1.Id}
   927  	hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
   928  
   929  	url := "/hooks/" + hook.Id
   930  	text := `this is a \"test\"
   931  	that contains a newline and a tab`
   932  
   933  	if _, err := Client.DoPost(url, "{\"text\":\"this is a test\"}", "application/json"); err != nil {
   934  		t.Fatal(err)
   935  	}
   936  
   937  	if _, err := Client.DoPost(url, "{\"text\":\""+text+"\"}", "application/json"); err != nil {
   938  		t.Fatal(err)
   939  	}
   940  
   941  	if _, err := Client.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", channel1.Name), "application/json"); err != nil {
   942  		t.Fatal(err)
   943  	}
   944  
   945  	if _, err := Client.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"#%s\"}", channel1.Name), "application/json"); err != nil {
   946  		t.Fatal(err)
   947  	}
   948  
   949  	if _, err := Client.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"@%s\"}", user2.Username), "application/json"); err != nil {
   950  		t.Fatal(err)
   951  	}
   952  
   953  	if _, err := Client.DoPost(url, "payload={\"text\":\"this is a test\"}", "application/x-www-form-urlencoded"); err != nil {
   954  		t.Fatal(err)
   955  	}
   956  
   957  	if _, err := Client.DoPost(url, "payload={\"text\":\""+text+"\"}", "application/x-www-form-urlencoded"); err != nil {
   958  		t.Fatal(err)
   959  	}
   960  
   961  	if _, err := th.BasicClient.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", model.DEFAULT_CHANNEL), "application/json"); err != nil {
   962  		t.Fatal("should not have failed -- ExperimentalTownSquareIsReadOnly is false and it's not a read only channel")
   963  	}
   964  
   965  	isLicensed := utils.IsLicensed()
   966  	license := utils.License()
   967  	disableTownSquareReadOnly := th.App.Config().TeamSettings.ExperimentalTownSquareIsReadOnly
   968  	defer func() {
   969  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = disableTownSquareReadOnly })
   970  		utils.SetIsLicensed(isLicensed)
   971  		utils.SetLicense(license)
   972  		th.App.SetDefaultRolesBasedOnConfig()
   973  	}()
   974  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true })
   975  	th.App.SetDefaultRolesBasedOnConfig()
   976  	utils.SetIsLicensed(true)
   977  	utils.SetLicense(&model.License{Features: &model.Features{}})
   978  	utils.License().Features.SetDefaults()
   979  
   980  	if _, err := th.BasicClient.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", model.DEFAULT_CHANNEL), "application/json"); err == nil {
   981  		t.Fatal("should have failed -- ExperimentalTownSquareIsReadOnly is true and it's a read only channel")
   982  	}
   983  
   984  	attachmentPayload := `{
   985  	       "text": "this is a test",
   986  	       "attachments": [
   987  	           {
   988  	               "fallback": "Required plain-text summary of the attachment.",
   989  
   990  	               "color": "#36a64f",
   991  
   992  	               "pretext": "Optional text that appears above the attachment block",
   993  
   994  	               "author_name": "Bobby Tables",
   995  	               "author_link": "http://flickr.com/bobby/",
   996  	               "author_icon": "http://flickr.com/icons/bobby.jpg",
   997  
   998  	               "title": "Slack API Documentation",
   999  	               "title_link": "https://api.slack.com/",
  1000  
  1001  	               "text": "Optional text that appears within the attachment",
  1002  
  1003  	               "fields": [
  1004  	                   {
  1005  	                       "title": "Priority",
  1006  	                       "value": "High",
  1007  	                       "short": false
  1008  	                   }
  1009  	               ],
  1010  
  1011  	               "image_url": "http://my-website.com/path/to/image.jpg",
  1012  	               "thumb_url": "http://example.com/path/to/thumb.png"
  1013  	           }
  1014  	       ]
  1015  	   }`
  1016  
  1017  	if _, err := Client.DoPost(url, attachmentPayload, "application/json"); err != nil {
  1018  		t.Fatal(err)
  1019  	}
  1020  
  1021  	if _, err := Client.DoPost(url, "{\"text\":\"\"}", "application/json"); err == nil || err.StatusCode != http.StatusBadRequest {
  1022  		t.Fatal("should have failed - no text")
  1023  	}
  1024  
  1025  	tooLongText := ""
  1026  	for i := 0; i < 8200; i++ {
  1027  		tooLongText += "a"
  1028  	}
  1029  
  1030  	if _, err := Client.DoPost(url, "{\"text\":\""+tooLongText+"\"}", "application/json"); err != nil {
  1031  		t.Fatal(err)
  1032  	}
  1033  
  1034  	attachmentPayload = `{
  1035  	       "text": "this is a test",
  1036  	       "attachments": [
  1037  	           {
  1038  	               "fallback": "Required plain-text summary of the attachment.",
  1039  
  1040  	               "color": "#36a64f",
  1041  
  1042  	               "pretext": "Optional text that appears above the attachment block",
  1043  
  1044  	               "author_name": "Bobby Tables",
  1045  	               "author_link": "http://flickr.com/bobby/",
  1046  	               "author_icon": "http://flickr.com/icons/bobby.jpg",
  1047  
  1048  	               "title": "Slack API Documentation",
  1049  	               "title_link": "https://api.slack.com/",
  1050  
  1051  	               "text": "` + tooLongText + `",
  1052  
  1053  	               "fields": [
  1054  	                   {
  1055  	                       "title": "Priority",
  1056  	                       "value": "High",
  1057  	                       "short": false
  1058  	                   }
  1059  	               ],
  1060  
  1061  	               "image_url": "http://my-website.com/path/to/image.jpg",
  1062  	               "thumb_url": "http://example.com/path/to/thumb.png"
  1063  	           }
  1064  	       ]
  1065  	   }`
  1066  
  1067  	if _, err := Client.DoPost(url, attachmentPayload, "application/json"); err != nil {
  1068  		t.Fatal(err)
  1069  	}
  1070  
  1071  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false })
  1072  
  1073  	if _, err := Client.DoPost(url, "{\"text\":\"this is a test\"}", "application/json"); err == nil {
  1074  		t.Fatal("should have failed - webhooks turned off")
  1075  	}
  1076  }