github.com/altipla-consulting/ravendb-go-client@v0.1.3/tests/attachments_revisions_test.go (about) 1 package tests 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "runtime" 7 "sort" 8 "strings" 9 "testing" 10 11 "github.com/altipla-consulting/ravendb-go-client" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func attachmentsRevisionsPutAttachments(t *testing.T, driver *RavenTestDriver) { 16 var err error 17 store := driver.getDocumentStoreMust(t) 18 defer store.Close() 19 20 { 21 _, err = setupRevisions(store, false, 4) 22 assert.NoError(t, err) 23 24 names := createDocumentWithAttachments(t, store) 25 { 26 f := func(t *testing.T, session *ravendb.DocumentSession, revisions []*User) { 27 assertRevisionAttachments(t, names, 3, revisions[0], session) 28 assertRevisionAttachments(t, names, 2, revisions[1], session) 29 assertRevisionAttachments(t, names, 1, revisions[2], session) 30 assertNoRevisionAttachment(t, revisions[3], session, false) 31 } 32 assertRevisions(t, store, names, f, 9) 33 } 34 { 35 // Delete document should delete all the attachments 36 f := func(t *testing.T, session *ravendb.DocumentSession, revisions []*User) { 37 assertNoRevisionAttachment(t, revisions[0], session, true) 38 assertRevisionAttachments(t, names, 3, revisions[1], session) 39 assertRevisionAttachments(t, names, 2, revisions[2], session) 40 assertRevisionAttachments(t, names, 1, revisions[3], session) 41 } 42 43 cmd := ravendb.NewDeleteDocumentCommand("users/1", nil) 44 err = store.GetRequestExecutor("").ExecuteCommand(cmd, nil) 45 assert.NoError(t, err) 46 assertRevisions2(t, store, names, f, 6, 0, 3) 47 } 48 49 { 50 // Create another revision which should delete old revision 51 session := openSessionMust(t, store) 52 // This will delete the revision #1 which is without attachment 53 user := &User{} 54 user.setName("Fitzchak 2") 55 err = session.StoreWithID(user, "users/1") 56 assert.NoError(t, err) 57 err = session.SaveChanges() 58 assert.NoError(t, err) 59 session.Close() 60 } 61 62 { 63 f := func(t *testing.T, session *ravendb.DocumentSession, revisions []*User) { 64 // This will delete the revision #2 which is with attachment 65 assertNoRevisionAttachment(t, revisions[0], session, false) 66 assertNoRevisionAttachment(t, revisions[1], session, true) 67 assertRevisionAttachments(t, names, 3, revisions[2], session) 68 assertRevisionAttachments(t, names, 2, revisions[3], session) 69 } 70 assertRevisions2(t, store, names, f, 5, 1, 3) 71 } 72 73 { 74 session := openSessionMust(t, store) 75 // This will delete the revision #2 which is with attachment 76 user := &User{} 77 user.setName("Fitzchak 3") 78 err = session.StoreWithID(user, "users/1") 79 assert.NoError(t, err) 80 err = session.SaveChanges() 81 assert.NoError(t, err) 82 session.Close() 83 } 84 85 { 86 f := func(t *testing.T, session *ravendb.DocumentSession, revisions []*User) { 87 // This will delete the revision #2 which is with attachment 88 assertNoRevisionAttachment(t, revisions[0], session, false) 89 assertNoRevisionAttachment(t, revisions[1], session, false) 90 assertNoRevisionAttachment(t, revisions[2], session, true) 91 assertRevisionAttachments(t, names, 3, revisions[3], session) 92 } 93 assertRevisions2(t, store, names, f, 3, 1, 3) 94 } 95 96 { 97 session := openSessionMust(t, store) 98 // This will delete the revision #3 which is with attachment 99 user := &User{} 100 user.setName("Fitzchak 4") 101 err = session.StoreWithID(user, "users/1") 102 assert.NoError(t, err) 103 err = session.SaveChanges() 104 assert.NoError(t, err) 105 session.Close() 106 } 107 108 { 109 f := func(t *testing.T, session *ravendb.DocumentSession, revisions []*User) { 110 // This will delete the revision #2 which is with attachment 111 assertNoRevisionAttachment(t, revisions[0], session, false) 112 assertNoRevisionAttachment(t, revisions[1], session, false) 113 assertNoRevisionAttachment(t, revisions[2], session, false) 114 assertNoRevisionAttachment(t, revisions[3], session, true) 115 } 116 assertRevisions2(t, store, names, f, 0, 1, 0) 117 } 118 119 { 120 session := openSessionMust(t, store) 121 // This will delete the revision #4 which is with attachment 122 user := &User{} 123 user.setName("Fitzchak 5") 124 err = session.StoreWithID(user, "users/1") 125 assert.NoError(t, err) 126 err = session.SaveChanges() 127 assert.NoError(t, err) 128 session.Close() 129 } 130 131 { 132 f := func(t *testing.T, session *ravendb.DocumentSession, revisions []*User) { 133 // This will delete the revision #2 which is with attachment 134 assertNoRevisionAttachment(t, revisions[0], session, false) 135 assertNoRevisionAttachment(t, revisions[1], session, false) 136 assertNoRevisionAttachment(t, revisions[2], session, false) 137 assertNoRevisionAttachment(t, revisions[3], session, false) 138 } 139 assertRevisions2(t, store, names, f, 0, 1, 0) 140 } 141 } 142 } 143 144 func attachmentsRevisionsAttachmentRevision(t *testing.T, driver *RavenTestDriver) { 145 var err error 146 store := driver.getDocumentStoreMust(t) 147 defer store.Close() 148 149 { 150 _, err = setupRevisions(store, false, 4) 151 assert.NoError(t, err) 152 153 createDocumentWithAttachments(t, store) 154 155 { 156 session := openSessionMust(t, store) 157 bais := bytes.NewBuffer([]byte{5, 4, 3, 2, 1}) 158 err = session.Advanced().Attachments().StoreByID("users/1", "profile.png", bais, "") 159 assert.NoError(t, err) 160 161 err = session.SaveChanges() 162 assert.NoError(t, err) 163 session.Close() 164 } 165 166 { 167 session := openSessionMust(t, store) 168 var revisions []*User 169 err = session.Advanced().Revisions().GetFor(&revisions, "users/1") 170 assert.NoError(t, err) 171 172 rev := revisions[1] 173 changeVector, err := session.Advanced().GetChangeVectorFor(rev) 174 assert.NoError(t, err) 175 176 { 177 revision, err := session.Advanced().Attachments().GetRevision("users/1", "profile.png", changeVector) 178 assert.NoError(t, err) 179 r := revision.Data 180 bytes, err := ioutil.ReadAll(r) 181 assert.NoError(t, err) 182 assert.Equal(t, len(bytes), 3) 183 assert.Equal(t, bytes, []byte{1, 2, 3}) 184 } 185 186 session.Close() 187 } 188 } 189 } 190 191 func createDocumentWithAttachments(t *testing.T, store *ravendb.DocumentStore) []string { 192 var err error 193 { 194 session := openSessionMust(t, store) 195 196 user := &User{} 197 user.setName("Fitzchak") 198 err = session.StoreWithID(user, "users/1") 199 assert.NoError(t, err) 200 201 err = session.SaveChanges() 202 assert.NoError(t, err) 203 204 session.Close() 205 } 206 207 names := []string{ 208 "profile.png", 209 "background-photo.jpg", 210 "fileNAME_#$1^%_בעברית.txt", 211 } 212 213 { 214 profileStream := bytes.NewBuffer([]byte{1, 2, 3}) 215 op := ravendb.NewPutAttachmentOperation("users/1", names[0], profileStream, "image/png", nil) 216 err = store.Operations().Send(op, nil) 217 218 assert.NoError(t, err) 219 220 result := op.Command.Result 221 s := *result.ChangeVector 222 assert.True(t, strings.Contains(s, "A:3")) 223 assert.Equal(t, result.Name, names[0]) 224 assert.Equal(t, result.DocumentID, "users/1") 225 assert.Equal(t, result.ContentType, "image/png") 226 } 227 228 { 229 backgroundStream := bytes.NewReader([]byte{10, 20, 30, 40, 50}) 230 op := ravendb.NewPutAttachmentOperation("users/1", names[1], backgroundStream, "ImGgE/jPeG", nil) 231 err = store.Operations().Send(op, nil) 232 assert.NoError(t, err) 233 result := op.Command.Result 234 s := *result.ChangeVector 235 assert.True(t, strings.Contains(s, "A:7")) 236 assert.Equal(t, result.Name, names[1]) 237 assert.Equal(t, result.DocumentID, "users/1") 238 assert.Equal(t, result.ContentType, "ImGgE/jPeG") 239 } 240 { 241 fileStream := bytes.NewReader([]byte{1, 2, 3, 4, 5}) 242 op := ravendb.NewPutAttachmentOperation("users/1", names[2], fileStream, "", nil) 243 err = store.Operations().Send(op, nil) 244 assert.NoError(t, err) 245 result := op.Command.Result 246 s := *result.ChangeVector 247 assert.True(t, strings.Contains(s, "A:12")) 248 assert.Equal(t, result.Name, names[2]) 249 assert.Equal(t, result.DocumentID, "users/1") 250 assert.Equal(t, result.ContentType, "") 251 } 252 return names 253 } 254 255 func assertRevisions(t *testing.T, store *ravendb.DocumentStore, names []string, assertAction func(*testing.T, *ravendb.DocumentSession, []*User), expectedCountOfAttachments int64) { 256 assertRevisions2(t, store, names, assertAction, expectedCountOfAttachments, 1, 3) 257 } 258 259 func assertRevisions2(t *testing.T, store *ravendb.DocumentStore, names []string, assertAction func(*testing.T, *ravendb.DocumentSession, []*User), expectedCountOfAttachments int64, expectedCountOfDocuments int64, expectedCountOfUniqueAttachments int64) { 260 op := ravendb.NewGetStatisticsOperation("") 261 err := store.Maintenance().Send(op) 262 assert.NoError(t, err) 263 statistics := op.Command.Result 264 265 assert.Equal(t, statistics.CountOfAttachments, expectedCountOfAttachments) 266 267 assert.Equal(t, statistics.CountOfUniqueAttachments, expectedCountOfUniqueAttachments) 268 269 assert.Equal(t, statistics.CountOfRevisionDocuments, int64(4)) 270 271 assert.Equal(t, statistics.CountOfDocuments, expectedCountOfDocuments) 272 273 assert.Equal(t, statistics.CountOfIndexes, 0) 274 275 { 276 session := openSessionMust(t, store) 277 var revisions []*User 278 err = session.Advanced().Revisions().GetFor(&revisions, "users/1") 279 assert.NoError(t, err) 280 assertAction(t, session, revisions) 281 282 session.Close() 283 } 284 } 285 286 func assertNoRevisionAttachment(t *testing.T, revision *User, session *ravendb.DocumentSession, isDeleteRevision bool) { 287 metadata, err := session.Advanced().GetMetadataFor(revision) 288 assert.NoError(t, err) 289 290 if isDeleteRevision { 291 v, _ := metadata.Get(ravendb.MetadataFlags) 292 s := v.(string) 293 assert.True(t, strings.Contains(s, "HasRevisions")) 294 assert.True(t, strings.Contains(s, "DeleteRevision")) 295 } else { 296 v, _ := metadata.Get(ravendb.MetadataFlags) 297 s := v.(string) 298 assert.True(t, strings.Contains(s, "HasRevisions")) 299 assert.True(t, strings.Contains(s, "Revision")) 300 } 301 302 hasIt := metadata.ContainsKey(ravendb.MetadataAttachments) 303 assert.False(t, hasIt) 304 } 305 306 func assertRevisionAttachments(t *testing.T, names []string, expectedCount int, revision *User, session *ravendb.DocumentSession) { 307 metadata, err := session.Advanced().GetMetadataFor(revision) 308 assert.NoError(t, err) 309 v, _ := metadata.Get(ravendb.MetadataFlags) 310 s := v.(string) 311 assert.True(t, strings.Contains(s, "HasRevisions")) 312 assert.True(t, strings.Contains(s, "Revision")) 313 assert.True(t, strings.Contains(s, "Revision")) 314 315 attachments := metadata.GetObjects(ravendb.MetadataAttachments) 316 assert.Equal(t, len(attachments), expectedCount) 317 318 // Note: unlike Java, compare them after sorting 319 attachmentNames := make([]string, expectedCount, expectedCount) 320 for i := 0; i < expectedCount; i++ { 321 attachment := attachments[i] 322 aname, ok := attachment.Get("Name") 323 assert.True(t, ok) 324 anameStr, ok := aname.(string) 325 assert.True(t, ok) 326 attachmentNames[i] = anameStr 327 } 328 329 orderedNames := append([]string{}, names...) 330 if len(orderedNames) > expectedCount { 331 orderedNames = orderedNames[:expectedCount] 332 } 333 sort.Strings(orderedNames) 334 sort.Strings(attachmentNames) 335 assert.Equal(t, orderedNames, attachmentNames) 336 } 337 338 func TestAttachmentsRevisions(t *testing.T) { 339 driver := createTestDriver(t) 340 destroy := func() { destroyDriver(t, driver) } 341 defer recoverTest(t, destroy) 342 343 // Those are flaky on mac and mac only. I suspect server issue 344 // see https://github.com/altipla-consulting/ravendb-go-client/issues/92 345 if runtime.GOOS == "darwin" && !enableFlakyTests { 346 return 347 } 348 349 // matches order of Java tests 350 attachmentsRevisionsPutAttachments(t, driver) 351 attachmentsRevisionsAttachmentRevision(t, driver) 352 }