github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+incompatible/api4/post_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 "encoding/json" 8 "fmt" 9 "net/http" 10 "net/http/httptest" 11 "net/url" 12 "reflect" 13 "strconv" 14 "strings" 15 "testing" 16 "time" 17 18 "github.com/mattermost/mattermost-server/app" 19 "github.com/mattermost/mattermost-server/model" 20 ) 21 22 func TestCreatePost(t *testing.T) { 23 th := Setup().InitBasic().InitSystemAdmin() 24 defer th.TearDown() 25 Client := th.Client 26 27 post := &model.Post{ChannelId: th.BasicChannel.Id, Message: "#hashtag a" + model.NewId() + "a", Props: model.StringInterface{model.PROPS_ADD_CHANNEL_MEMBER: "no good"}} 28 rpost, resp := Client.CreatePost(post) 29 CheckNoError(t, resp) 30 CheckCreatedStatus(t, resp) 31 32 if rpost.Message != post.Message { 33 t.Fatal("message didn't match") 34 } 35 36 if rpost.Hashtags != "#hashtag" { 37 t.Fatal("hashtag didn't match") 38 } 39 40 if len(rpost.FileIds) != 0 { 41 t.Fatal("shouldn't have files") 42 } 43 44 if rpost.EditAt != 0 { 45 t.Fatal("newly created post shouldn't have EditAt set") 46 } 47 48 if rpost.Props[model.PROPS_ADD_CHANNEL_MEMBER] != nil { 49 t.Fatal("newly created post shouldn't have Props['add_channel_member'] set") 50 } 51 52 post.RootId = rpost.Id 53 post.ParentId = rpost.Id 54 _, resp = Client.CreatePost(post) 55 CheckNoError(t, resp) 56 57 post.RootId = "junk" 58 _, resp = Client.CreatePost(post) 59 CheckBadRequestStatus(t, resp) 60 61 post.RootId = rpost.Id 62 post.ParentId = "junk" 63 _, resp = Client.CreatePost(post) 64 CheckBadRequestStatus(t, resp) 65 66 post2 := &model.Post{ChannelId: th.BasicChannel2.Id, Message: "zz" + model.NewId() + "a", CreateAt: 123} 67 rpost2, resp := Client.CreatePost(post2) 68 69 if rpost2.CreateAt == post2.CreateAt { 70 t.Fatal("create at should not match") 71 } 72 73 post.RootId = "" 74 post.ParentId = "" 75 post.Type = model.POST_SYSTEM_GENERIC 76 _, resp = Client.CreatePost(post) 77 CheckBadRequestStatus(t, resp) 78 79 post.Type = "" 80 post.RootId = rpost2.Id 81 post.ParentId = rpost2.Id 82 _, resp = Client.CreatePost(post) 83 CheckBadRequestStatus(t, resp) 84 85 post.RootId = "" 86 post.ParentId = "" 87 post.ChannelId = "junk" 88 _, resp = Client.CreatePost(post) 89 CheckForbiddenStatus(t, resp) 90 91 post.ChannelId = model.NewId() 92 _, resp = Client.CreatePost(post) 93 CheckForbiddenStatus(t, resp) 94 95 if r, err := Client.DoApiPost("/posts", "garbage"); err == nil { 96 t.Fatal("should have errored") 97 } else { 98 if r.StatusCode != http.StatusBadRequest { 99 t.Log("actual: " + strconv.Itoa(r.StatusCode)) 100 t.Log("expected: " + strconv.Itoa(http.StatusBadRequest)) 101 t.Fatal("wrong status code") 102 } 103 } 104 105 Client.Logout() 106 _, resp = Client.CreatePost(post) 107 CheckUnauthorizedStatus(t, resp) 108 109 post.ChannelId = th.BasicChannel.Id 110 post.CreateAt = 123 111 rpost, resp = th.SystemAdminClient.CreatePost(post) 112 CheckNoError(t, resp) 113 114 if rpost.CreateAt != post.CreateAt { 115 t.Fatal("create at should match") 116 } 117 } 118 119 func TestCreatePostEphemeral(t *testing.T) { 120 th := Setup().InitBasic().InitSystemAdmin() 121 defer th.TearDown() 122 Client := th.SystemAdminClient 123 124 ephemeralPost := &model.PostEphemeral{ 125 UserID: th.BasicUser2.Id, 126 Post: &model.Post{ChannelId: th.BasicChannel.Id, Message: "a" + model.NewId() + "a", Props: model.StringInterface{model.PROPS_ADD_CHANNEL_MEMBER: "no good"}}, 127 } 128 129 rpost, resp := Client.CreatePostEphemeral(ephemeralPost) 130 CheckNoError(t, resp) 131 CheckCreatedStatus(t, resp) 132 133 if rpost.Message != ephemeralPost.Post.Message { 134 t.Fatal("message didn't match") 135 } 136 137 if rpost.EditAt != 0 { 138 t.Fatal("newly created ephemeral post shouldn't have EditAt set") 139 } 140 141 if r, err := Client.DoApiPost("/posts/ephemeral", "garbage"); err == nil { 142 t.Fatal("should have errored") 143 } else { 144 if r.StatusCode != http.StatusBadRequest { 145 t.Log("actual: " + strconv.Itoa(r.StatusCode)) 146 t.Log("expected: " + strconv.Itoa(http.StatusBadRequest)) 147 t.Fatal("wrong status code") 148 } 149 } 150 151 Client.Logout() 152 _, resp = Client.CreatePostEphemeral(ephemeralPost) 153 CheckUnauthorizedStatus(t, resp) 154 155 Client = th.Client 156 rpost, resp = Client.CreatePostEphemeral(ephemeralPost) 157 CheckForbiddenStatus(t, resp) 158 } 159 160 func testCreatePostWithOutgoingHook( 161 t *testing.T, 162 hookContentType, expectedContentType, message, triggerWord string, 163 fileIds []string, 164 triggerWhen int, 165 commentPostType bool, 166 ) { 167 th := Setup().InitBasic().InitSystemAdmin() 168 defer th.TearDown() 169 user := th.SystemAdminUser 170 team := th.BasicTeam 171 channel := th.BasicChannel 172 173 th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true }) 174 th.App.UpdateConfig(func(cfg *model.Config) { 175 *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1" 176 }) 177 178 var hook *model.OutgoingWebhook 179 var post *model.Post 180 181 // Create a test server that is the target of the outgoing webhook. It will 182 // validate the webhook body fields and write to the success channel on 183 // success/failure. 184 success := make(chan bool) 185 wait := make(chan bool, 1) 186 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 187 <-wait 188 189 requestContentType := r.Header.Get("Content-Type") 190 if requestContentType != expectedContentType { 191 t.Logf("Content-Type is %s, should be %s", requestContentType, expectedContentType) 192 success <- false 193 return 194 } 195 196 expectedPayload := &model.OutgoingWebhookPayload{ 197 Token: hook.Token, 198 TeamId: hook.TeamId, 199 TeamDomain: team.Name, 200 ChannelId: post.ChannelId, 201 ChannelName: channel.Name, 202 Timestamp: post.CreateAt, 203 UserId: post.UserId, 204 UserName: user.Username, 205 PostId: post.Id, 206 Text: post.Message, 207 TriggerWord: triggerWord, 208 FileIds: strings.Join(post.FileIds, ","), 209 } 210 211 // depending on the Content-Type, we expect to find a JSON or form encoded payload 212 if requestContentType == "application/json" { 213 decoder := json.NewDecoder(r.Body) 214 o := &model.OutgoingWebhookPayload{} 215 decoder.Decode(&o) 216 217 if !reflect.DeepEqual(expectedPayload, o) { 218 t.Logf("JSON payload is %+v, should be %+v", o, expectedPayload) 219 success <- false 220 return 221 } 222 } else { 223 err := r.ParseForm() 224 if err != nil { 225 t.Logf("Error parsing form: %q", err) 226 success <- false 227 return 228 } 229 230 expectedFormValues, _ := url.ParseQuery(expectedPayload.ToFormValues()) 231 232 if !reflect.DeepEqual(expectedFormValues, r.Form) { 233 t.Logf("Form values are: %q\n, should be: %q\n", r.Form, expectedFormValues) 234 success <- false 235 return 236 } 237 } 238 239 respPostType := "" //if is empty or post will do a normal post. 240 if commentPostType { 241 respPostType = model.OUTGOING_HOOK_RESPONSE_TYPE_COMMENT 242 } 243 244 outGoingHookResponse := &model.OutgoingWebhookResponse{ 245 Text: model.NewString("some test text"), 246 Username: "TestCommandServer", 247 IconURL: "https://www.mattermost.org/wp-content/uploads/2016/04/icon.png", 248 Type: "custom_as", 249 ResponseType: respPostType, 250 } 251 252 fmt.Fprintf(w, outGoingHookResponse.ToJson()) 253 success <- true 254 })) 255 defer ts.Close() 256 257 // create an outgoing webhook, passing it the test server URL 258 var triggerWords []string 259 if triggerWord != "" { 260 triggerWords = []string{triggerWord} 261 } 262 263 hook = &model.OutgoingWebhook{ 264 ChannelId: channel.Id, 265 TeamId: team.Id, 266 ContentType: hookContentType, 267 TriggerWords: triggerWords, 268 TriggerWhen: triggerWhen, 269 CallbackURLs: []string{ts.URL}, 270 } 271 272 hook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook) 273 CheckNoError(t, resp) 274 275 // create a post to trigger the webhook 276 post = &model.Post{ 277 ChannelId: channel.Id, 278 Message: message, 279 FileIds: fileIds, 280 } 281 282 post, resp = th.SystemAdminClient.CreatePost(post) 283 CheckNoError(t, resp) 284 285 wait <- true 286 287 // We wait for the test server to write to the success channel and we make 288 // the test fail if that doesn't happen before the timeout. 289 select { 290 case ok := <-success: 291 if !ok { 292 t.Fatal("Test server did send an invalid webhook.") 293 } 294 case <-time.After(time.Second): 295 t.Fatal("Timeout, test server did not send the webhook.") 296 } 297 298 if commentPostType { 299 time.Sleep(time.Millisecond * 100) 300 postList, resp := th.SystemAdminClient.GetPostThread(post.Id, "") 301 CheckNoError(t, resp) 302 if postList.Order[0] != post.Id { 303 t.Fatal("wrong order") 304 } 305 306 if _, ok := postList.Posts[post.Id]; !ok { 307 t.Fatal("should have had post") 308 } 309 310 if len(postList.Posts) != 2 { 311 t.Fatal("should have 2 posts") 312 } 313 314 } 315 } 316 317 func TestCreatePostWithOutgoingHook_form_urlencoded(t *testing.T) { 318 testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "triggerword lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH, false) 319 testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "triggerwordaaazzz lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH, false) 320 testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "", "", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH, false) 321 testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "", "", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH, false) 322 testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "triggerword lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH, true) 323 testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "triggerwordaaazzz lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH, true) 324 } 325 326 func TestCreatePostWithOutgoingHook_json(t *testing.T) { 327 testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerword lorem ipsum", "triggerword", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_EXACT_MATCH, false) 328 testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerwordaaazzz lorem ipsum", "triggerword", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_STARTS_WITH, false) 329 testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerword lorem ipsum", "", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH, false) 330 testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerwordaaazzz lorem ipsum", "", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH, false) 331 testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerword lorem ipsum", "triggerword", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_EXACT_MATCH, true) 332 testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerwordaaazzz lorem ipsum", "", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH, true) 333 } 334 335 // hooks created before we added the ContentType field should be considered as 336 // application/x-www-form-urlencoded 337 func TestCreatePostWithOutgoingHook_no_content_type(t *testing.T) { 338 testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerword lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH, false) 339 testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerwordaaazzz lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH, false) 340 testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerword lorem ipsum", "", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_EXACT_MATCH, false) 341 testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerwordaaazzz lorem ipsum", "", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_STARTS_WITH, false) 342 testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerword lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH, true) 343 testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerword lorem ipsum", "", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_EXACT_MATCH, true) 344 } 345 346 func TestCreatePostPublic(t *testing.T) { 347 th := Setup().InitBasic().InitSystemAdmin() 348 defer th.TearDown() 349 Client := th.Client 350 351 post := &model.Post{ChannelId: th.BasicChannel.Id, Message: "#hashtag a" + model.NewId() + "a"} 352 353 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Joram Wilander", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_USER_ROLE_ID} 354 355 ruser, resp := Client.CreateUser(&user) 356 CheckNoError(t, resp) 357 358 Client.Login(user.Email, user.Password) 359 360 _, resp = Client.CreatePost(post) 361 CheckForbiddenStatus(t, resp) 362 363 th.App.UpdateUserRoles(ruser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_POST_ALL_PUBLIC_ROLE_ID, false) 364 th.App.InvalidateAllCaches() 365 366 Client.Login(user.Email, user.Password) 367 368 _, resp = Client.CreatePost(post) 369 CheckNoError(t, resp) 370 371 post.ChannelId = th.BasicPrivateChannel.Id 372 _, resp = Client.CreatePost(post) 373 CheckForbiddenStatus(t, resp) 374 375 th.App.UpdateUserRoles(ruser.Id, model.SYSTEM_USER_ROLE_ID, false) 376 th.App.JoinUserToTeam(th.BasicTeam, ruser, "") 377 th.App.UpdateTeamMemberRoles(th.BasicTeam.Id, ruser.Id, model.TEAM_USER_ROLE_ID+" "+model.TEAM_POST_ALL_PUBLIC_ROLE_ID) 378 th.App.InvalidateAllCaches() 379 380 Client.Login(user.Email, user.Password) 381 382 post.ChannelId = th.BasicPrivateChannel.Id 383 _, resp = Client.CreatePost(post) 384 CheckForbiddenStatus(t, resp) 385 386 post.ChannelId = th.BasicChannel.Id 387 _, resp = Client.CreatePost(post) 388 CheckNoError(t, resp) 389 } 390 391 func TestCreatePostAll(t *testing.T) { 392 th := Setup().InitBasic().InitSystemAdmin() 393 defer th.TearDown() 394 Client := th.Client 395 396 post := &model.Post{ChannelId: th.BasicChannel.Id, Message: "#hashtag a" + model.NewId() + "a"} 397 398 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Joram Wilander", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_USER_ROLE_ID} 399 400 directChannel, _ := th.App.CreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id) 401 402 ruser, resp := Client.CreateUser(&user) 403 CheckNoError(t, resp) 404 405 Client.Login(user.Email, user.Password) 406 407 _, resp = Client.CreatePost(post) 408 CheckForbiddenStatus(t, resp) 409 410 th.App.UpdateUserRoles(ruser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_POST_ALL_ROLE_ID, false) 411 th.App.InvalidateAllCaches() 412 413 Client.Login(user.Email, user.Password) 414 415 _, resp = Client.CreatePost(post) 416 CheckNoError(t, resp) 417 418 post.ChannelId = th.BasicPrivateChannel.Id 419 _, resp = Client.CreatePost(post) 420 CheckNoError(t, resp) 421 422 post.ChannelId = directChannel.Id 423 _, resp = Client.CreatePost(post) 424 CheckNoError(t, resp) 425 426 th.App.UpdateUserRoles(ruser.Id, model.SYSTEM_USER_ROLE_ID, false) 427 th.App.JoinUserToTeam(th.BasicTeam, ruser, "") 428 th.App.UpdateTeamMemberRoles(th.BasicTeam.Id, ruser.Id, model.TEAM_USER_ROLE_ID+" "+model.TEAM_POST_ALL_ROLE_ID) 429 th.App.InvalidateAllCaches() 430 431 Client.Login(user.Email, user.Password) 432 433 post.ChannelId = th.BasicPrivateChannel.Id 434 _, resp = Client.CreatePost(post) 435 CheckNoError(t, resp) 436 437 post.ChannelId = th.BasicChannel.Id 438 _, resp = Client.CreatePost(post) 439 CheckNoError(t, resp) 440 441 post.ChannelId = directChannel.Id 442 _, resp = Client.CreatePost(post) 443 CheckForbiddenStatus(t, resp) 444 } 445 446 func TestCreatePostSendOutOfChannelMentions(t *testing.T) { 447 th := Setup().InitBasic().InitSystemAdmin() 448 defer th.TearDown() 449 Client := th.Client 450 451 WebSocketClient, err := th.CreateWebSocketClient() 452 if err != nil { 453 t.Fatal(err) 454 } 455 WebSocketClient.Listen() 456 457 inChannelUser := th.CreateUser() 458 th.LinkUserToTeam(inChannelUser, th.BasicTeam) 459 th.App.AddUserToChannel(inChannelUser, th.BasicChannel) 460 461 post1 := &model.Post{ChannelId: th.BasicChannel.Id, Message: "@" + inChannelUser.Username} 462 _, resp := Client.CreatePost(post1) 463 CheckNoError(t, resp) 464 CheckCreatedStatus(t, resp) 465 466 timeout := time.After(300 * time.Millisecond) 467 waiting := true 468 for waiting { 469 select { 470 case event := <-WebSocketClient.EventChannel: 471 if event.Event == model.WEBSOCKET_EVENT_EPHEMERAL_MESSAGE { 472 t.Fatal("should not have ephemeral message event") 473 } 474 475 case <-timeout: 476 waiting = false 477 } 478 } 479 480 outOfChannelUser := th.CreateUser() 481 th.LinkUserToTeam(outOfChannelUser, th.BasicTeam) 482 483 post2 := &model.Post{ChannelId: th.BasicChannel.Id, Message: "@" + outOfChannelUser.Username} 484 _, resp = Client.CreatePost(post2) 485 CheckNoError(t, resp) 486 CheckCreatedStatus(t, resp) 487 488 timeout = time.After(300 * time.Millisecond) 489 waiting = true 490 for waiting { 491 select { 492 case event := <-WebSocketClient.EventChannel: 493 if event.Event != model.WEBSOCKET_EVENT_EPHEMERAL_MESSAGE { 494 // Ignore any other events 495 continue 496 } 497 498 wpost := model.PostFromJson(strings.NewReader(event.Data["post"].(string))) 499 if acm, ok := wpost.Props[model.PROPS_ADD_CHANNEL_MEMBER].(map[string]interface{}); !ok { 500 t.Fatal("should have received ephemeral post with 'add_channel_member' in props") 501 } else { 502 if acm["post_id"] == nil || acm["user_ids"] == nil || acm["usernames"] == nil { 503 t.Fatal("should not be nil") 504 } 505 } 506 waiting = false 507 case <-timeout: 508 t.Fatal("timed out waiting for ephemeral message event") 509 } 510 } 511 } 512 513 func TestUpdatePost(t *testing.T) { 514 th := Setup().InitBasic().InitSystemAdmin() 515 defer th.TearDown() 516 Client := th.Client 517 channel := th.BasicChannel 518 519 th.App.SetLicense(model.NewTestLicense()) 520 521 post := &model.Post{ChannelId: channel.Id, Message: "zz" + model.NewId() + "a"} 522 rpost, resp := Client.CreatePost(post) 523 CheckNoError(t, resp) 524 525 if rpost.Message != post.Message { 526 t.Fatal("full name didn't match") 527 } 528 529 if rpost.EditAt != 0 { 530 t.Fatal("Newly created post shouldn't have EditAt set") 531 } 532 533 msg := "zz" + model.NewId() + " update post" 534 rpost.Message = msg 535 rpost.UserId = "" 536 537 rupost, resp := Client.UpdatePost(rpost.Id, rpost) 538 CheckNoError(t, resp) 539 540 if rupost.Message != msg { 541 t.Fatal("failed to updates") 542 } 543 if rupost.EditAt == 0 { 544 t.Fatal("EditAt not updated for post") 545 } 546 547 msg1 := "#hashtag a" + model.NewId() + " update post again" 548 rpost.Message = msg1 549 rpost.Props[model.PROPS_ADD_CHANNEL_MEMBER] = "no good" 550 rrupost, resp := Client.UpdatePost(rpost.Id, rpost) 551 CheckNoError(t, resp) 552 553 if rrupost.Message != msg1 && rrupost.Hashtags != "#hashtag" { 554 t.Fatal("failed to updates") 555 } 556 557 if rrupost.Props[model.PROPS_ADD_CHANNEL_MEMBER] != nil { 558 t.Fatal("failed to sanitize Props['add_channel_member'], should be nil") 559 } 560 561 rpost2, err := th.App.CreatePost(&model.Post{ChannelId: channel.Id, Message: "zz" + model.NewId() + "a", Type: model.POST_JOIN_LEAVE, UserId: th.BasicUser.Id}, channel, false) 562 if err != nil { 563 t.Fatal(err) 564 } 565 566 up2 := &model.Post{Id: rpost2.Id, ChannelId: channel.Id, Message: "zz" + model.NewId() + " update post 2"} 567 _, resp = Client.UpdatePost(rpost2.Id, up2) 568 CheckBadRequestStatus(t, resp) 569 570 Client.Logout() 571 _, resp = Client.UpdatePost(rpost.Id, rpost) 572 CheckUnauthorizedStatus(t, resp) 573 574 th.LoginBasic2() 575 _, resp = Client.UpdatePost(rpost.Id, rpost) 576 CheckForbiddenStatus(t, resp) 577 578 Client.Logout() 579 580 _, resp = th.SystemAdminClient.UpdatePost(rpost.Id, rpost) 581 CheckNoError(t, resp) 582 } 583 584 func TestPatchPost(t *testing.T) { 585 th := Setup().InitBasic().InitSystemAdmin() 586 defer th.TearDown() 587 Client := th.Client 588 channel := th.BasicChannel 589 590 th.App.SetLicense(model.NewTestLicense()) 591 592 post := &model.Post{ 593 ChannelId: channel.Id, 594 IsPinned: true, 595 Message: "#hashtag a message", 596 Props: model.StringInterface{"channel_header": "old_header"}, 597 FileIds: model.StringArray{"file1", "file2"}, 598 HasReactions: true, 599 } 600 post, _ = Client.CreatePost(post) 601 602 patch := &model.PostPatch{} 603 604 patch.IsPinned = model.NewBool(false) 605 patch.Message = model.NewString("#otherhashtag other message") 606 patch.Props = new(model.StringInterface) 607 *patch.Props = model.StringInterface{"channel_header": "new_header"} 608 patch.FileIds = new(model.StringArray) 609 *patch.FileIds = model.StringArray{"file1", "otherfile2", "otherfile3"} 610 patch.HasReactions = model.NewBool(false) 611 612 rpost, resp := Client.PatchPost(post.Id, patch) 613 CheckNoError(t, resp) 614 615 if rpost.IsPinned { 616 t.Fatal("IsPinned did not update properly") 617 } 618 if rpost.Message != "#otherhashtag other message" { 619 t.Fatal("Message did not update properly") 620 } 621 if len(rpost.Props) != 1 { 622 t.Fatal("Props did not update properly") 623 } 624 if !reflect.DeepEqual(rpost.Props, *patch.Props) { 625 t.Fatal("Props did not update properly") 626 } 627 if rpost.Hashtags != "#otherhashtag" { 628 t.Fatal("Message did not update properly") 629 } 630 if len(rpost.FileIds) != 3 { 631 t.Fatal("FileIds did not update properly") 632 } 633 if !reflect.DeepEqual(rpost.FileIds, *patch.FileIds) { 634 t.Fatal("FileIds did not update properly") 635 } 636 if rpost.HasReactions { 637 t.Fatal("HasReactions did not update properly") 638 } 639 640 if r, err := Client.DoApiPut("/posts/"+post.Id+"/patch", "garbage"); err == nil { 641 t.Fatal("should have errored") 642 } else { 643 if r.StatusCode != http.StatusBadRequest { 644 t.Log("actual: " + strconv.Itoa(r.StatusCode)) 645 t.Log("expected: " + strconv.Itoa(http.StatusBadRequest)) 646 t.Fatal("wrong status code") 647 } 648 } 649 650 _, resp = Client.PatchPost("junk", patch) 651 CheckBadRequestStatus(t, resp) 652 653 _, resp = Client.PatchPost(GenerateTestId(), patch) 654 CheckForbiddenStatus(t, resp) 655 656 Client.Logout() 657 _, resp = Client.PatchPost(post.Id, patch) 658 CheckUnauthorizedStatus(t, resp) 659 660 th.LoginBasic2() 661 _, resp = Client.PatchPost(post.Id, patch) 662 CheckForbiddenStatus(t, resp) 663 664 th.LoginTeamAdmin() 665 _, resp = Client.PatchPost(post.Id, patch) 666 CheckNoError(t, resp) 667 668 _, resp = th.SystemAdminClient.PatchPost(post.Id, patch) 669 CheckNoError(t, resp) 670 } 671 672 func TestPinPost(t *testing.T) { 673 th := Setup().InitBasic().InitSystemAdmin() 674 defer th.TearDown() 675 Client := th.Client 676 677 post := th.BasicPost 678 pass, resp := Client.PinPost(post.Id) 679 CheckNoError(t, resp) 680 681 if !pass { 682 t.Fatal("should have passed") 683 } 684 685 if rpost, err := th.App.GetSinglePost(post.Id); err != nil && !rpost.IsPinned { 686 t.Fatal("failed to pin post") 687 } 688 689 pass, resp = Client.PinPost("junk") 690 CheckBadRequestStatus(t, resp) 691 692 if pass { 693 t.Fatal("should have failed") 694 } 695 696 _, resp = Client.PinPost(GenerateTestId()) 697 CheckForbiddenStatus(t, resp) 698 699 Client.Logout() 700 _, resp = Client.PinPost(post.Id) 701 CheckUnauthorizedStatus(t, resp) 702 703 _, resp = th.SystemAdminClient.PinPost(post.Id) 704 CheckNoError(t, resp) 705 } 706 707 func TestUnpinPost(t *testing.T) { 708 th := Setup().InitBasic().InitSystemAdmin() 709 defer th.TearDown() 710 Client := th.Client 711 712 pinnedPost := th.CreatePinnedPost() 713 pass, resp := Client.UnpinPost(pinnedPost.Id) 714 CheckNoError(t, resp) 715 716 if !pass { 717 t.Fatal("should have passed") 718 } 719 720 if rpost, err := th.App.GetSinglePost(pinnedPost.Id); err != nil && rpost.IsPinned { 721 t.Fatal("failed to pin post") 722 } 723 724 pass, resp = Client.UnpinPost("junk") 725 CheckBadRequestStatus(t, resp) 726 727 if pass { 728 t.Fatal("should have failed") 729 } 730 731 _, resp = Client.UnpinPost(GenerateTestId()) 732 CheckForbiddenStatus(t, resp) 733 734 Client.Logout() 735 _, resp = Client.UnpinPost(pinnedPost.Id) 736 CheckUnauthorizedStatus(t, resp) 737 738 _, resp = th.SystemAdminClient.UnpinPost(pinnedPost.Id) 739 CheckNoError(t, resp) 740 } 741 742 func TestGetPostsForChannel(t *testing.T) { 743 th := Setup().InitBasic().InitSystemAdmin() 744 defer th.TearDown() 745 Client := th.Client 746 747 post1 := th.CreatePost() 748 post2 := th.CreatePost() 749 post3 := &model.Post{ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a", RootId: post1.Id} 750 post3, _ = Client.CreatePost(post3) 751 752 time.Sleep(300 * time.Millisecond) 753 since := model.GetMillis() 754 time.Sleep(300 * time.Millisecond) 755 756 post4 := th.CreatePost() 757 758 posts, resp := Client.GetPostsForChannel(th.BasicChannel.Id, 0, 60, "") 759 CheckNoError(t, resp) 760 761 if posts.Order[0] != post4.Id { 762 t.Fatal("wrong order") 763 } 764 765 if posts.Order[1] != post3.Id { 766 t.Fatal("wrong order") 767 } 768 769 if posts.Order[2] != post2.Id { 770 t.Fatal("wrong order") 771 } 772 773 if posts.Order[3] != post1.Id { 774 t.Fatal("wrong order") 775 } 776 777 posts, resp = Client.GetPostsForChannel(th.BasicChannel.Id, 0, 3, resp.Etag) 778 CheckEtag(t, posts, resp) 779 780 posts, resp = Client.GetPostsForChannel(th.BasicChannel.Id, 0, 3, "") 781 CheckNoError(t, resp) 782 783 if len(posts.Order) != 3 { 784 t.Fatal("wrong number returned") 785 } 786 787 if _, ok := posts.Posts[post3.Id]; !ok { 788 t.Fatal("missing comment") 789 } 790 791 if _, ok := posts.Posts[post1.Id]; !ok { 792 t.Fatal("missing root post") 793 } 794 795 posts, resp = Client.GetPostsForChannel(th.BasicChannel.Id, 1, 1, "") 796 CheckNoError(t, resp) 797 798 if posts.Order[0] != post3.Id { 799 t.Fatal("wrong order") 800 } 801 802 posts, resp = Client.GetPostsForChannel(th.BasicChannel.Id, 10000, 10000, "") 803 CheckNoError(t, resp) 804 805 if len(posts.Order) != 0 { 806 t.Fatal("should be no posts") 807 } 808 809 post5 := th.CreatePost() 810 811 posts, resp = Client.GetPostsSince(th.BasicChannel.Id, since) 812 CheckNoError(t, resp) 813 814 if len(posts.Posts) != 2 { 815 t.Log(posts.Posts) 816 t.Fatal("should return 2 posts") 817 } 818 819 found := make([]bool, 2) 820 for _, p := range posts.Posts { 821 if p.CreateAt < since { 822 t.Fatal("bad create at for post returned") 823 } 824 if p.Id == post4.Id { 825 found[0] = true 826 } else if p.Id == post5.Id { 827 found[1] = true 828 } 829 } 830 831 for _, f := range found { 832 if !f { 833 t.Fatal("missing post") 834 } 835 } 836 837 _, resp = Client.GetPostsForChannel("", 0, 60, "") 838 CheckBadRequestStatus(t, resp) 839 840 _, resp = Client.GetPostsForChannel("junk", 0, 60, "") 841 CheckBadRequestStatus(t, resp) 842 843 _, resp = Client.GetPostsForChannel(model.NewId(), 0, 60, "") 844 CheckForbiddenStatus(t, resp) 845 846 Client.Logout() 847 _, resp = Client.GetPostsForChannel(model.NewId(), 0, 60, "") 848 CheckUnauthorizedStatus(t, resp) 849 850 _, resp = th.SystemAdminClient.GetPostsForChannel(th.BasicChannel.Id, 0, 60, "") 851 CheckNoError(t, resp) 852 } 853 854 func TestGetFlaggedPostsForUser(t *testing.T) { 855 th := Setup().InitBasic().InitSystemAdmin() 856 defer th.TearDown() 857 Client := th.Client 858 user := th.BasicUser 859 team1 := th.BasicTeam 860 channel1 := th.BasicChannel 861 post1 := th.CreatePost() 862 channel2 := th.CreatePublicChannel() 863 post2 := th.CreatePostWithClient(Client, channel2) 864 865 preference := model.Preference{ 866 UserId: user.Id, 867 Category: model.PREFERENCE_CATEGORY_FLAGGED_POST, 868 Name: post1.Id, 869 Value: "true", 870 } 871 Client.UpdatePreferences(user.Id, &model.Preferences{preference}) 872 preference.Name = post2.Id 873 Client.UpdatePreferences(user.Id, &model.Preferences{preference}) 874 875 opl := model.NewPostList() 876 opl.AddPost(post1) 877 opl.AddOrder(post1.Id) 878 879 rpl, resp := Client.GetFlaggedPostsForUserInChannel(user.Id, channel1.Id, 0, 10) 880 CheckNoError(t, resp) 881 882 if len(rpl.Posts) != 1 { 883 t.Fatal("should have returned 1 post") 884 } 885 886 if !reflect.DeepEqual(rpl.Posts, opl.Posts) { 887 t.Fatal("posts should have matched") 888 } 889 890 rpl, resp = Client.GetFlaggedPostsForUserInChannel(user.Id, channel1.Id, 0, 1) 891 CheckNoError(t, resp) 892 893 if len(rpl.Posts) != 1 { 894 t.Fatal("should have returned 1 post") 895 } 896 897 rpl, resp = Client.GetFlaggedPostsForUserInChannel(user.Id, channel1.Id, 1, 1) 898 CheckNoError(t, resp) 899 900 if len(rpl.Posts) != 0 { 901 t.Fatal("should be empty") 902 } 903 904 rpl, resp = Client.GetFlaggedPostsForUserInChannel(user.Id, GenerateTestId(), 0, 10) 905 CheckNoError(t, resp) 906 907 if len(rpl.Posts) != 0 { 908 t.Fatal("should be empty") 909 } 910 911 rpl, resp = Client.GetFlaggedPostsForUserInChannel(user.Id, "junk", 0, 10) 912 CheckBadRequestStatus(t, resp) 913 914 if rpl != nil { 915 t.Fatal("should be nil") 916 } 917 918 opl.AddPost(post2) 919 opl.AddOrder(post2.Id) 920 921 rpl, resp = Client.GetFlaggedPostsForUserInTeam(user.Id, team1.Id, 0, 10) 922 CheckNoError(t, resp) 923 924 if len(rpl.Posts) != 2 { 925 t.Fatal("should have returned 2 posts") 926 } 927 928 if !reflect.DeepEqual(rpl.Posts, opl.Posts) { 929 t.Fatal("posts should have matched") 930 } 931 932 rpl, resp = Client.GetFlaggedPostsForUserInTeam(user.Id, team1.Id, 0, 1) 933 CheckNoError(t, resp) 934 935 if len(rpl.Posts) != 1 { 936 t.Fatal("should have returned 1 post") 937 } 938 939 rpl, resp = Client.GetFlaggedPostsForUserInTeam(user.Id, team1.Id, 1, 1) 940 CheckNoError(t, resp) 941 942 if len(rpl.Posts) != 1 { 943 t.Fatal("should have returned 1 post") 944 } 945 946 rpl, resp = Client.GetFlaggedPostsForUserInTeam(user.Id, team1.Id, 1000, 10) 947 CheckNoError(t, resp) 948 949 if len(rpl.Posts) != 0 { 950 t.Fatal("should be empty") 951 } 952 953 rpl, resp = Client.GetFlaggedPostsForUserInTeam(user.Id, GenerateTestId(), 0, 10) 954 CheckNoError(t, resp) 955 956 if len(rpl.Posts) != 0 { 957 t.Fatal("should be empty") 958 } 959 960 rpl, resp = Client.GetFlaggedPostsForUserInTeam(user.Id, "junk", 0, 10) 961 CheckBadRequestStatus(t, resp) 962 963 if rpl != nil { 964 t.Fatal("should be nil") 965 } 966 967 channel3 := th.CreatePrivateChannel() 968 post4 := th.CreatePostWithClient(Client, channel3) 969 970 preference.Name = post4.Id 971 Client.UpdatePreferences(user.Id, &model.Preferences{preference}) 972 973 opl.AddPost(post4) 974 opl.AddOrder(post4.Id) 975 976 rpl, resp = Client.GetFlaggedPostsForUser(user.Id, 0, 10) 977 CheckNoError(t, resp) 978 979 if len(rpl.Posts) != 3 { 980 t.Fatal("should have returned 3 posts") 981 } 982 983 if !reflect.DeepEqual(rpl.Posts, opl.Posts) { 984 t.Fatal("posts should have matched") 985 } 986 987 rpl, resp = Client.GetFlaggedPostsForUser(user.Id, 0, 2) 988 CheckNoError(t, resp) 989 990 if len(rpl.Posts) != 2 { 991 t.Fatal("should have returned 2 posts") 992 } 993 994 rpl, resp = Client.GetFlaggedPostsForUser(user.Id, 2, 2) 995 CheckNoError(t, resp) 996 997 if len(rpl.Posts) != 1 { 998 t.Fatal("should have returned 1 post") 999 } 1000 1001 rpl, resp = Client.GetFlaggedPostsForUser(user.Id, 1000, 10) 1002 CheckNoError(t, resp) 1003 1004 if len(rpl.Posts) != 0 { 1005 t.Fatal("should be empty") 1006 } 1007 1008 _, resp = Client.GetFlaggedPostsForUser("junk", 0, 10) 1009 CheckBadRequestStatus(t, resp) 1010 1011 _, resp = Client.GetFlaggedPostsForUser(GenerateTestId(), 0, 10) 1012 CheckForbiddenStatus(t, resp) 1013 1014 Client.Logout() 1015 1016 rpl, resp = Client.GetFlaggedPostsForUserInChannel(user.Id, channel1.Id, 0, 10) 1017 CheckUnauthorizedStatus(t, resp) 1018 1019 rpl, resp = Client.GetFlaggedPostsForUserInTeam(user.Id, team1.Id, 0, 10) 1020 CheckUnauthorizedStatus(t, resp) 1021 1022 rpl, resp = Client.GetFlaggedPostsForUser(user.Id, 0, 10) 1023 CheckUnauthorizedStatus(t, resp) 1024 1025 rpl, resp = th.SystemAdminClient.GetFlaggedPostsForUserInChannel(user.Id, channel1.Id, 0, 10) 1026 CheckNoError(t, resp) 1027 1028 rpl, resp = th.SystemAdminClient.GetFlaggedPostsForUserInTeam(user.Id, team1.Id, 0, 10) 1029 CheckNoError(t, resp) 1030 1031 rpl, resp = th.SystemAdminClient.GetFlaggedPostsForUser(user.Id, 0, 10) 1032 CheckNoError(t, resp) 1033 } 1034 1035 func TestGetPostsAfterAndBefore(t *testing.T) { 1036 th := Setup().InitBasic() 1037 defer th.TearDown() 1038 Client := th.Client 1039 1040 post1 := th.CreatePost() 1041 post2 := th.CreatePost() 1042 post3 := th.CreatePost() 1043 post4 := th.CreatePost() 1044 post5 := th.CreatePost() 1045 1046 posts, resp := Client.GetPostsBefore(th.BasicChannel.Id, post3.Id, 0, 100, "") 1047 CheckNoError(t, resp) 1048 1049 found := make([]bool, 2) 1050 for _, p := range posts.Posts { 1051 if p.Id == post1.Id { 1052 found[0] = true 1053 } else if p.Id == post2.Id { 1054 found[1] = true 1055 } 1056 1057 if p.Id == post4.Id || p.Id == post5.Id { 1058 t.Fatal("returned posts after") 1059 } 1060 } 1061 1062 for _, f := range found { 1063 if !f { 1064 t.Fatal("missing post") 1065 } 1066 } 1067 1068 posts, resp = Client.GetPostsBefore(th.BasicChannel.Id, post3.Id, 1, 1, "") 1069 CheckNoError(t, resp) 1070 1071 if len(posts.Posts) != 1 { 1072 t.Fatal("too many posts returned") 1073 } 1074 1075 posts, resp = Client.GetPostsBefore(th.BasicChannel.Id, "junk", 1, 1, "") 1076 CheckNoError(t, resp) 1077 1078 if len(posts.Posts) != 0 { 1079 t.Fatal("should have no posts") 1080 } 1081 1082 posts, resp = Client.GetPostsAfter(th.BasicChannel.Id, post3.Id, 0, 100, "") 1083 CheckNoError(t, resp) 1084 1085 found = make([]bool, 2) 1086 for _, p := range posts.Posts { 1087 if p.Id == post4.Id { 1088 found[0] = true 1089 } else if p.Id == post5.Id { 1090 found[1] = true 1091 } 1092 1093 if p.Id == post1.Id || p.Id == post2.Id { 1094 t.Fatal("returned posts before") 1095 } 1096 } 1097 1098 for _, f := range found { 1099 if !f { 1100 t.Fatal("missing post") 1101 } 1102 } 1103 1104 posts, resp = Client.GetPostsAfter(th.BasicChannel.Id, post3.Id, 1, 1, "") 1105 CheckNoError(t, resp) 1106 1107 if len(posts.Posts) != 1 { 1108 t.Fatal("too many posts returned") 1109 } 1110 1111 posts, resp = Client.GetPostsAfter(th.BasicChannel.Id, "junk", 1, 1, "") 1112 CheckNoError(t, resp) 1113 1114 if len(posts.Posts) != 0 { 1115 t.Fatal("should have no posts") 1116 } 1117 } 1118 1119 func TestGetPost(t *testing.T) { 1120 th := Setup().InitBasic().InitSystemAdmin() 1121 defer th.TearDown() 1122 Client := th.Client 1123 1124 post, resp := Client.GetPost(th.BasicPost.Id, "") 1125 CheckNoError(t, resp) 1126 1127 if post.Id != th.BasicPost.Id { 1128 t.Fatal("post ids don't match") 1129 } 1130 1131 post, resp = Client.GetPost(th.BasicPost.Id, resp.Etag) 1132 CheckEtag(t, post, resp) 1133 1134 _, resp = Client.GetPost("", "") 1135 CheckNotFoundStatus(t, resp) 1136 1137 _, resp = Client.GetPost("junk", "") 1138 CheckBadRequestStatus(t, resp) 1139 1140 _, resp = Client.GetPost(model.NewId(), "") 1141 CheckNotFoundStatus(t, resp) 1142 1143 Client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id) 1144 1145 // Channel is public, should be able to read post 1146 post, resp = Client.GetPost(th.BasicPost.Id, "") 1147 CheckNoError(t, resp) 1148 1149 privatePost := th.CreatePostWithClient(Client, th.BasicPrivateChannel) 1150 1151 post, resp = Client.GetPost(privatePost.Id, "") 1152 CheckNoError(t, resp) 1153 1154 Client.RemoveUserFromChannel(th.BasicPrivateChannel.Id, th.BasicUser.Id) 1155 1156 // Channel is private, should not be able to read post 1157 post, resp = Client.GetPost(privatePost.Id, "") 1158 CheckForbiddenStatus(t, resp) 1159 1160 Client.Logout() 1161 _, resp = Client.GetPost(model.NewId(), "") 1162 CheckUnauthorizedStatus(t, resp) 1163 1164 post, resp = th.SystemAdminClient.GetPost(th.BasicPost.Id, "") 1165 CheckNoError(t, resp) 1166 } 1167 1168 func TestDeletePost(t *testing.T) { 1169 th := Setup().InitBasic().InitSystemAdmin() 1170 defer th.TearDown() 1171 Client := th.Client 1172 1173 _, resp := Client.DeletePost("") 1174 CheckNotFoundStatus(t, resp) 1175 1176 _, resp = Client.DeletePost("junk") 1177 CheckBadRequestStatus(t, resp) 1178 1179 _, resp = Client.DeletePost(th.BasicPost.Id) 1180 CheckForbiddenStatus(t, resp) 1181 1182 Client.Login(th.TeamAdminUser.Email, th.TeamAdminUser.Password) 1183 _, resp = Client.DeletePost(th.BasicPost.Id) 1184 CheckNoError(t, resp) 1185 1186 post := th.CreatePost() 1187 user := th.CreateUser() 1188 1189 Client.Logout() 1190 Client.Login(user.Email, user.Password) 1191 1192 _, resp = Client.DeletePost(post.Id) 1193 CheckForbiddenStatus(t, resp) 1194 1195 Client.Logout() 1196 _, resp = Client.DeletePost(model.NewId()) 1197 CheckUnauthorizedStatus(t, resp) 1198 1199 status, resp := th.SystemAdminClient.DeletePost(post.Id) 1200 if !status { 1201 t.Fatal("post should return status OK") 1202 } 1203 CheckNoError(t, resp) 1204 } 1205 1206 func TestGetPostThread(t *testing.T) { 1207 th := Setup().InitBasic().InitSystemAdmin() 1208 defer th.TearDown() 1209 Client := th.Client 1210 1211 post := &model.Post{ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a", RootId: th.BasicPost.Id} 1212 post, _ = Client.CreatePost(post) 1213 1214 list, resp := Client.GetPostThread(th.BasicPost.Id, "") 1215 CheckNoError(t, resp) 1216 1217 var list2 *model.PostList 1218 list2, resp = Client.GetPostThread(th.BasicPost.Id, resp.Etag) 1219 CheckEtag(t, list2, resp) 1220 1221 if list.Order[0] != th.BasicPost.Id { 1222 t.Fatal("wrong order") 1223 } 1224 1225 if _, ok := list.Posts[th.BasicPost.Id]; !ok { 1226 t.Fatal("should have had post") 1227 } 1228 1229 if _, ok := list.Posts[post.Id]; !ok { 1230 t.Fatal("should have had post") 1231 } 1232 1233 _, resp = Client.GetPostThread("junk", "") 1234 CheckBadRequestStatus(t, resp) 1235 1236 _, resp = Client.GetPostThread(model.NewId(), "") 1237 CheckNotFoundStatus(t, resp) 1238 1239 Client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id) 1240 1241 // Channel is public, should be able to read post 1242 _, resp = Client.GetPostThread(th.BasicPost.Id, "") 1243 CheckNoError(t, resp) 1244 1245 privatePost := th.CreatePostWithClient(Client, th.BasicPrivateChannel) 1246 1247 _, resp = Client.GetPostThread(privatePost.Id, "") 1248 CheckNoError(t, resp) 1249 1250 Client.RemoveUserFromChannel(th.BasicPrivateChannel.Id, th.BasicUser.Id) 1251 1252 // Channel is private, should not be able to read post 1253 _, resp = Client.GetPostThread(privatePost.Id, "") 1254 CheckForbiddenStatus(t, resp) 1255 1256 Client.Logout() 1257 _, resp = Client.GetPostThread(model.NewId(), "") 1258 CheckUnauthorizedStatus(t, resp) 1259 1260 list, resp = th.SystemAdminClient.GetPostThread(th.BasicPost.Id, "") 1261 CheckNoError(t, resp) 1262 } 1263 1264 func TestSearchPosts(t *testing.T) { 1265 th := Setup().InitBasic() 1266 defer th.TearDown() 1267 th.LoginBasic() 1268 Client := th.Client 1269 1270 message := "search for post1" 1271 _ = th.CreateMessagePost(message) 1272 1273 message = "search for post2" 1274 post2 := th.CreateMessagePost(message) 1275 1276 message = "#hashtag search for post3" 1277 post3 := th.CreateMessagePost(message) 1278 1279 message = "hashtag for post4" 1280 _ = th.CreateMessagePost(message) 1281 1282 posts, resp := Client.SearchPosts(th.BasicTeam.Id, "search", false) 1283 CheckNoError(t, resp) 1284 if len(posts.Order) != 3 { 1285 t.Fatal("wrong search") 1286 } 1287 1288 posts, resp = Client.SearchPosts(th.BasicTeam.Id, "post2", false) 1289 CheckNoError(t, resp) 1290 if len(posts.Order) != 1 && posts.Order[0] == post2.Id { 1291 t.Fatal("wrong search") 1292 } 1293 1294 posts, resp = Client.SearchPosts(th.BasicTeam.Id, "#hashtag", false) 1295 CheckNoError(t, resp) 1296 if len(posts.Order) != 1 && posts.Order[0] == post3.Id { 1297 t.Fatal("wrong search") 1298 } 1299 1300 if posts, resp = Client.SearchPosts(th.BasicTeam.Id, "*", false); len(posts.Order) != 0 { 1301 t.Fatal("searching for just * shouldn't return any results") 1302 } 1303 1304 posts, resp = Client.SearchPosts(th.BasicTeam.Id, "post1 post2", true) 1305 CheckNoError(t, resp) 1306 if len(posts.Order) != 2 { 1307 t.Fatal("wrong search results") 1308 } 1309 1310 _, resp = Client.SearchPosts("junk", "#sgtitlereview", false) 1311 CheckBadRequestStatus(t, resp) 1312 1313 _, resp = Client.SearchPosts(model.NewId(), "#sgtitlereview", false) 1314 CheckForbiddenStatus(t, resp) 1315 1316 _, resp = Client.SearchPosts(th.BasicTeam.Id, "", false) 1317 CheckBadRequestStatus(t, resp) 1318 1319 Client.Logout() 1320 _, resp = Client.SearchPosts(th.BasicTeam.Id, "#sgtitlereview", false) 1321 CheckUnauthorizedStatus(t, resp) 1322 1323 } 1324 1325 func TestSearchHashtagPosts(t *testing.T) { 1326 th := Setup().InitBasic() 1327 defer th.TearDown() 1328 th.LoginBasic() 1329 Client := th.Client 1330 1331 message := "#sgtitlereview with space" 1332 _ = th.CreateMessagePost(message) 1333 1334 message = "#sgtitlereview\n with return" 1335 _ = th.CreateMessagePost(message) 1336 1337 message = "no hashtag" 1338 _ = th.CreateMessagePost(message) 1339 1340 posts, resp := Client.SearchPosts(th.BasicTeam.Id, "#sgtitlereview", false) 1341 CheckNoError(t, resp) 1342 if len(posts.Order) != 2 { 1343 t.Fatal("wrong search results") 1344 } 1345 1346 Client.Logout() 1347 _, resp = Client.SearchPosts(th.BasicTeam.Id, "#sgtitlereview", false) 1348 CheckUnauthorizedStatus(t, resp) 1349 } 1350 1351 func TestSearchPostsInChannel(t *testing.T) { 1352 th := Setup().InitBasic() 1353 defer th.TearDown() 1354 th.LoginBasic() 1355 Client := th.Client 1356 1357 channel := th.CreatePublicChannel() 1358 1359 message := "sgtitlereview with space" 1360 _ = th.CreateMessagePost(message) 1361 1362 message = "sgtitlereview\n with return" 1363 _ = th.CreateMessagePostWithClient(Client, th.BasicChannel2, message) 1364 1365 message = "other message with no return" 1366 _ = th.CreateMessagePostWithClient(Client, th.BasicChannel2, message) 1367 1368 message = "other message with no return" 1369 _ = th.CreateMessagePostWithClient(Client, channel, message) 1370 1371 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "channel:", false); len(posts.Order) != 0 { 1372 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1373 } 1374 1375 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "in:", false); len(posts.Order) != 0 { 1376 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1377 } 1378 1379 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "channel:"+th.BasicChannel.Name, false); len(posts.Order) != 2 { 1380 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1381 } 1382 1383 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "in:"+th.BasicChannel2.Name, false); len(posts.Order) != 2 { 1384 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1385 } 1386 1387 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "channel:"+th.BasicChannel2.Name, false); len(posts.Order) != 2 { 1388 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1389 } 1390 1391 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "ChAnNeL:"+th.BasicChannel2.Name, false); len(posts.Order) != 2 { 1392 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1393 } 1394 1395 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "sgtitlereview", false); len(posts.Order) != 2 { 1396 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1397 } 1398 1399 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "sgtitlereview channel:"+th.BasicChannel.Name, false); len(posts.Order) != 1 { 1400 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1401 } 1402 1403 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "sgtitlereview in: "+th.BasicChannel2.Name, false); len(posts.Order) != 1 { 1404 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1405 } 1406 1407 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "sgtitlereview channel: "+th.BasicChannel2.Name, false); len(posts.Order) != 1 { 1408 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1409 } 1410 1411 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "channel: "+th.BasicChannel2.Name+" channel: "+channel.Name, false); len(posts.Order) != 3 { 1412 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1413 } 1414 1415 } 1416 1417 func TestSearchPostsFromUser(t *testing.T) { 1418 th := Setup().InitBasic() 1419 defer th.TearDown() 1420 Client := th.Client 1421 1422 th.LoginTeamAdmin() 1423 user := th.CreateUser() 1424 th.LinkUserToTeam(user, th.BasicTeam) 1425 th.App.AddUserToChannel(user, th.BasicChannel) 1426 th.App.AddUserToChannel(user, th.BasicChannel2) 1427 1428 message := "sgtitlereview with space" 1429 _ = th.CreateMessagePost(message) 1430 1431 Client.Logout() 1432 th.LoginBasic2() 1433 1434 message = "sgtitlereview\n with return" 1435 _ = th.CreateMessagePostWithClient(Client, th.BasicChannel2, message) 1436 1437 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "from: "+th.TeamAdminUser.Username, false); len(posts.Order) != 2 { 1438 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1439 } 1440 1441 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "from: "+th.BasicUser2.Username, false); len(posts.Order) != 1 { 1442 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1443 } 1444 1445 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "from: "+th.BasicUser2.Username+" sgtitlereview", false); len(posts.Order) != 1 { 1446 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1447 } 1448 1449 message = "hullo" 1450 _ = th.CreateMessagePost(message) 1451 1452 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "from: "+th.BasicUser2.Username+" in:"+th.BasicChannel.Name, false); len(posts.Order) != 1 { 1453 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1454 } 1455 1456 Client.Login(user.Email, user.Password) 1457 1458 // wait for the join/leave messages to be created for user3 since they're done asynchronously 1459 time.Sleep(100 * time.Millisecond) 1460 1461 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "from: "+th.BasicUser2.Username, false); len(posts.Order) != 2 { 1462 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1463 } 1464 1465 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "from: "+th.BasicUser2.Username+" from: "+user.Username, false); len(posts.Order) != 2 { 1466 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1467 } 1468 1469 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "from: "+th.BasicUser2.Username+" from: "+user.Username+" in:"+th.BasicChannel2.Name, false); len(posts.Order) != 1 { 1470 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1471 } 1472 1473 message = "coconut" 1474 _ = th.CreateMessagePostWithClient(Client, th.BasicChannel2, message) 1475 1476 if posts, _ := Client.SearchPosts(th.BasicTeam.Id, "from: "+th.BasicUser2.Username+" from: "+user.Username+" in:"+th.BasicChannel2.Name+" coconut", false); len(posts.Order) != 1 { 1477 t.Fatalf("wrong number of posts returned %v", len(posts.Order)) 1478 } 1479 } 1480 1481 func TestGetFileInfosForPost(t *testing.T) { 1482 th := Setup().InitBasic().InitSystemAdmin() 1483 defer th.TearDown() 1484 Client := th.Client 1485 1486 fileIds := make([]string, 3) 1487 if data, err := readTestFile("test.png"); err != nil { 1488 t.Fatal(err) 1489 } else { 1490 for i := 0; i < 3; i++ { 1491 fileResp, _ := Client.UploadFile(data, th.BasicChannel.Id, "test.png") 1492 fileIds[i] = fileResp.FileInfos[0].Id 1493 } 1494 } 1495 1496 post := &model.Post{ChannelId: th.BasicChannel.Id, Message: "zz" + model.NewId() + "a", FileIds: fileIds} 1497 post, _ = Client.CreatePost(post) 1498 1499 infos, resp := Client.GetFileInfosForPost(post.Id, "") 1500 CheckNoError(t, resp) 1501 1502 if len(infos) != 3 { 1503 t.Fatal("missing file infos") 1504 } 1505 1506 found := false 1507 for _, info := range infos { 1508 if info.Id == fileIds[0] { 1509 found = true 1510 } 1511 } 1512 1513 if !found { 1514 t.Fatal("missing file info") 1515 } 1516 1517 infos, resp = Client.GetFileInfosForPost(post.Id, resp.Etag) 1518 CheckEtag(t, infos, resp) 1519 1520 infos, resp = Client.GetFileInfosForPost(th.BasicPost.Id, "") 1521 CheckNoError(t, resp) 1522 1523 if len(infos) != 0 { 1524 t.Fatal("should have no file infos") 1525 } 1526 1527 _, resp = Client.GetFileInfosForPost("junk", "") 1528 CheckBadRequestStatus(t, resp) 1529 1530 _, resp = Client.GetFileInfosForPost(model.NewId(), "") 1531 CheckForbiddenStatus(t, resp) 1532 1533 Client.Logout() 1534 _, resp = Client.GetFileInfosForPost(model.NewId(), "") 1535 CheckUnauthorizedStatus(t, resp) 1536 1537 _, resp = th.SystemAdminClient.GetFileInfosForPost(th.BasicPost.Id, "") 1538 CheckNoError(t, resp) 1539 }