github.com/mad-app/mattermost-server@v5.11.1+incompatible/api4/integration_action_test.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/json"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"net/http/httptest"
    12  	"testing"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  
    16  	"github.com/mattermost/mattermost-server/model"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  type testHandler struct {
    21  	t *testing.T
    22  }
    23  
    24  func (th *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    25  	bb, err := ioutil.ReadAll(r.Body)
    26  	assert.Nil(th.t, err)
    27  	assert.NotEmpty(th.t, string(bb))
    28  	poir := model.PostActionIntegrationRequestFromJson(bytes.NewReader(bb))
    29  	assert.NotEmpty(th.t, poir.UserId)
    30  	assert.NotEmpty(th.t, poir.ChannelId)
    31  	assert.Empty(th.t, poir.TeamId)
    32  	assert.NotEmpty(th.t, poir.PostId)
    33  	assert.NotEmpty(th.t, poir.TriggerId)
    34  	assert.Equal(th.t, "button", poir.Type)
    35  	assert.Equal(th.t, "test-value", poir.Context["test-key"])
    36  	w.Write([]byte("{}"))
    37  	w.WriteHeader(200)
    38  }
    39  
    40  func TestPostActionCookies(t *testing.T) {
    41  	th := Setup().InitBasic()
    42  	defer th.TearDown()
    43  	Client := th.Client
    44  
    45  	th.App.UpdateConfig(func(cfg *model.Config) {
    46  		*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1"
    47  	})
    48  
    49  	handler := &testHandler{t}
    50  	server := httptest.NewServer(handler)
    51  	action := model.PostAction{
    52  		Id:   model.NewId(),
    53  		Name: "Test-action",
    54  		Type: model.POST_ACTION_TYPE_BUTTON,
    55  		Integration: &model.PostActionIntegration{
    56  			URL: server.URL,
    57  			Context: map[string]interface{}{
    58  				"test-key": "test-value",
    59  			},
    60  		},
    61  	}
    62  
    63  	post := &model.Post{
    64  		Id:        model.NewId(),
    65  		Type:      model.POST_EPHEMERAL,
    66  		UserId:    th.BasicUser.Id,
    67  		ChannelId: th.BasicChannel.Id,
    68  		CreateAt:  model.GetMillis(),
    69  		UpdateAt:  model.GetMillis(),
    70  		Props: map[string]interface{}{
    71  			"attachments": []*model.SlackAttachment{
    72  				{
    73  					Title:     "some-title",
    74  					TitleLink: "https://some-url.com",
    75  					Text:      "some-text",
    76  					ImageURL:  "https://some-other-url.com",
    77  					Actions:   []*model.PostAction{&action},
    78  				},
    79  			},
    80  		},
    81  	}
    82  
    83  	post.GenerateActionIds()
    84  	assert.Equal(t, 32, len(th.App.PostActionCookieSecret()))
    85  	post = model.AddPostActionCookies(post, th.App.PostActionCookieSecret())
    86  
    87  	ok, resp := Client.DoPostActionWithCookie(post.Id, action.Id, "", action.Cookie)
    88  	assert.True(t, ok)
    89  	assert.NotNil(t, resp)
    90  	assert.Equal(t, 200, resp.StatusCode)
    91  	assert.Nil(t, resp.Error)
    92  	assert.NotNil(t, resp.RequestId)
    93  	assert.NotNil(t, resp.ServerVersion)
    94  }
    95  
    96  func TestOpenDialog(t *testing.T) {
    97  	th := Setup().InitBasic()
    98  	defer th.TearDown()
    99  	Client := th.Client
   100  
   101  	th.App.UpdateConfig(func(cfg *model.Config) {
   102  		*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1"
   103  	})
   104  
   105  	_, triggerId, err := model.GenerateTriggerId(th.BasicUser.Id, th.App.AsymmetricSigningKey())
   106  	require.Nil(t, err)
   107  
   108  	request := model.OpenDialogRequest{
   109  		TriggerId: triggerId,
   110  		URL:       "http://localhost:8065",
   111  		Dialog: model.Dialog{
   112  			CallbackId: "callbackid",
   113  			Title:      "Some Title",
   114  			Elements: []model.DialogElement{
   115  				model.DialogElement{
   116  					DisplayName: "Element Name",
   117  					Name:        "element_name",
   118  					Type:        "text",
   119  					Placeholder: "Enter a value",
   120  				},
   121  			},
   122  			SubmitLabel:    "Submit",
   123  			NotifyOnCancel: false,
   124  			State:          "somestate",
   125  		},
   126  	}
   127  
   128  	pass, resp := Client.OpenInteractiveDialog(request)
   129  	CheckNoError(t, resp)
   130  	assert.True(t, pass)
   131  
   132  	// Should fail on bad trigger ID
   133  	request.TriggerId = "junk"
   134  	pass, resp = Client.OpenInteractiveDialog(request)
   135  	CheckBadRequestStatus(t, resp)
   136  	assert.False(t, pass)
   137  
   138  	// URL is required
   139  	request.TriggerId = triggerId
   140  	request.URL = ""
   141  	pass, resp = Client.OpenInteractiveDialog(request)
   142  	CheckBadRequestStatus(t, resp)
   143  	assert.False(t, pass)
   144  
   145  	// At least one element is required
   146  	request.URL = "http://localhost:8065"
   147  	request.Dialog.Elements = nil
   148  	pass, resp = Client.OpenInteractiveDialog(request)
   149  	CheckBadRequestStatus(t, resp)
   150  	assert.False(t, pass)
   151  	request.Dialog.Elements = []model.DialogElement{}
   152  	pass, resp = Client.OpenInteractiveDialog(request)
   153  	CheckBadRequestStatus(t, resp)
   154  	assert.False(t, pass)
   155  }
   156  
   157  func TestSubmitDialog(t *testing.T) {
   158  	th := Setup().InitBasic()
   159  	defer th.TearDown()
   160  	Client := th.Client
   161  
   162  	th.App.UpdateConfig(func(cfg *model.Config) {
   163  		*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1"
   164  	})
   165  
   166  	submit := model.SubmitDialogRequest{
   167  		CallbackId: "callbackid",
   168  		State:      "somestate",
   169  		UserId:     th.BasicUser.Id,
   170  		ChannelId:  th.BasicChannel.Id,
   171  		TeamId:     th.BasicTeam.Id,
   172  		Submission: map[string]interface{}{"somename": "somevalue"},
   173  	}
   174  
   175  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   176  		var request model.SubmitDialogRequest
   177  		err := json.NewDecoder(r.Body).Decode(&request)
   178  		require.Nil(t, err)
   179  		assert.NotNil(t, request)
   180  
   181  		assert.Equal(t, request.URL, "")
   182  		assert.Equal(t, request.UserId, submit.UserId)
   183  		assert.Equal(t, request.ChannelId, submit.ChannelId)
   184  		assert.Equal(t, request.TeamId, submit.TeamId)
   185  		assert.Equal(t, request.CallbackId, submit.CallbackId)
   186  		assert.Equal(t, request.State, submit.State)
   187  		val, ok := request.Submission["somename"].(string)
   188  		require.True(t, ok)
   189  		assert.Equal(t, "somevalue", val)
   190  	}))
   191  	defer ts.Close()
   192  
   193  	submit.URL = ts.URL
   194  
   195  	submitResp, resp := Client.SubmitInteractiveDialog(submit)
   196  	CheckNoError(t, resp)
   197  	assert.NotNil(t, submitResp)
   198  
   199  	submit.URL = ""
   200  	submitResp, resp = Client.SubmitInteractiveDialog(submit)
   201  	CheckBadRequestStatus(t, resp)
   202  	assert.Nil(t, submitResp)
   203  
   204  	submit.URL = ts.URL
   205  	submit.ChannelId = model.NewId()
   206  	submitResp, resp = Client.SubmitInteractiveDialog(submit)
   207  	CheckForbiddenStatus(t, resp)
   208  	assert.Nil(t, submitResp)
   209  
   210  	submit.URL = ts.URL
   211  	submit.ChannelId = th.BasicChannel.Id
   212  	submit.TeamId = model.NewId()
   213  	submitResp, resp = Client.SubmitInteractiveDialog(submit)
   214  	CheckForbiddenStatus(t, resp)
   215  	assert.Nil(t, submitResp)
   216  }