github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/api4/integration_action_test.go (about) 1 // Copyright (c) 2015-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 "github.com/stretchr/testify/require" 16 17 "github.com/masterhung0112/hk_server/v5/model" 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.NoError(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.UserName) 31 assert.NotEmpty(th.t, poir.ChannelId) 32 assert.NotEmpty(th.t, poir.ChannelName) 33 assert.NotEmpty(th.t, poir.TeamId) 34 assert.NotEmpty(th.t, poir.TeamName) 35 assert.NotEmpty(th.t, poir.PostId) 36 assert.NotEmpty(th.t, poir.TriggerId) 37 assert.Equal(th.t, "button", poir.Type) 38 assert.Equal(th.t, "test-value", poir.Context["test-key"]) 39 w.Write([]byte("{}")) 40 w.WriteHeader(200) 41 } 42 43 func TestPostActionCookies(t *testing.T) { 44 th := Setup(t).InitBasic() 45 defer th.TearDown() 46 Client := th.Client 47 48 th.App.UpdateConfig(func(cfg *model.Config) { 49 *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost,127.0.0.1" 50 }) 51 52 handler := &testHandler{t} 53 server := httptest.NewServer(handler) 54 55 for name, test := range map[string]struct { 56 Action model.PostAction 57 ExpectedSucess bool 58 ExpectedStatusCode int 59 }{ 60 "32 character ID": { 61 Action: model.PostAction{ 62 Id: model.NewId(), 63 Name: "Test-action", 64 Type: model.POST_ACTION_TYPE_BUTTON, 65 Integration: &model.PostActionIntegration{ 66 URL: server.URL, 67 Context: map[string]interface{}{ 68 "test-key": "test-value", 69 }, 70 }, 71 }, 72 ExpectedSucess: true, 73 ExpectedStatusCode: http.StatusOK, 74 }, 75 "6 character ID": { 76 Action: model.PostAction{ 77 Id: "someID", 78 Name: "Test-action", 79 Type: model.POST_ACTION_TYPE_BUTTON, 80 Integration: &model.PostActionIntegration{ 81 URL: server.URL, 82 Context: map[string]interface{}{ 83 "test-key": "test-value", 84 }, 85 }, 86 }, 87 ExpectedSucess: true, 88 ExpectedStatusCode: http.StatusOK, 89 }, 90 "Empty ID": { 91 Action: model.PostAction{ 92 Id: "", 93 Name: "Test-action", 94 Type: model.POST_ACTION_TYPE_BUTTON, 95 Integration: &model.PostActionIntegration{ 96 URL: server.URL, 97 Context: map[string]interface{}{ 98 "test-key": "test-value", 99 }, 100 }, 101 }, 102 ExpectedSucess: false, 103 ExpectedStatusCode: http.StatusNotFound, 104 }, 105 } { 106 t.Run(name, func(t *testing.T) { 107 post := &model.Post{ 108 Id: model.NewId(), 109 Type: model.POST_EPHEMERAL, 110 UserId: th.BasicUser.Id, 111 ChannelId: th.BasicChannel.Id, 112 CreateAt: model.GetMillis(), 113 UpdateAt: model.GetMillis(), 114 Props: map[string]interface{}{ 115 "attachments": []*model.SlackAttachment{ 116 { 117 Title: "some-title", 118 TitleLink: "https://some-url.com", 119 Text: "some-text", 120 ImageURL: "https://some-other-url.com", 121 Actions: []*model.PostAction{&test.Action}, 122 }, 123 }, 124 }, 125 } 126 127 assert.Equal(t, 32, len(th.App.PostActionCookieSecret())) 128 post = model.AddPostActionCookies(post, th.App.PostActionCookieSecret()) 129 130 ok, resp := Client.DoPostActionWithCookie(post.Id, test.Action.Id, "", test.Action.Cookie) 131 require.NotNil(t, resp) 132 if test.ExpectedSucess { 133 assert.True(t, ok) 134 assert.Nil(t, resp.Error) 135 } else { 136 assert.False(t, ok) 137 assert.NotNil(t, resp.Error) 138 } 139 assert.Equal(t, test.ExpectedStatusCode, resp.StatusCode) 140 assert.NotNil(t, resp.RequestId) 141 assert.NotNil(t, resp.ServerVersion) 142 }) 143 } 144 } 145 146 func TestOpenDialog(t *testing.T) { 147 th := Setup(t).InitBasic() 148 defer th.TearDown() 149 Client := th.Client 150 151 th.App.UpdateConfig(func(cfg *model.Config) { 152 *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost,127.0.0.1" 153 }) 154 155 _, triggerId, err := model.GenerateTriggerId(th.BasicUser.Id, th.App.AsymmetricSigningKey()) 156 require.Nil(t, err) 157 158 request := model.OpenDialogRequest{ 159 TriggerId: triggerId, 160 URL: "http://localhost:8065", 161 Dialog: model.Dialog{ 162 CallbackId: "callbackid", 163 Title: "Some Title", 164 Elements: []model.DialogElement{ 165 { 166 DisplayName: "Element Name", 167 Name: "element_name", 168 Type: "text", 169 Placeholder: "Enter a value", 170 }, 171 }, 172 SubmitLabel: "Submit", 173 NotifyOnCancel: false, 174 State: "somestate", 175 }, 176 } 177 178 pass, resp := Client.OpenInteractiveDialog(request) 179 CheckNoError(t, resp) 180 assert.True(t, pass) 181 182 // Should fail on bad trigger ID 183 request.TriggerId = "junk" 184 pass, resp = Client.OpenInteractiveDialog(request) 185 CheckBadRequestStatus(t, resp) 186 assert.False(t, pass) 187 188 // URL is required 189 request.TriggerId = triggerId 190 request.URL = "" 191 pass, resp = Client.OpenInteractiveDialog(request) 192 CheckBadRequestStatus(t, resp) 193 assert.False(t, pass) 194 195 // Should pass with markdown formatted introduction text 196 request.URL = "http://localhost:8065" 197 request.Dialog.IntroductionText = "**Some** _introduction text" 198 pass, resp = Client.OpenInteractiveDialog(request) 199 CheckNoError(t, resp) 200 assert.True(t, pass) 201 202 // Should pass with empty introduction text 203 request.Dialog.IntroductionText = "" 204 pass, resp = Client.OpenInteractiveDialog(request) 205 CheckNoError(t, resp) 206 assert.True(t, pass) 207 208 // Should pass with no elements 209 request.Dialog.Elements = nil 210 pass, resp = Client.OpenInteractiveDialog(request) 211 CheckNoError(t, resp) 212 assert.True(t, pass) 213 request.Dialog.Elements = []model.DialogElement{} 214 pass, resp = Client.OpenInteractiveDialog(request) 215 CheckNoError(t, resp) 216 assert.True(t, pass) 217 } 218 219 func TestSubmitDialog(t *testing.T) { 220 th := Setup(t).InitBasic() 221 defer th.TearDown() 222 Client := th.Client 223 224 th.App.UpdateConfig(func(cfg *model.Config) { 225 *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost,127.0.0.1" 226 }) 227 228 submit := model.SubmitDialogRequest{ 229 CallbackId: "callbackid", 230 State: "somestate", 231 UserId: th.BasicUser.Id, 232 ChannelId: th.BasicChannel.Id, 233 TeamId: th.BasicTeam.Id, 234 Submission: map[string]interface{}{"somename": "somevalue"}, 235 } 236 237 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 238 var request model.SubmitDialogRequest 239 err := json.NewDecoder(r.Body).Decode(&request) 240 require.NoError(t, err) 241 242 assert.Equal(t, request.URL, "") 243 assert.Equal(t, request.UserId, submit.UserId) 244 assert.Equal(t, request.ChannelId, submit.ChannelId) 245 assert.Equal(t, request.TeamId, submit.TeamId) 246 assert.Equal(t, request.CallbackId, submit.CallbackId) 247 assert.Equal(t, request.State, submit.State) 248 val, ok := request.Submission["somename"].(string) 249 require.True(t, ok) 250 assert.Equal(t, "somevalue", val) 251 })) 252 defer ts.Close() 253 254 submit.URL = ts.URL 255 256 submitResp, resp := Client.SubmitInteractiveDialog(submit) 257 CheckNoError(t, resp) 258 assert.NotNil(t, submitResp) 259 260 submit.URL = "" 261 submitResp, resp = Client.SubmitInteractiveDialog(submit) 262 CheckBadRequestStatus(t, resp) 263 assert.Nil(t, submitResp) 264 265 submit.URL = ts.URL 266 submit.ChannelId = model.NewId() 267 submitResp, resp = Client.SubmitInteractiveDialog(submit) 268 CheckForbiddenStatus(t, resp) 269 assert.Nil(t, submitResp) 270 271 submit.URL = ts.URL 272 submit.ChannelId = th.BasicChannel.Id 273 submit.TeamId = model.NewId() 274 submitResp, resp = Client.SubmitInteractiveDialog(submit) 275 CheckForbiddenStatus(t, resp) 276 assert.Nil(t, submitResp) 277 }