github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+incompatible/app/post_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  	"encoding/json"
     8  	"fmt"
     9  	"net/http"
    10  	"net/http/httptest"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	"github.com/mattermost/mattermost-server/model"
    18  )
    19  
    20  func TestUpdatePostEditAt(t *testing.T) {
    21  	th := Setup().InitBasic()
    22  	defer th.TearDown()
    23  
    24  	post := &model.Post{}
    25  	*post = *th.BasicPost
    26  
    27  	post.IsPinned = true
    28  	if saved, err := th.App.UpdatePost(post, true); err != nil {
    29  		t.Fatal(err)
    30  	} else if saved.EditAt != post.EditAt {
    31  		t.Fatal("shouldn't have updated post.EditAt when pinning post")
    32  
    33  		*post = *saved
    34  	}
    35  
    36  	time.Sleep(time.Millisecond * 100)
    37  
    38  	post.Message = model.NewId()
    39  	if saved, err := th.App.UpdatePost(post, true); err != nil {
    40  		t.Fatal(err)
    41  	} else if saved.EditAt == post.EditAt {
    42  		t.Fatal("should have updated post.EditAt when updating post message")
    43  	}
    44  }
    45  
    46  func TestPostReplyToPostWhereRootPosterLeftChannel(t *testing.T) {
    47  	// This test ensures that when replying to a root post made by a user who has since left the channel, the reply
    48  	// post completes successfully. This is a regression test for PLT-6523.
    49  	th := Setup().InitBasic()
    50  	defer th.TearDown()
    51  
    52  	channel := th.BasicChannel
    53  	userInChannel := th.BasicUser2
    54  	userNotInChannel := th.BasicUser
    55  	rootPost := th.BasicPost
    56  
    57  	if _, err := th.App.AddUserToChannel(userInChannel, channel); err != nil {
    58  		t.Fatal(err)
    59  	}
    60  
    61  	if err := th.App.RemoveUserFromChannel(userNotInChannel.Id, "", channel); err != nil {
    62  		t.Fatal(err)
    63  	}
    64  
    65  	replyPost := model.Post{
    66  		Message:       "asd",
    67  		ChannelId:     channel.Id,
    68  		RootId:        rootPost.Id,
    69  		ParentId:      rootPost.Id,
    70  		PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
    71  		UserId:        userInChannel.Id,
    72  		CreateAt:      0,
    73  	}
    74  
    75  	if _, err := th.App.CreatePostAsUser(&replyPost); err != nil {
    76  		t.Fatal(err)
    77  	}
    78  }
    79  
    80  func TestPostAction(t *testing.T) {
    81  	th := Setup().InitBasic()
    82  	defer th.TearDown()
    83  
    84  	th.App.UpdateConfig(func(cfg *model.Config) {
    85  		*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1"
    86  	})
    87  
    88  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    89  		var request model.PostActionIntegrationRequest
    90  		err := json.NewDecoder(r.Body).Decode(&request)
    91  		assert.NoError(t, err)
    92  		assert.Equal(t, request.UserId, th.BasicUser.Id)
    93  		assert.Equal(t, "foo", request.Context["s"])
    94  		assert.EqualValues(t, 3, request.Context["n"])
    95  		fmt.Fprintf(w, `{"update": {"message": "updated"}, "ephemeral_text": "foo"}`)
    96  	}))
    97  	defer ts.Close()
    98  
    99  	interactivePost := model.Post{
   100  		Message:       "Interactive post",
   101  		ChannelId:     th.BasicChannel.Id,
   102  		PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
   103  		UserId:        th.BasicUser.Id,
   104  		Props: model.StringInterface{
   105  			"attachments": []*model.SlackAttachment{
   106  				{
   107  					Text: "hello",
   108  					Actions: []*model.PostAction{
   109  						{
   110  							Integration: &model.PostActionIntegration{
   111  								Context: model.StringInterface{
   112  									"s": "foo",
   113  									"n": 3,
   114  								},
   115  								URL: ts.URL,
   116  							},
   117  							Name: "action",
   118  						},
   119  					},
   120  				},
   121  			},
   122  		},
   123  	}
   124  
   125  	post, err := th.App.CreatePostAsUser(&interactivePost)
   126  	require.Nil(t, err)
   127  
   128  	attachments, ok := post.Props["attachments"].([]*model.SlackAttachment)
   129  	require.True(t, ok)
   130  
   131  	require.NotEmpty(t, attachments[0].Actions)
   132  	require.NotEmpty(t, attachments[0].Actions[0].Id)
   133  
   134  	err = th.App.DoPostAction(post.Id, "notavalidid", th.BasicUser.Id)
   135  	require.NotNil(t, err)
   136  	assert.Equal(t, http.StatusNotFound, err.StatusCode)
   137  
   138  	err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id)
   139  	require.Nil(t, err)
   140  }
   141  
   142  func TestPostChannelMentions(t *testing.T) {
   143  	th := Setup().InitBasic()
   144  	defer th.TearDown()
   145  
   146  	channel := th.BasicChannel
   147  	user := th.BasicUser
   148  
   149  	channelToMention, err := th.App.CreateChannel(&model.Channel{
   150  		DisplayName: "Mention Test",
   151  		Name:        "mention-test",
   152  		Type:        model.CHANNEL_OPEN,
   153  		TeamId:      th.BasicTeam.Id,
   154  	}, false)
   155  	if err != nil {
   156  		t.Fatal(err.Error())
   157  	}
   158  	defer th.App.PermanentDeleteChannel(channelToMention)
   159  
   160  	_, err = th.App.AddUserToChannel(user, channel)
   161  	require.Nil(t, err)
   162  
   163  	post := &model.Post{
   164  		Message:       fmt.Sprintf("hello, ~%v!", channelToMention.Name),
   165  		ChannelId:     channel.Id,
   166  		PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
   167  		UserId:        user.Id,
   168  		CreateAt:      0,
   169  	}
   170  
   171  	result, err := th.App.CreatePostAsUser(post)
   172  	require.Nil(t, err)
   173  	assert.Equal(t, map[string]interface{}{
   174  		"mention-test": map[string]interface{}{
   175  			"display_name": "Mention Test",
   176  		},
   177  	}, result.Props["channel_mentions"])
   178  
   179  	post.Message = fmt.Sprintf("goodbye, ~%v!", channelToMention.Name)
   180  	result, err = th.App.UpdatePost(post, false)
   181  	require.Nil(t, err)
   182  	assert.Equal(t, map[string]interface{}{
   183  		"mention-test": map[string]interface{}{
   184  			"display_name": "Mention Test",
   185  		},
   186  	}, result.Props["channel_mentions"])
   187  }
   188  
   189  func TestImageProxy(t *testing.T) {
   190  	th := Setup().InitBasic()
   191  	defer th.TearDown()
   192  
   193  	for name, tc := range map[string]struct {
   194  		ProxyType       string
   195  		ProxyURL        string
   196  		ProxyOptions    string
   197  		ImageURL        string
   198  		ProxiedImageURL string
   199  	}{
   200  		"atmos/camo": {
   201  			ProxyType:       "atmos/camo",
   202  			ProxyURL:        "https://127.0.0.1",
   203  			ProxyOptions:    "foo",
   204  			ImageURL:        "http://mydomain.com/myimage",
   205  			ProxiedImageURL: "https://127.0.0.1/f8dace906d23689e8d5b12c3cefbedbf7b9b72f5/687474703a2f2f6d79646f6d61696e2e636f6d2f6d79696d616765",
   206  		},
   207  		"willnorris/imageproxy": {
   208  			ProxyType:       "willnorris/imageproxy",
   209  			ProxyURL:        "https://127.0.0.1",
   210  			ProxyOptions:    "x1000",
   211  			ImageURL:        "http://mydomain.com/myimage",
   212  			ProxiedImageURL: "https://127.0.0.1/x1000/http://mydomain.com/myimage",
   213  		},
   214  		"willnorris/imageproxy_WithSigning": {
   215  			ProxyType:       "willnorris/imageproxy",
   216  			ProxyURL:        "https://127.0.0.1",
   217  			ProxyOptions:    "x1000|foo",
   218  			ImageURL:        "http://mydomain.com/myimage",
   219  			ProxiedImageURL: "https://127.0.0.1/x1000,sbhHVoG5d60UvnNtGh6Iy6x4PaMmnsh8JfZ7JfErKjGU=/http://mydomain.com/myimage",
   220  		},
   221  	} {
   222  		t.Run(name, func(t *testing.T) {
   223  			th.App.UpdateConfig(func(cfg *model.Config) {
   224  				cfg.ServiceSettings.ImageProxyType = model.NewString(tc.ProxyType)
   225  				cfg.ServiceSettings.ImageProxyOptions = model.NewString(tc.ProxyOptions)
   226  				cfg.ServiceSettings.ImageProxyURL = model.NewString(tc.ProxyURL)
   227  			})
   228  
   229  			post := &model.Post{
   230  				Id:      model.NewId(),
   231  				Message: "![foo](" + tc.ImageURL + ")",
   232  			}
   233  
   234  			list := model.NewPostList()
   235  			list.Posts[post.Id] = post
   236  
   237  			assert.Equal(t, "![foo]("+tc.ProxiedImageURL+")", th.App.PostListWithProxyAddedToImageURLs(list).Posts[post.Id].Message)
   238  			assert.Equal(t, "![foo]("+tc.ProxiedImageURL+")", th.App.PostWithProxyAddedToImageURLs(post).Message)
   239  
   240  			assert.Equal(t, "![foo]("+tc.ImageURL+")", th.App.PostWithProxyRemovedFromImageURLs(post).Message)
   241  			post.Message = "![foo](" + tc.ProxiedImageURL + ")"
   242  			assert.Equal(t, "![foo]("+tc.ImageURL+")", th.App.PostWithProxyRemovedFromImageURLs(post).Message)
   243  		})
   244  	}
   245  }
   246  
   247  var imageProxyBenchmarkSink *model.Post
   248  
   249  func BenchmarkPostWithProxyRemovedFromImageURLs(b *testing.B) {
   250  	th := Setup().InitBasic()
   251  	defer th.TearDown()
   252  
   253  	th.App.UpdateConfig(func(cfg *model.Config) {
   254  		cfg.ServiceSettings.ImageProxyType = model.NewString("willnorris/imageproxy")
   255  		cfg.ServiceSettings.ImageProxyOptions = model.NewString("x1000|foo")
   256  		cfg.ServiceSettings.ImageProxyURL = model.NewString("https://127.0.0.1")
   257  	})
   258  
   259  	post := &model.Post{
   260  		Message: "![foo](http://mydomain.com/myimage)",
   261  	}
   262  
   263  	b.ResetTimer()
   264  
   265  	for i := 0; i < b.N; i++ {
   266  		imageProxyBenchmarkSink = th.App.PostWithProxyAddedToImageURLs(post)
   267  	}
   268  }