github.com/cjdelisle/matterfoss@v5.11.1+incompatible/model/post_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package model
     5  
     6  import (
     7  	"io/ioutil"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  func TestPostToJson(t *testing.T) {
    15  	o := Post{Id: NewId(), Message: NewId()}
    16  	j := o.ToJson()
    17  	ro := PostFromJson(strings.NewReader(j))
    18  
    19  	assert.NotNil(t, ro)
    20  	assert.Equal(t, o, *ro)
    21  }
    22  
    23  func TestPostFromJsonError(t *testing.T) {
    24  	ro := PostFromJson(strings.NewReader(""))
    25  	assert.Nil(t, ro)
    26  }
    27  
    28  func TestPostIsValid(t *testing.T) {
    29  	o := Post{}
    30  	maxPostSize := 10000
    31  
    32  	if err := o.IsValid(maxPostSize); err == nil {
    33  		t.Fatal("should be invalid")
    34  	}
    35  
    36  	o.Id = NewId()
    37  	if err := o.IsValid(maxPostSize); err == nil {
    38  		t.Fatal("should be invalid")
    39  	}
    40  
    41  	o.CreateAt = GetMillis()
    42  	if err := o.IsValid(maxPostSize); err == nil {
    43  		t.Fatal("should be invalid")
    44  	}
    45  
    46  	o.UpdateAt = GetMillis()
    47  	if err := o.IsValid(maxPostSize); err == nil {
    48  		t.Fatal("should be invalid")
    49  	}
    50  
    51  	o.UserId = NewId()
    52  	if err := o.IsValid(maxPostSize); err == nil {
    53  		t.Fatal("should be invalid")
    54  	}
    55  
    56  	o.ChannelId = NewId()
    57  	o.RootId = "123"
    58  	if err := o.IsValid(maxPostSize); err == nil {
    59  		t.Fatal("should be invalid")
    60  	}
    61  
    62  	o.RootId = ""
    63  	o.ParentId = "123"
    64  	if err := o.IsValid(maxPostSize); err == nil {
    65  		t.Fatal("should be invalid")
    66  	}
    67  
    68  	o.ParentId = NewId()
    69  	o.RootId = ""
    70  	if err := o.IsValid(maxPostSize); err == nil {
    71  		t.Fatal("should be invalid")
    72  	}
    73  
    74  	o.ParentId = ""
    75  	o.Message = strings.Repeat("0", maxPostSize+1)
    76  	if err := o.IsValid(maxPostSize); err == nil {
    77  		t.Fatal("should be invalid")
    78  	}
    79  
    80  	o.Message = strings.Repeat("0", maxPostSize)
    81  	if err := o.IsValid(maxPostSize); err != nil {
    82  		t.Fatal(err)
    83  	}
    84  
    85  	o.Message = "test"
    86  	if err := o.IsValid(maxPostSize); err != nil {
    87  		t.Fatal(err)
    88  	}
    89  
    90  	o.Type = "junk"
    91  	if err := o.IsValid(maxPostSize); err == nil {
    92  		t.Fatal("should be invalid")
    93  	}
    94  
    95  	o.Type = POST_CUSTOM_TYPE_PREFIX + "type"
    96  	if err := o.IsValid(maxPostSize); err != nil {
    97  		t.Fatal(err)
    98  	}
    99  }
   100  
   101  func TestPostPreSave(t *testing.T) {
   102  	o := Post{Message: "test"}
   103  	o.PreSave()
   104  
   105  	if o.CreateAt == 0 {
   106  		t.Fatal("should be set")
   107  	}
   108  
   109  	past := GetMillis() - 1
   110  	o = Post{Message: "test", CreateAt: past}
   111  	o.PreSave()
   112  
   113  	if o.CreateAt > past {
   114  		t.Fatal("should not be updated")
   115  	}
   116  
   117  	o.Etag()
   118  }
   119  
   120  func TestPostIsSystemMessage(t *testing.T) {
   121  	post1 := Post{Message: "test_1"}
   122  	post1.PreSave()
   123  
   124  	if post1.IsSystemMessage() {
   125  		t.Fatalf("TestPostIsSystemMessage failed, expected post1.IsSystemMessage() to be false")
   126  	}
   127  
   128  	post2 := Post{Message: "test_2", Type: POST_JOIN_LEAVE}
   129  	post2.PreSave()
   130  	if !post2.IsSystemMessage() {
   131  		t.Fatalf("TestPostIsSystemMessage failed, expected post2.IsSystemMessage() to be true")
   132  	}
   133  }
   134  
   135  func TestPostChannelMentions(t *testing.T) {
   136  	post := Post{Message: "~a ~b ~b ~c/~d."}
   137  	assert.Equal(t, []string{"a", "b", "c", "d"}, post.ChannelMentions())
   138  }
   139  
   140  func TestPostSanitizeProps(t *testing.T) {
   141  	post1 := &Post{
   142  		Message: "test",
   143  	}
   144  
   145  	post1.SanitizeProps()
   146  
   147  	if post1.Props[PROPS_ADD_CHANNEL_MEMBER] != nil {
   148  		t.Fatal("should be nil")
   149  	}
   150  
   151  	post2 := &Post{
   152  		Message: "test",
   153  		Props: StringInterface{
   154  			PROPS_ADD_CHANNEL_MEMBER: "test",
   155  		},
   156  	}
   157  
   158  	post2.SanitizeProps()
   159  
   160  	if post2.Props[PROPS_ADD_CHANNEL_MEMBER] != nil {
   161  		t.Fatal("should be nil")
   162  	}
   163  
   164  	post3 := &Post{
   165  		Message: "test",
   166  		Props: StringInterface{
   167  			PROPS_ADD_CHANNEL_MEMBER: "no good",
   168  			"attachments":            "good",
   169  		},
   170  	}
   171  
   172  	post3.SanitizeProps()
   173  
   174  	if post3.Props[PROPS_ADD_CHANNEL_MEMBER] != nil {
   175  		t.Fatal("should be nil")
   176  	}
   177  
   178  	if post3.Props["attachments"] == nil {
   179  		t.Fatal("should not be nil")
   180  	}
   181  }
   182  
   183  func TestPost_AttachmentsEqual(t *testing.T) {
   184  	post1 := &Post {
   185  	}
   186  	post2 := &Post {
   187  	}
   188  	for name, tc := range map[string]struct {
   189  		Attachments1 []*SlackAttachment
   190  		Attachments2 []*SlackAttachment
   191  		Expected bool
   192  	}{
   193  		"Empty": {
   194  			nil,
   195  			nil,
   196  			true,
   197  		},
   198  		"DifferentLength": {
   199  			[]*SlackAttachment{
   200  				{
   201  					Text: "Hello World",
   202  				},
   203  			},
   204  			nil,
   205  			false,
   206  		},
   207  		"EqualText": {
   208  			[]*SlackAttachment{
   209  				{
   210  					Text: "Hello World",
   211  				},
   212  			},
   213  			[]*SlackAttachment{
   214  				{
   215  					Text: "Hello World",
   216  				},
   217  			},
   218  			true,
   219  		},
   220  		"DifferentText": {
   221  			[]*SlackAttachment{
   222  				{
   223  					Text: "Hello World",
   224  				},
   225  			},
   226  			[]*SlackAttachment{
   227  				{
   228  					Text: "Hello World 2",
   229  				},
   230  			},
   231  			false,
   232  		},
   233  		"DifferentColor": {
   234  			[]*SlackAttachment{
   235  				{
   236  					Text: "Hello World",
   237  					Color: "#152313",
   238  				},
   239  			},
   240  			[]*SlackAttachment{
   241  				{
   242  					Text: "Hello World 2",
   243  				},
   244  			},
   245  			false,
   246  		},
   247  		"EqualFields": {
   248  			[]*SlackAttachment{
   249  				{
   250  					Fields: []*SlackAttachmentField {
   251  						{
   252  							Title: "Hello World",
   253  							Value: "FooBar",
   254  						},
   255  						{
   256  							Title: "Hello World2",
   257  							Value: "FooBar2",
   258  						},
   259  					},
   260  				},
   261  			},
   262  			[]*SlackAttachment{
   263  				{
   264  					Fields: []*SlackAttachmentField {
   265  						{
   266  							Title: "Hello World",
   267  							Value: "FooBar",
   268  						},
   269  						{
   270  							Title: "Hello World2",
   271  							Value: "FooBar2",
   272  						},
   273  					},
   274  				},
   275  			},
   276  			true,
   277  		},
   278  		"DifferentFields": {
   279  			[]*SlackAttachment{
   280  				{
   281  					Fields: []*SlackAttachmentField {
   282  						{
   283  							Title: "Hello World",
   284  							Value: "FooBar",
   285  						},
   286  					},
   287  				},
   288  			},
   289  			[]*SlackAttachment{
   290  				{
   291  					Fields: []*SlackAttachmentField {
   292  						{
   293  							Title: "Hello World",
   294  							Value: "FooBar",
   295  							Short: false,
   296  						},
   297  						{
   298  							Title: "Hello World2",
   299  							Value: "FooBar2",
   300  							Short: true,
   301  						},
   302  					},
   303  				},
   304  			},
   305  			false,
   306  		},
   307  		"EqualActions": {
   308  			[]*SlackAttachment{
   309  				{
   310  					Actions: []*PostAction{
   311  						{
   312  							Name: "FooBar",
   313  							Options: []*PostActionOptions {
   314  								{
   315  									Text: "abcdef",
   316  									Value: "abcdef",
   317  								},
   318  							},
   319  							Integration: &PostActionIntegration{
   320  								URL: "http://localhost",
   321  								Context: map[string]interface{}{
   322  									"context": "foobar",
   323  									"test": 123,
   324  								},
   325  							},
   326  						},
   327  					},
   328  				},
   329  			},
   330  			[]*SlackAttachment{
   331  				{
   332  					Actions: []*PostAction{
   333  						{
   334  							Name: "FooBar",
   335  							Options: []*PostActionOptions {
   336  								{
   337  									Text: "abcdef",
   338  									Value: "abcdef",
   339  								},
   340  							},
   341  							Integration: &PostActionIntegration{
   342  								URL: "http://localhost",
   343  								Context: map[string]interface{}{
   344  									"context": "foobar",
   345  									"test": 123,
   346  								},
   347  							},
   348  						},
   349  					},
   350  				},
   351  			},
   352  			true,
   353  		},
   354  		"DifferentActions": {
   355  			[]*SlackAttachment{
   356  				{
   357  					Actions: []*PostAction{
   358  						{
   359  							Name: "FooBar",
   360  							Options: []*PostActionOptions {
   361  								{
   362  									Text: "abcdef",
   363  									Value: "abcdef",
   364  								},
   365  							},
   366  							Integration: &PostActionIntegration{
   367  								URL: "http://localhost",
   368  								Context: map[string]interface{}{
   369  									"context": "foobar",
   370  									"test": "mattermost",
   371  								},
   372  							},
   373  						},
   374  					},
   375  				},
   376  			},
   377  			[]*SlackAttachment{
   378  				{
   379  					Actions: []*PostAction{
   380  						{
   381  							Name: "FooBar",
   382  							Options: []*PostActionOptions {
   383  								{
   384  									Text: "abcdef",
   385  									Value: "abcdef",
   386  								},
   387  							},
   388  							Integration: &PostActionIntegration{
   389  								URL: "http://localhost",
   390  								Context: map[string]interface{}{
   391  									"context": "foobar",
   392  									"test": 123,
   393  								},
   394  							},
   395  						},
   396  					},
   397  				},
   398  			},
   399  			false,
   400  		},
   401  	} {
   402  		t.Run(name, func(t *testing.T) {
   403  			post1.AddProp("attachments", tc.Attachments1)
   404  			post2.AddProp("attachments", tc.Attachments2)
   405  			assert.Equal(t, tc.Expected, post1.AttachmentsEqual(post2))
   406  		})
   407  	}
   408  }
   409  
   410  var markdownSample, markdownSampleWithRewrittenImageURLs string
   411  
   412  func init() {
   413  	bytes, err := ioutil.ReadFile("testdata/markdown-sample.md")
   414  	if err != nil {
   415  		panic(err)
   416  	}
   417  	markdownSample = string(bytes)
   418  
   419  	bytes, err = ioutil.ReadFile("testdata/markdown-sample-with-rewritten-image-urls.md")
   420  	if err != nil {
   421  		panic(err)
   422  	}
   423  	markdownSampleWithRewrittenImageURLs = string(bytes)
   424  }
   425  
   426  func TestRewriteImageURLs(t *testing.T) {
   427  	for name, tc := range map[string]struct {
   428  		Markdown string
   429  		Expected string
   430  	}{
   431  		"Empty": {
   432  			Markdown: ``,
   433  			Expected: ``,
   434  		},
   435  		"NoImages": {
   436  			Markdown: `foo`,
   437  			Expected: `foo`,
   438  		},
   439  		"Link": {
   440  			Markdown: `[foo](/url)`,
   441  			Expected: `[foo](/url)`,
   442  		},
   443  		"Image": {
   444  			Markdown: `![foo](/url)`,
   445  			Expected: `![foo](rewritten:/url)`,
   446  		},
   447  		"SpacedURL": {
   448  			Markdown: `![foo]( /url )`,
   449  			Expected: `![foo]( rewritten:/url )`,
   450  		},
   451  		"Title": {
   452  			Markdown: `![foo](/url "title")`,
   453  			Expected: `![foo](rewritten:/url "title")`,
   454  		},
   455  		"Parentheses": {
   456  			Markdown: `![foo](/url(1) "title")`,
   457  			Expected: `![foo](rewritten:/url\(1\) "title")`,
   458  		},
   459  		"AngleBrackets": {
   460  			Markdown: `![foo](</url\<1\>\\> "title")`,
   461  			Expected: `![foo](<rewritten:/url\<1\>\\> "title")`,
   462  		},
   463  		"MultipleLines": {
   464  			Markdown: `![foo](
   465  				</url\<1\>\\>
   466  				"title"
   467  			)`,
   468  			Expected: `![foo](
   469  				<rewritten:/url\<1\>\\>
   470  				"title"
   471  			)`,
   472  		},
   473  		"ReferenceLink": {
   474  			Markdown: `[foo]: </url\<1\>\\> "title"
   475  		 		[foo]`,
   476  			Expected: `[foo]: </url\<1\>\\> "title"
   477  		 		[foo]`,
   478  		},
   479  		"ReferenceImage": {
   480  			Markdown: `[foo]: </url\<1\>\\> "title"
   481  		 		![foo]`,
   482  			Expected: `[foo]: <rewritten:/url\<1\>\\> "title"
   483  		 		![foo]`,
   484  		},
   485  		"MultipleReferenceImages": {
   486  			Markdown: `[foo]: </url1> "title"
   487  				[bar]: </url2>
   488  				[baz]: /url3 "title"
   489  				[qux]: /url4
   490  				![foo]![qux]`,
   491  			Expected: `[foo]: <rewritten:/url1> "title"
   492  				[bar]: </url2>
   493  				[baz]: /url3 "title"
   494  				[qux]: rewritten:/url4
   495  				![foo]![qux]`,
   496  		},
   497  		"DuplicateReferences": {
   498  			Markdown: `[foo]: </url1> "title"
   499  				[foo]: </url2>
   500  				[foo]: /url3 "title"
   501  				[foo]: /url4
   502  				![foo]![foo]![foo]`,
   503  			Expected: `[foo]: <rewritten:/url1> "title"
   504  				[foo]: </url2>
   505  				[foo]: /url3 "title"
   506  				[foo]: /url4
   507  				![foo]![foo]![foo]`,
   508  		},
   509  		"TrailingURL": {
   510  			Markdown: "![foo]\n\n[foo]: /url",
   511  			Expected: "![foo]\n\n[foo]: rewritten:/url",
   512  		},
   513  		"Sample": {
   514  			Markdown: markdownSample,
   515  			Expected: markdownSampleWithRewrittenImageURLs,
   516  		},
   517  	} {
   518  		t.Run(name, func(t *testing.T) {
   519  			assert.Equal(t, tc.Expected, RewriteImageURLs(tc.Markdown, func(url string) string {
   520  				return "rewritten:" + url
   521  			}))
   522  		})
   523  	}
   524  }
   525  
   526  var rewriteImageURLsSink string
   527  
   528  func BenchmarkRewriteImageURLs(b *testing.B) {
   529  	for i := 0; i < b.N; i++ {
   530  		rewriteImageURLsSink = RewriteImageURLs(markdownSample, func(url string) string {
   531  			return "rewritten:" + url
   532  		})
   533  	}
   534  }