github.com/haalcala/mattermost-server-change-repo/v5@v5.33.2/store/storetest/link_metadata_store.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package storetest
     5  
     6  import (
     7  	"errors"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/dyatlov/go-opengraph/opengraph"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"github.com/mattermost/mattermost-server/v5/model"
    16  	"github.com/mattermost/mattermost-server/v5/store"
    17  )
    18  
    19  // These tests are ran on the same store instance, so this provides easier unique, valid timestamps
    20  var linkMetadataTimestamp int64 = 1546300800000
    21  
    22  func getNextLinkMetadataTimestamp() int64 {
    23  	linkMetadataTimestamp += int64(time.Hour) / (1000 * 1000)
    24  	return linkMetadataTimestamp
    25  }
    26  
    27  func TestLinkMetadataStore(t *testing.T, ss store.Store) {
    28  	t.Run("Save", func(t *testing.T) { testLinkMetadataStoreSave(t, ss) })
    29  	t.Run("Get", func(t *testing.T) { testLinkMetadataStoreGet(t, ss) })
    30  	t.Run("Types", func(t *testing.T) { testLinkMetadataStoreTypes(t, ss) })
    31  }
    32  
    33  func testLinkMetadataStoreSave(t *testing.T, ss store.Store) {
    34  	t.Run("should save item", func(t *testing.T) {
    35  		metadata := &model.LinkMetadata{
    36  			URL:       "http://example.com",
    37  			Timestamp: getNextLinkMetadataTimestamp(),
    38  			Type:      model.LINK_METADATA_TYPE_IMAGE,
    39  			Data:      &model.PostImage{},
    40  		}
    41  
    42  		linkMetadata, err := ss.LinkMetadata().Save(metadata)
    43  
    44  		require.NoError(t, err)
    45  		assert.Equal(t, *metadata, *linkMetadata)
    46  	})
    47  
    48  	t.Run("should fail to save invalid item", func(t *testing.T) {
    49  		metadata := &model.LinkMetadata{
    50  			URL:       "",
    51  			Timestamp: 0,
    52  			Type:      "garbage",
    53  			Data:      nil,
    54  		}
    55  
    56  		_, err := ss.LinkMetadata().Save(metadata)
    57  
    58  		assert.Error(t, err)
    59  	})
    60  
    61  	t.Run("should save with duplicate URL and different timestamp", func(t *testing.T) {
    62  		metadata := &model.LinkMetadata{
    63  			URL:       "http://example.com",
    64  			Timestamp: getNextLinkMetadataTimestamp(),
    65  			Type:      model.LINK_METADATA_TYPE_IMAGE,
    66  			Data:      &model.PostImage{},
    67  		}
    68  
    69  		_, err := ss.LinkMetadata().Save(metadata)
    70  		require.NoError(t, err)
    71  
    72  		metadata.Timestamp = getNextLinkMetadataTimestamp()
    73  
    74  		linkMetadata, err := ss.LinkMetadata().Save(metadata)
    75  
    76  		require.NoError(t, err)
    77  		assert.Equal(t, *metadata, *linkMetadata)
    78  	})
    79  
    80  	t.Run("should save with duplicate timestamp and different URL", func(t *testing.T) {
    81  		metadata := &model.LinkMetadata{
    82  			URL:       "http://example.com",
    83  			Timestamp: getNextLinkMetadataTimestamp(),
    84  			Type:      model.LINK_METADATA_TYPE_IMAGE,
    85  			Data:      &model.PostImage{},
    86  		}
    87  
    88  		_, err := ss.LinkMetadata().Save(metadata)
    89  		require.NoError(t, err)
    90  
    91  		metadata.URL = "http://example.com/another/page"
    92  
    93  		linkMetadata, err := ss.LinkMetadata().Save(metadata)
    94  
    95  		require.NoError(t, err)
    96  		assert.Equal(t, *metadata, *linkMetadata)
    97  	})
    98  
    99  	t.Run("should not save with duplicate URL and timestamp, but should not return an error", func(t *testing.T) {
   100  		metadata := &model.LinkMetadata{
   101  			URL:       "http://example.com",
   102  			Timestamp: getNextLinkMetadataTimestamp(),
   103  			Type:      model.LINK_METADATA_TYPE_IMAGE,
   104  			Data:      &model.PostImage{},
   105  		}
   106  
   107  		linkMetadata, err := ss.LinkMetadata().Save(metadata)
   108  		require.NoError(t, err)
   109  		assert.Equal(t, &model.PostImage{}, linkMetadata.Data)
   110  
   111  		metadata.Data = &model.PostImage{Height: 10, Width: 20}
   112  
   113  		linkMetadata, err = ss.LinkMetadata().Save(metadata)
   114  		require.NoError(t, err)
   115  		assert.Equal(t, linkMetadata.Data, &model.PostImage{Height: 10, Width: 20})
   116  
   117  		// Should return the original result, not the duplicate one
   118  		linkMetadata, err = ss.LinkMetadata().Get(metadata.URL, metadata.Timestamp)
   119  		require.NoError(t, err)
   120  		assert.Equal(t, &model.PostImage{}, linkMetadata.Data)
   121  	})
   122  }
   123  
   124  func testLinkMetadataStoreGet(t *testing.T, ss store.Store) {
   125  	t.Run("should get value", func(t *testing.T) {
   126  		metadata := &model.LinkMetadata{
   127  			URL:       "http://example.com",
   128  			Timestamp: getNextLinkMetadataTimestamp(),
   129  			Type:      model.LINK_METADATA_TYPE_IMAGE,
   130  			Data:      &model.PostImage{},
   131  		}
   132  
   133  		_, err := ss.LinkMetadata().Save(metadata)
   134  		require.NoError(t, err)
   135  
   136  		linkMetadata, err := ss.LinkMetadata().Get(metadata.URL, metadata.Timestamp)
   137  
   138  		require.NoError(t, err)
   139  		require.IsType(t, metadata, linkMetadata)
   140  		assert.Equal(t, *metadata, *linkMetadata)
   141  	})
   142  
   143  	t.Run("should return not found with incorrect URL", func(t *testing.T) {
   144  		metadata := &model.LinkMetadata{
   145  			URL:       "http://example.com",
   146  			Timestamp: getNextLinkMetadataTimestamp(),
   147  			Type:      model.LINK_METADATA_TYPE_IMAGE,
   148  			Data:      &model.PostImage{},
   149  		}
   150  
   151  		_, err := ss.LinkMetadata().Save(metadata)
   152  		require.NoError(t, err)
   153  
   154  		_, err = ss.LinkMetadata().Get("http://example.com/another_page", metadata.Timestamp)
   155  
   156  		require.Error(t, err)
   157  		var nfErr *store.ErrNotFound
   158  		assert.True(t, errors.As(err, &nfErr))
   159  	})
   160  
   161  	t.Run("should return not found with incorrect timestamp", func(t *testing.T) {
   162  		metadata := &model.LinkMetadata{
   163  			URL:       "http://example.com",
   164  			Timestamp: getNextLinkMetadataTimestamp(),
   165  			Type:      model.LINK_METADATA_TYPE_IMAGE,
   166  			Data:      &model.PostImage{},
   167  		}
   168  
   169  		_, err := ss.LinkMetadata().Save(metadata)
   170  		require.NoError(t, err)
   171  
   172  		_, err = ss.LinkMetadata().Get(metadata.URL, getNextLinkMetadataTimestamp())
   173  
   174  		require.Error(t, err)
   175  		var nfErr *store.ErrNotFound
   176  		assert.True(t, errors.As(err, &nfErr))
   177  	})
   178  }
   179  
   180  func testLinkMetadataStoreTypes(t *testing.T, ss store.Store) {
   181  	t.Run("should save and get image metadata", func(t *testing.T) {
   182  		metadata := &model.LinkMetadata{
   183  			URL:       "http://example.com",
   184  			Timestamp: getNextLinkMetadataTimestamp(),
   185  			Type:      model.LINK_METADATA_TYPE_IMAGE,
   186  			Data: &model.PostImage{
   187  				Width:  123,
   188  				Height: 456,
   189  			},
   190  		}
   191  
   192  		received, err := ss.LinkMetadata().Save(metadata)
   193  		require.NoError(t, err)
   194  
   195  		require.IsType(t, &model.PostImage{}, received.Data)
   196  		assert.Equal(t, *(metadata.Data.(*model.PostImage)), *(received.Data.(*model.PostImage)))
   197  
   198  		received, err = ss.LinkMetadata().Get(metadata.URL, metadata.Timestamp)
   199  		require.NoError(t, err)
   200  
   201  		require.IsType(t, &model.PostImage{}, received.Data)
   202  		assert.Equal(t, *(metadata.Data.(*model.PostImage)), *(received.Data.(*model.PostImage)))
   203  	})
   204  
   205  	t.Run("should save and get opengraph data", func(t *testing.T) {
   206  		og := &opengraph.OpenGraph{
   207  			URL: "http://example.com",
   208  			Images: []*opengraph.Image{
   209  				{
   210  					URL: "http://example.com/image.png",
   211  				},
   212  			},
   213  		}
   214  
   215  		metadata := &model.LinkMetadata{
   216  			URL:       "http://example.com",
   217  			Timestamp: getNextLinkMetadataTimestamp(),
   218  			Type:      model.LINK_METADATA_TYPE_OPENGRAPH,
   219  			Data:      og,
   220  		}
   221  
   222  		received, err := ss.LinkMetadata().Save(metadata)
   223  		require.NoError(t, err)
   224  
   225  		require.IsType(t, &opengraph.OpenGraph{}, received.Data)
   226  		assert.Equal(t, *(metadata.Data.(*opengraph.OpenGraph)), *(received.Data.(*opengraph.OpenGraph)))
   227  
   228  		received, err = ss.LinkMetadata().Get(metadata.URL, metadata.Timestamp)
   229  		require.NoError(t, err)
   230  
   231  		require.IsType(t, &opengraph.OpenGraph{}, received.Data)
   232  		assert.Equal(t, *(metadata.Data.(*opengraph.OpenGraph)), *(received.Data.(*opengraph.OpenGraph)))
   233  	})
   234  
   235  	t.Run("should save and get nil", func(t *testing.T) {
   236  		metadata := &model.LinkMetadata{
   237  			URL:       "http://example.com",
   238  			Timestamp: getNextLinkMetadataTimestamp(),
   239  			Type:      model.LINK_METADATA_TYPE_NONE,
   240  			Data:      nil,
   241  		}
   242  
   243  		received, err := ss.LinkMetadata().Save(metadata)
   244  		require.NoError(t, err)
   245  		assert.Nil(t, received.Data)
   246  
   247  		received, err = ss.LinkMetadata().Get(metadata.URL, metadata.Timestamp)
   248  		require.NoError(t, err)
   249  
   250  		require.Nil(t, received.Data)
   251  	})
   252  }