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