github.com/lologarithm/mattermost-server@v5.3.2-0.20181002060438-c82a84ed765b+incompatible/app/webhook_test.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/mattermost/mattermost-server/model"
    14  	"net/http"
    15  	"net/http/httptest"
    16  	"time"
    17  )
    18  
    19  func TestCreateIncomingWebhookForChannel(t *testing.T) {
    20  	th := Setup().InitBasic()
    21  	defer th.TearDown()
    22  
    23  	type TestCase struct {
    24  		EnableIncomingHooks        bool
    25  		EnablePostUsernameOverride bool
    26  		EnablePostIconOverride     bool
    27  		IncomingWebhook            model.IncomingWebhook
    28  
    29  		ExpectedError           bool
    30  		ExpectedIncomingWebhook *model.IncomingWebhook
    31  	}
    32  
    33  	for name, tc := range map[string]TestCase{
    34  		"webhooks not enabled": {
    35  			EnableIncomingHooks:        false,
    36  			EnablePostUsernameOverride: false,
    37  			EnablePostIconOverride:     false,
    38  			IncomingWebhook: model.IncomingWebhook{
    39  				DisplayName: "title",
    40  				Description: "description",
    41  				ChannelId:   th.BasicChannel.Id,
    42  			},
    43  
    44  			ExpectedError:           true,
    45  			ExpectedIncomingWebhook: nil,
    46  		},
    47  		"valid: username and post icon url ignored, since override not enabled": {
    48  			EnableIncomingHooks:        true,
    49  			EnablePostUsernameOverride: false,
    50  			EnablePostIconOverride:     false,
    51  			IncomingWebhook: model.IncomingWebhook{
    52  				DisplayName: "title",
    53  				Description: "description",
    54  				ChannelId:   th.BasicChannel.Id,
    55  				Username:    ":invalid and ignored:",
    56  				IconURL:     "ignored",
    57  			},
    58  
    59  			ExpectedError: false,
    60  			ExpectedIncomingWebhook: &model.IncomingWebhook{
    61  				DisplayName: "title",
    62  				Description: "description",
    63  				ChannelId:   th.BasicChannel.Id,
    64  			},
    65  		},
    66  		"invalid username, override enabled": {
    67  			EnableIncomingHooks:        true,
    68  			EnablePostUsernameOverride: true,
    69  			EnablePostIconOverride:     false,
    70  			IncomingWebhook: model.IncomingWebhook{
    71  				DisplayName: "title",
    72  				Description: "description",
    73  				ChannelId:   th.BasicChannel.Id,
    74  				Username:    ":invalid:",
    75  			},
    76  
    77  			ExpectedError:           true,
    78  			ExpectedIncomingWebhook: nil,
    79  		},
    80  		"valid, no username or post icon url provided": {
    81  			EnableIncomingHooks:        true,
    82  			EnablePostUsernameOverride: true,
    83  			EnablePostIconOverride:     true,
    84  			IncomingWebhook: model.IncomingWebhook{
    85  				DisplayName: "title",
    86  				Description: "description",
    87  				ChannelId:   th.BasicChannel.Id,
    88  			},
    89  
    90  			ExpectedError: false,
    91  			ExpectedIncomingWebhook: &model.IncomingWebhook{
    92  				DisplayName: "title",
    93  				Description: "description",
    94  				ChannelId:   th.BasicChannel.Id,
    95  			},
    96  		},
    97  		"valid, with username and post icon": {
    98  			EnableIncomingHooks:        true,
    99  			EnablePostUsernameOverride: true,
   100  			EnablePostIconOverride:     true,
   101  			IncomingWebhook: model.IncomingWebhook{
   102  				DisplayName: "title",
   103  				Description: "description",
   104  				ChannelId:   th.BasicChannel.Id,
   105  				Username:    "valid",
   106  				IconURL:     "http://example.com/icon",
   107  			},
   108  
   109  			ExpectedError: false,
   110  			ExpectedIncomingWebhook: &model.IncomingWebhook{
   111  				DisplayName: "title",
   112  				Description: "description",
   113  				ChannelId:   th.BasicChannel.Id,
   114  				Username:    "valid",
   115  				IconURL:     "http://example.com/icon",
   116  			},
   117  		},
   118  	} {
   119  		t.Run(name, func(t *testing.T) {
   120  			assert := assert.New(t)
   121  
   122  			th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = tc.EnableIncomingHooks })
   123  			th.App.UpdateConfig(func(cfg *model.Config) {
   124  				cfg.ServiceSettings.EnablePostUsernameOverride = tc.EnablePostUsernameOverride
   125  			})
   126  			th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = tc.EnablePostIconOverride })
   127  
   128  			createdHook, err := th.App.CreateIncomingWebhookForChannel(th.BasicUser.Id, th.BasicChannel, &tc.IncomingWebhook)
   129  			if tc.ExpectedError && err == nil {
   130  				t.Fatal("should have failed")
   131  			} else if !tc.ExpectedError && err != nil {
   132  				t.Fatalf("should not have failed: %v", err.Error())
   133  			}
   134  			if createdHook != nil {
   135  				defer th.App.DeleteIncomingWebhook(createdHook.Id)
   136  			}
   137  			if tc.ExpectedIncomingWebhook == nil {
   138  				assert.Nil(createdHook, "expected nil webhook")
   139  			} else if assert.NotNil(createdHook, "expected non-nil webhook") {
   140  				assert.Equal(tc.ExpectedIncomingWebhook.DisplayName, createdHook.DisplayName)
   141  				assert.Equal(tc.ExpectedIncomingWebhook.Description, createdHook.Description)
   142  				assert.Equal(tc.ExpectedIncomingWebhook.ChannelId, createdHook.ChannelId)
   143  				assert.Equal(tc.ExpectedIncomingWebhook.Username, createdHook.Username)
   144  				assert.Equal(tc.ExpectedIncomingWebhook.IconURL, createdHook.IconURL)
   145  			}
   146  		})
   147  	}
   148  }
   149  
   150  func TestUpdateIncomingWebhook(t *testing.T) {
   151  	th := Setup().InitBasic()
   152  	defer th.TearDown()
   153  
   154  	type TestCase struct {
   155  		EnableIncomingHooks        bool
   156  		EnablePostUsernameOverride bool
   157  		EnablePostIconOverride     bool
   158  		IncomingWebhook            model.IncomingWebhook
   159  
   160  		ExpectedError           bool
   161  		ExpectedIncomingWebhook *model.IncomingWebhook
   162  	}
   163  
   164  	for name, tc := range map[string]TestCase{
   165  		"webhooks not enabled": {
   166  			EnableIncomingHooks:        false,
   167  			EnablePostUsernameOverride: false,
   168  			EnablePostIconOverride:     false,
   169  			IncomingWebhook: model.IncomingWebhook{
   170  				DisplayName: "title",
   171  				Description: "description",
   172  				ChannelId:   th.BasicChannel.Id,
   173  			},
   174  
   175  			ExpectedError:           true,
   176  			ExpectedIncomingWebhook: nil,
   177  		},
   178  		"valid: username and post icon url ignored, since override not enabled": {
   179  			EnableIncomingHooks:        true,
   180  			EnablePostUsernameOverride: false,
   181  			EnablePostIconOverride:     false,
   182  			IncomingWebhook: model.IncomingWebhook{
   183  				DisplayName: "title",
   184  				Description: "description",
   185  				ChannelId:   th.BasicChannel.Id,
   186  				Username:    ":invalid and ignored:",
   187  				IconURL:     "ignored",
   188  			},
   189  
   190  			ExpectedError: false,
   191  			ExpectedIncomingWebhook: &model.IncomingWebhook{
   192  				DisplayName: "title",
   193  				Description: "description",
   194  				ChannelId:   th.BasicChannel.Id,
   195  			},
   196  		},
   197  		"invalid username, override enabled": {
   198  			EnableIncomingHooks:        true,
   199  			EnablePostUsernameOverride: true,
   200  			EnablePostIconOverride:     false,
   201  			IncomingWebhook: model.IncomingWebhook{
   202  				DisplayName: "title",
   203  				Description: "description",
   204  				ChannelId:   th.BasicChannel.Id,
   205  				Username:    ":invalid:",
   206  			},
   207  
   208  			ExpectedError:           true,
   209  			ExpectedIncomingWebhook: nil,
   210  		},
   211  		"valid, no username or post icon url provided": {
   212  			EnableIncomingHooks:        true,
   213  			EnablePostUsernameOverride: true,
   214  			EnablePostIconOverride:     true,
   215  			IncomingWebhook: model.IncomingWebhook{
   216  				DisplayName: "title",
   217  				Description: "description",
   218  				ChannelId:   th.BasicChannel.Id,
   219  			},
   220  
   221  			ExpectedError: false,
   222  			ExpectedIncomingWebhook: &model.IncomingWebhook{
   223  				DisplayName: "title",
   224  				Description: "description",
   225  				ChannelId:   th.BasicChannel.Id,
   226  			},
   227  		},
   228  		"valid, with username and post icon": {
   229  			EnableIncomingHooks:        true,
   230  			EnablePostUsernameOverride: true,
   231  			EnablePostIconOverride:     true,
   232  			IncomingWebhook: model.IncomingWebhook{
   233  				DisplayName: "title",
   234  				Description: "description",
   235  				ChannelId:   th.BasicChannel.Id,
   236  				Username:    "valid",
   237  				IconURL:     "http://example.com/icon",
   238  			},
   239  
   240  			ExpectedError: false,
   241  			ExpectedIncomingWebhook: &model.IncomingWebhook{
   242  				DisplayName: "title",
   243  				Description: "description",
   244  				ChannelId:   th.BasicChannel.Id,
   245  				Username:    "valid",
   246  				IconURL:     "http://example.com/icon",
   247  			},
   248  		},
   249  	} {
   250  		t.Run(name, func(t *testing.T) {
   251  			assert := assert.New(t)
   252  
   253  			th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   254  
   255  			hook, err := th.App.CreateIncomingWebhookForChannel(th.BasicUser.Id, th.BasicChannel, &model.IncomingWebhook{
   256  				ChannelId: th.BasicChannel.Id,
   257  			})
   258  			if err != nil {
   259  				t.Fatal(err.Error())
   260  			}
   261  			defer th.App.DeleteIncomingWebhook(hook.Id)
   262  
   263  			th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = tc.EnableIncomingHooks })
   264  			th.App.UpdateConfig(func(cfg *model.Config) {
   265  				cfg.ServiceSettings.EnablePostUsernameOverride = tc.EnablePostUsernameOverride
   266  			})
   267  			th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = tc.EnablePostIconOverride })
   268  
   269  			updatedHook, err := th.App.UpdateIncomingWebhook(hook, &tc.IncomingWebhook)
   270  			if tc.ExpectedError && err == nil {
   271  				t.Fatal("should have failed")
   272  			} else if !tc.ExpectedError && err != nil {
   273  				t.Fatalf("should not have failed: %v", err.Error())
   274  			}
   275  			if tc.ExpectedIncomingWebhook == nil {
   276  				assert.Nil(updatedHook, "expected nil webhook")
   277  			} else if assert.NotNil(updatedHook, "expected non-nil webhook") {
   278  				assert.Equal(tc.ExpectedIncomingWebhook.DisplayName, updatedHook.DisplayName)
   279  				assert.Equal(tc.ExpectedIncomingWebhook.Description, updatedHook.Description)
   280  				assert.Equal(tc.ExpectedIncomingWebhook.ChannelId, updatedHook.ChannelId)
   281  				assert.Equal(tc.ExpectedIncomingWebhook.Username, updatedHook.Username)
   282  				assert.Equal(tc.ExpectedIncomingWebhook.IconURL, updatedHook.IconURL)
   283  			}
   284  		})
   285  	}
   286  }
   287  
   288  func TestCreateWebhookPost(t *testing.T) {
   289  	th := Setup().InitBasic()
   290  	defer th.TearDown()
   291  
   292  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   293  
   294  	hook, err := th.App.CreateIncomingWebhookForChannel(th.BasicUser.Id, th.BasicChannel, &model.IncomingWebhook{ChannelId: th.BasicChannel.Id})
   295  	if err != nil {
   296  		t.Fatal(err.Error())
   297  	}
   298  	defer th.App.DeleteIncomingWebhook(hook.Id)
   299  
   300  	post, err := th.App.CreateWebhookPost(hook.UserId, th.BasicChannel, "foo", "user", "http://iconurl", model.StringInterface{
   301  		"attachments": []*model.SlackAttachment{
   302  			{
   303  				Text: "text",
   304  			},
   305  		},
   306  		"webhook_display_name": hook.DisplayName,
   307  	}, model.POST_SLACK_ATTACHMENT, "")
   308  	if err != nil {
   309  		t.Fatal(err.Error())
   310  	}
   311  
   312  	for _, k := range []string{"from_webhook", "attachments", "webhook_display_name"} {
   313  		if _, ok := post.Props[k]; !ok {
   314  			t.Log("missing one props: " + k)
   315  			t.Fatal(k)
   316  		}
   317  	}
   318  
   319  	_, err = th.App.CreateWebhookPost(hook.UserId, th.BasicChannel, "foo", "user", "http://iconurl", nil, model.POST_SYSTEM_GENERIC, "")
   320  	if err == nil {
   321  		t.Fatal("should have failed - bad post type")
   322  	}
   323  
   324  	expectedText := "`<>|<>|`"
   325  	post, err = th.App.CreateWebhookPost(hook.UserId, th.BasicChannel, expectedText, "user", "http://iconurl", model.StringInterface{
   326  		"attachments": []*model.SlackAttachment{
   327  			{
   328  				Text: "text",
   329  			},
   330  		},
   331  		"webhook_display_name": hook.DisplayName,
   332  	}, model.POST_SLACK_ATTACHMENT, "")
   333  	if err != nil {
   334  		t.Fatal(err.Error())
   335  	}
   336  	assert.Equal(t, expectedText, post.Message)
   337  
   338  	expectedText = "< | \n|\n>"
   339  	post, err = th.App.CreateWebhookPost(hook.UserId, th.BasicChannel, expectedText, "user", "http://iconurl", model.StringInterface{
   340  		"attachments": []*model.SlackAttachment{
   341  			{
   342  				Text: "text",
   343  			},
   344  		},
   345  		"webhook_display_name": hook.DisplayName,
   346  	}, model.POST_SLACK_ATTACHMENT, "")
   347  	if err != nil {
   348  		t.Fatal(err.Error())
   349  	}
   350  	assert.Equal(t, expectedText, post.Message)
   351  
   352  	expectedText = `commit bc95839e4a430ace453e8b209a3723c000c1729a
   353  Author: foo <foo@example.org>
   354  Date:   Thu Mar 1 19:46:54 2018 +0300
   355  
   356      commit message 2
   357  
   358    test | 1 +
   359   1 file changed, 1 insertion(+)
   360  
   361  commit 5df78b7139b543997838071cd912e375d8bd69b2
   362  Author: foo <foo@example.org>
   363  Date:   Thu Mar 1 19:46:48 2018 +0300
   364  
   365      commit message 1
   366  
   367   test | 3 +++
   368   1 file changed, 3 insertions(+)`
   369  	post, err = th.App.CreateWebhookPost(hook.UserId, th.BasicChannel, expectedText, "user", "http://iconurl", model.StringInterface{
   370  		"attachments": []*model.SlackAttachment{
   371  			{
   372  				Text: "text",
   373  			},
   374  		},
   375  		"webhook_display_name": hook.DisplayName,
   376  	}, model.POST_SLACK_ATTACHMENT, "")
   377  	if err != nil {
   378  		t.Fatal(err.Error())
   379  	}
   380  	assert.Equal(t, expectedText, post.Message)
   381  }
   382  
   383  func TestSplitWebhookPost(t *testing.T) {
   384  	type TestCase struct {
   385  		Post     *model.Post
   386  		Expected []*model.Post
   387  	}
   388  
   389  	maxPostSize := 10000
   390  
   391  	for name, tc := range map[string]TestCase{
   392  		"LongPost": {
   393  			Post: &model.Post{
   394  				Message: strings.Repeat("本", maxPostSize*3/2),
   395  			},
   396  			Expected: []*model.Post{
   397  				{
   398  					Message: strings.Repeat("本", maxPostSize),
   399  				},
   400  				{
   401  					Message: strings.Repeat("本", maxPostSize/2),
   402  				},
   403  			},
   404  		},
   405  		"LongPostAndMultipleAttachments": {
   406  			Post: &model.Post{
   407  				Message: strings.Repeat("本", maxPostSize*3/2),
   408  				Props: map[string]interface{}{
   409  					"attachments": []*model.SlackAttachment{
   410  						&model.SlackAttachment{
   411  							Text: strings.Repeat("本", 1000),
   412  						},
   413  						&model.SlackAttachment{
   414  							Text: strings.Repeat("本", 2000),
   415  						},
   416  						&model.SlackAttachment{
   417  							Text: strings.Repeat("本", model.POST_PROPS_MAX_USER_RUNES-1000),
   418  						},
   419  					},
   420  				},
   421  			},
   422  			Expected: []*model.Post{
   423  				{
   424  					Message: strings.Repeat("本", maxPostSize),
   425  				},
   426  				{
   427  					Message: strings.Repeat("本", maxPostSize/2),
   428  					Props: map[string]interface{}{
   429  						"attachments": []*model.SlackAttachment{
   430  							&model.SlackAttachment{
   431  								Text: strings.Repeat("本", 1000),
   432  							},
   433  							&model.SlackAttachment{
   434  								Text: strings.Repeat("本", 2000),
   435  							},
   436  						},
   437  					},
   438  				},
   439  				{
   440  					Props: map[string]interface{}{
   441  						"attachments": []*model.SlackAttachment{
   442  							&model.SlackAttachment{
   443  								Text: strings.Repeat("本", model.POST_PROPS_MAX_USER_RUNES-1000),
   444  							},
   445  						},
   446  					},
   447  				},
   448  			},
   449  		},
   450  		"UnsplittableProps": {
   451  			Post: &model.Post{
   452  				Message: "foo",
   453  				Props: map[string]interface{}{
   454  					"foo": strings.Repeat("x", model.POST_PROPS_MAX_USER_RUNES*2),
   455  				},
   456  			},
   457  		},
   458  	} {
   459  		t.Run(name, func(t *testing.T) {
   460  			splits, err := SplitWebhookPost(tc.Post, maxPostSize)
   461  			if tc.Expected == nil {
   462  				require.NotNil(t, err)
   463  			} else {
   464  				require.Nil(t, err)
   465  			}
   466  			assert.Equal(t, len(tc.Expected), len(splits))
   467  			for i, split := range splits {
   468  				if i < len(tc.Expected) {
   469  					assert.Equal(t, tc.Expected[i].Message, split.Message)
   470  					assert.Equal(t, tc.Expected[i].Props["attachments"], split.Props["attachments"])
   471  				}
   472  			}
   473  		})
   474  	}
   475  }
   476  
   477  func TestCreateOutGoingWebhookWithUsernameAndIconURL(t *testing.T) {
   478  	th := Setup().InitBasic()
   479  	defer th.TearDown()
   480  
   481  	outgoingWebhook := model.OutgoingWebhook{
   482  		ChannelId:    th.BasicChannel.Id,
   483  		TeamId:       th.BasicChannel.TeamId,
   484  		CallbackURLs: []string{"http://nowhere.com"},
   485  		Username:     "some-user-name",
   486  		IconURL:      "http://some-icon/",
   487  		DisplayName:  "some-display-name",
   488  		Description:  "some-description",
   489  		CreatorId:    th.BasicUser.Id,
   490  	}
   491  
   492  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   493  
   494  	createdHook, err := th.App.CreateOutgoingWebhook(&outgoingWebhook)
   495  
   496  	if err != nil {
   497  		t.Fatalf("should not have failed: %v", err.Error())
   498  	}
   499  
   500  	assert.NotNil(t, createdHook, "should not be null")
   501  
   502  	assert.Equal(t, createdHook.ChannelId, outgoingWebhook.ChannelId)
   503  	assert.Equal(t, createdHook.TeamId, outgoingWebhook.TeamId)
   504  	assert.Equal(t, createdHook.CallbackURLs, outgoingWebhook.CallbackURLs)
   505  	assert.Equal(t, createdHook.Username, outgoingWebhook.Username)
   506  	assert.Equal(t, createdHook.IconURL, outgoingWebhook.IconURL)
   507  	assert.Equal(t, createdHook.DisplayName, outgoingWebhook.DisplayName)
   508  	assert.Equal(t, createdHook.Description, outgoingWebhook.Description)
   509  
   510  }
   511  
   512  func TestTriggerOutGoingWebhookWithUsernameAndIconURL(t *testing.T) {
   513  
   514  	getPayload := func(hook *model.OutgoingWebhook, th *TestHelper, channel *model.Channel) *model.OutgoingWebhookPayload {
   515  		return &model.OutgoingWebhookPayload{
   516  			Token:       hook.Token,
   517  			TeamId:      hook.TeamId,
   518  			TeamDomain:  th.BasicTeam.Name,
   519  			ChannelId:   channel.Id,
   520  			ChannelName: channel.Name,
   521  			Timestamp:   th.BasicPost.CreateAt,
   522  			UserId:      th.BasicPost.UserId,
   523  			UserName:    th.BasicUser.Username,
   524  			PostId:      th.BasicPost.Id,
   525  			Text:        th.BasicPost.Message,
   526  			TriggerWord: "Abracadabra",
   527  			FileIds:     strings.Join(th.BasicPost.FileIds, ","),
   528  		}
   529  	}
   530  
   531  	waitUntilWebhookResposeIsCreatedAsPost := func(channel *model.Channel, th *TestHelper, t *testing.T, createdPost chan *model.Post) {
   532  		go func() {
   533  			for i := 0; i < 5; i++ {
   534  				time.Sleep(time.Second)
   535  				posts, _ := th.App.GetPosts(channel.Id, 0, 5)
   536  				if len(posts.Posts) > 0 {
   537  					for _, post := range posts.Posts {
   538  						createdPost <- post
   539  						return
   540  					}
   541  				}
   542  			}
   543  		}()
   544  	}
   545  
   546  	type TestCaseOutgoing struct {
   547  		EnablePostUsernameOverride bool
   548  		EnablePostIconOverride     bool
   549  		ExpectedUsername           string
   550  		ExpectedIconUrl            string
   551  		WebhookResponse            *model.OutgoingWebhookResponse
   552  	}
   553  
   554  	createOutgoingWebhook := func(channel *model.Channel, testCallBackUrl string, th *TestHelper) (*model.OutgoingWebhook, *model.AppError) {
   555  		outgoingWebhook := model.OutgoingWebhook{
   556  			ChannelId:    channel.Id,
   557  			TeamId:       channel.TeamId,
   558  			CallbackURLs: []string{testCallBackUrl},
   559  			Username:     "some-user-name",
   560  			IconURL:      "http://some-icon/",
   561  			DisplayName:  "some-display-name",
   562  			Description:  "some-description",
   563  			CreatorId:    th.BasicUser.Id,
   564  			TriggerWords: []string{"Abracadabra"},
   565  			ContentType:  "application/json",
   566  		}
   567  
   568  		return th.App.CreateOutgoingWebhook(&outgoingWebhook)
   569  	}
   570  
   571  	getTestCases := func() map[string]TestCaseOutgoing {
   572  
   573  		webHookResponse := "sample response text from test server"
   574  		testCasesOutgoing := map[string]TestCaseOutgoing{
   575  
   576  			"Should override username and Icon": {
   577  				EnablePostUsernameOverride: true,
   578  				EnablePostIconOverride:     true,
   579  				ExpectedUsername:           "some-user-name",
   580  				ExpectedIconUrl:            "http://some-icon/",
   581  			},
   582  			"Should not override username and Icon": {
   583  				EnablePostUsernameOverride: false,
   584  				EnablePostIconOverride:     false,
   585  			},
   586  			"Should not override username and Icon if the webhook response already has it": {
   587  				EnablePostUsernameOverride: true,
   588  				EnablePostIconOverride:     true,
   589  				ExpectedUsername:           "webhookuser",
   590  				ExpectedIconUrl:            "http://webhok/icon",
   591  				WebhookResponse:            &model.OutgoingWebhookResponse{Text: &webHookResponse, Username: "webhookuser", IconURL: "http://webhok/icon"},
   592  			},
   593  		}
   594  		return testCasesOutgoing
   595  	}
   596  
   597  	th := Setup().InitBasic()
   598  	defer th.TearDown()
   599  
   600  	th.App.UpdateConfig(func(cfg *model.Config) {
   601  		*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1"
   602  	})
   603  	createdPost := make(chan *model.Post)
   604  
   605  	for name, testCase := range getTestCases() {
   606  		t.Run(name, func(t *testing.T) {
   607  
   608  			th.App.UpdateConfig(func(cfg *model.Config) {
   609  				cfg.ServiceSettings.EnableOutgoingWebhooks = true
   610  				cfg.ServiceSettings.EnablePostUsernameOverride = testCase.EnablePostUsernameOverride
   611  				cfg.ServiceSettings.EnablePostIconOverride = testCase.EnablePostIconOverride
   612  			})
   613  
   614  			ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   615  				if testCase.WebhookResponse != nil {
   616  					w.Write([]byte(testCase.WebhookResponse.ToJson()))
   617  				} else {
   618  					w.Write([]byte(`{"text": "sample response text from test server"}`))
   619  				}
   620  			}))
   621  			defer ts.Close()
   622  
   623  			channel := th.CreateChannel(th.BasicTeam)
   624  			hook, _ := createOutgoingWebhook(channel, ts.URL, th)
   625  			payload := getPayload(hook, th, channel)
   626  
   627  			th.App.TriggerWebhook(payload, hook, th.BasicPost, channel)
   628  
   629  			waitUntilWebhookResposeIsCreatedAsPost(channel, th, t, createdPost)
   630  
   631  			select {
   632  			case webhookPost := <-createdPost:
   633  				assert.Equal(t, webhookPost.Message, "sample response text from test server")
   634  				assert.Equal(t, webhookPost.Props["from_webhook"], "true")
   635  				if testCase.ExpectedIconUrl != "" {
   636  					assert.Equal(t, webhookPost.Props["override_icon_url"], testCase.ExpectedIconUrl)
   637  				} else {
   638  					assert.Nil(t, webhookPost.Props["override_icon_url"])
   639  				}
   640  
   641  				if testCase.ExpectedUsername != "" {
   642  					assert.Equal(t, webhookPost.Props["override_username"], testCase.ExpectedUsername)
   643  				} else {
   644  					assert.Nil(t, webhookPost.Props["override_username"])
   645  				}
   646  			case <-time.After(5 * time.Second):
   647  				t.Fatal("Timeout, webhook response not created as post")
   648  			}
   649  
   650  		})
   651  	}
   652  
   653  }