eintopf.info@v0.13.16/service/event/testutil/store.go (about) 1 // Copyright (C) 2022 The Eintopf authors 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 package testutil 17 18 import ( 19 "context" 20 "reflect" 21 "testing" 22 23 "eintopf.info/internal/crud" 24 "eintopf.info/service/event" 25 ) 26 27 type newStore func() (event.Storer, func(), error) 28 29 // TestStore tests if a given event.Service acts as a event store. 30 func TestStore(t *testing.T, newStore newStore) { 31 ctx := context.Background() 32 t.Helper() 33 34 t.Run("Create", func(tt *testing.T) { 35 store, cleanup, err := newStore() 36 if err != nil { 37 tt.Fatalf("Failed to create a new store: %s", err) 38 } 39 defer cleanup() 40 41 event, err := store.Create(ctx, &event.NewEvent{Name: "event1"}) 42 if err != nil { 43 tt.Fatalf("expected store.Create to succeed. got %s", err.Error()) 44 } 45 if event == nil { 46 tt.Fatalf("expected event not to be nil") 47 } 48 }) 49 50 t.Run("CreateWithTags", func(tt *testing.T) { 51 store, cleanup, err := newStore() 52 if err != nil { 53 tt.Fatalf("Failed to create a new store: %s", err) 54 } 55 defer cleanup() 56 57 event, err := store.Create(ctx, &event.NewEvent{Name: "event1", Tags: []string{"foo", "bar"}}) 58 if err != nil { 59 tt.Fatalf("expected store.Create to succeed. got %s", err.Error()) 60 } 61 if event == nil { 62 tt.Fatalf("expected event not to be nil") 63 } 64 }) 65 66 t.Run("CreateWithOwnedBy", func(tt *testing.T) { 67 store, cleanup, err := newStore() 68 if err != nil { 69 tt.Fatalf("Failed to create a new store: %s", err) 70 } 71 defer cleanup() 72 73 event, err := store.Create(ctx, &event.NewEvent{Name: "event1", OwnedBy: []string{"foo", "bar"}}) 74 if err != nil { 75 tt.Fatalf("expected store.Create to succeed. got %s", err.Error()) 76 } 77 if event == nil { 78 tt.Fatalf("expected event not to be nil") 79 } 80 }) 81 82 t.Run("FindByIDNoMatch", func(tt *testing.T) { 83 store, cleanup, err := newStore() 84 if err != nil { 85 tt.Fatalf("Failed to create a new store: %s", err) 86 } 87 defer cleanup() 88 89 event, err := store.FindByID(ctx, "test") 90 if err != nil { 91 tt.Fatalf("expected store.FindByID to succeed. got %s", err.Error()) 92 } 93 if event != nil { 94 tt.Fatalf("expected to event to be nil. got %v", event) 95 } 96 }) 97 98 t.Run("FindByIDWithMatch", func(tt *testing.T) { 99 store, cleanup, err := newStore() 100 if err != nil { 101 tt.Fatalf("Failed to create a new store: %s", err) 102 } 103 defer cleanup() 104 105 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event1"}) 106 event, err := store.FindByID(ctx, event1.ID) 107 if err != nil { 108 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 109 } 110 if event.ID != event1.ID || event.Name != event1.Name { 111 tt.Fatalf("expected to find event1. got %v. want %v", event, event1) 112 } 113 }) 114 115 t.Run("FindByIDWithTags", func(tt *testing.T) { 116 store, cleanup, err := newStore() 117 if err != nil { 118 tt.Fatalf("Failed to create a new store: %s", err) 119 } 120 defer cleanup() 121 122 event1, _ := store.Create(ctx, &event.NewEvent{ 123 Name: "event1", 124 Tags: []string{"a", "b"}, 125 }) 126 127 event, err := store.FindByID(ctx, event1.ID) 128 if err != nil { 129 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 130 } 131 if event.ID != event1.ID || event.Name != event1.Name || !reflect.DeepEqual(event.Tags, event1.Tags) { 132 tt.Fatalf("expected to find event1. got %v. want %v", event, event1) 133 } 134 }) 135 136 t.Run("FindByIDWithOwnedBy", func(tt *testing.T) { 137 store, cleanup, err := newStore() 138 if err != nil { 139 tt.Fatalf("Failed to create a new store: %s", err) 140 } 141 defer cleanup() 142 143 event1, _ := store.Create(ctx, &event.NewEvent{ 144 Name: "event1", 145 OwnedBy: []string{"a", "b"}, 146 }) 147 148 event, err := store.FindByID(ctx, event1.ID) 149 if err != nil { 150 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 151 } 152 if event.ID != event1.ID || event.Name != event1.Name || !reflect.DeepEqual(event.OwnedBy, event1.OwnedBy) { 153 tt.Fatalf("expected to find event1. got %v. want %v", event, event1) 154 } 155 }) 156 157 t.Run("Find", func(tt *testing.T) { 158 store, cleanup, err := newStore() 159 if err != nil { 160 tt.Fatalf("Failed to create a new store: %s", err) 161 } 162 defer cleanup() 163 164 store.Create(ctx, &event.NewEvent{Name: "event1"}) 165 store.Create(ctx, &event.NewEvent{Name: "event2"}) 166 events, totalEvents, err := store.Find(ctx, nil) 167 if err != nil { 168 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 169 } 170 if len(events) != 2 { 171 tt.Fatalf("expected to recieve two events. got %d", len(events)) 172 } 173 if totalEvents != 2 { 174 tt.Fatalf("expected to recieve a total of two events. got %d", totalEvents) 175 } 176 }) 177 178 t.Run("FindTags", func(tt *testing.T) { 179 store, cleanup, err := newStore() 180 if err != nil { 181 tt.Fatalf("Failed to create a new store: %s", err) 182 } 183 defer cleanup() 184 185 event0, _ := store.Create(ctx, &event.NewEvent{Name: "event1", Tags: []string{"foo"}}) 186 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event2", Tags: []string{"bar", "foo"}}) 187 events, _, err := store.Find(ctx, nil) 188 if err != nil { 189 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 190 } 191 if !reflect.DeepEqual(events[0].Tags, event0.Tags) { 192 tt.Fatalf("event0: tags are not the same: got %v, want %v", events[0].Tags, event0.Tags) 193 } 194 if !reflect.DeepEqual(events[1].Tags, event1.Tags) { 195 tt.Fatalf("event0: tags are not the same: got %v, want %v", events[1].Tags, event1.Tags) 196 } 197 }) 198 199 t.Run("FindOwnedBy", func(tt *testing.T) { 200 store, cleanup, err := newStore() 201 if err != nil { 202 tt.Fatalf("Failed to create a new store: %s", err) 203 } 204 defer cleanup() 205 206 event0, _ := store.Create(ctx, &event.NewEvent{Name: "event1", OwnedBy: []string{"foo"}}) 207 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event2", OwnedBy: []string{"bar", "foo"}}) 208 events, _, err := store.Find(ctx, nil) 209 if err != nil { 210 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 211 } 212 if !reflect.DeepEqual(events[0].OwnedBy, event0.OwnedBy) { 213 tt.Fatalf("event0: ownedBy are not the same: got %v, want %v", events[0].OwnedBy, event0.OwnedBy) 214 } 215 if !reflect.DeepEqual(events[1].OwnedBy, event1.OwnedBy) { 216 tt.Fatalf("event0: ownedBy are not the same: got %v, want %v", events[1].OwnedBy, event1.OwnedBy) 217 } 218 }) 219 220 t.Run("FindFilter", func(tt *testing.T) { 221 store, cleanup, err := newStore() 222 if err != nil { 223 tt.Fatalf("Failed to create a new store: %s", err) 224 } 225 defer cleanup() 226 227 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event1"}) 228 store.Create(ctx, &event.NewEvent{Name: "event2"}) 229 events, totalEvents, err := store.Find(ctx, &crud.FindParams[event.FindFilters]{ 230 Filters: &event.FindFilters{Name: &event1.Name}, 231 }) 232 if err != nil { 233 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 234 } 235 if len(events) != 1 { 236 tt.Fatalf("expected to recieve one event. got %d", len(events)) 237 } 238 if totalEvents != 1 { 239 tt.Fatalf("expected to recieve a total of one event. got %d", totalEvents) 240 } 241 if events[0].ID != event1.ID { 242 tt.Fatalf("expected to find event1. got %v. want %v", events[0], event1) 243 } 244 }) 245 246 t.Run("FindFilterTags", func(tt *testing.T) { 247 store, cleanup, err := newStore() 248 if err != nil { 249 tt.Fatalf("Failed to create a new store: %s", err) 250 } 251 defer cleanup() 252 253 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event1", Tags: []string{"foo"}}) 254 store.Create(ctx, &event.NewEvent{Name: "event2"}) 255 events, totalEvents, err := store.Find(ctx, &crud.FindParams[event.FindFilters]{ 256 Filters: &event.FindFilters{Tags: []string{"foo"}}, 257 }) 258 if err != nil { 259 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 260 } 261 if len(events) != 1 { 262 tt.Fatalf("expected to recieve one event. got %d", len(events)) 263 } 264 if totalEvents != 1 { 265 tt.Fatalf("expected to recieve a total of one event. got %d", totalEvents) 266 } 267 if events[0].ID != event1.ID { 268 tt.Fatalf("expected to find event1. got %v. want %v", events[0], event1) 269 } 270 }) 271 272 t.Run("FindFilterOwnedBy", func(tt *testing.T) { 273 store, cleanup, err := newStore() 274 if err != nil { 275 tt.Fatalf("Failed to create a new store: %s", err) 276 } 277 defer cleanup() 278 279 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event1", OwnedBy: []string{"foo"}}) 280 store.Create(ctx, &event.NewEvent{Name: "event2"}) 281 events, totalEvents, err := store.Find(ctx, &crud.FindParams[event.FindFilters]{ 282 Filters: &event.FindFilters{OwnedBy: []string{"foo"}}, 283 }) 284 if err != nil { 285 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 286 } 287 if len(events) != 1 { 288 tt.Fatalf("expected to recieve one event. got %d", len(events)) 289 } 290 if totalEvents != 1 { 291 tt.Fatalf("expected to recieve a total of one event. got %d", totalEvents) 292 } 293 if events[0].ID != event1.ID { 294 tt.Fatalf("expected to find event1. got %v. want %v", events[0], event1) 295 } 296 }) 297 298 t.Run("FindFilterLikeName", func(tt *testing.T) { 299 store, cleanup, err := newStore() 300 if err != nil { 301 tt.Fatalf("Failed to create a new store: %s", err) 302 } 303 defer cleanup() 304 305 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event1"}) 306 store.Create(ctx, &event.NewEvent{Name: "event2"}) 307 events, totalEvents, err := store.Find(ctx, &crud.FindParams[event.FindFilters]{ 308 Filters: &event.FindFilters{LikeName: strptr("1")}, 309 }) 310 if err != nil { 311 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 312 } 313 if len(events) != 1 { 314 tt.Fatalf("expected to recieve one event. got %d", len(events)) 315 } 316 if totalEvents != 1 { 317 tt.Fatalf("expected to recieve a total of one event. got %d", totalEvents) 318 } 319 if events[0].ID != event1.ID { 320 tt.Fatalf("expected to find event1. got %v. want %v", events[0], event1) 321 } 322 }) 323 324 t.Run("CreateFindSortedASC", func(tt *testing.T) { 325 store, cleanup, err := newStore() 326 if err != nil { 327 tt.Fatalf("Failed to create a new store: %s", err) 328 } 329 defer cleanup() 330 331 event1, _ := store.Create(ctx, &event.NewEvent{Name: "c event1"}) 332 event2, _ := store.Create(ctx, &event.NewEvent{Name: "a event2"}) 333 event3, _ := store.Create(ctx, &event.NewEvent{Name: "b event3"}) 334 events, totalEvents, err := store.Find(ctx, &crud.FindParams[event.FindFilters]{ 335 Sort: "name", 336 Order: crud.OrderAsc, 337 }) 338 if err != nil { 339 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 340 } 341 if len(events) != 3 { 342 tt.Fatalf("expected to find three event. got %d", len(events)) 343 } 344 if totalEvents != 3 { 345 tt.Fatalf("expected to recieve a total of three events. got %d", totalEvents) 346 } 347 if events[0].ID != event2.ID { 348 tt.Fatalf("expected to event[0] to be event2 . got %v", events[0]) 349 } 350 if events[1].ID != event3.ID { 351 tt.Fatalf("expected to event[1] to be event3 . got %v", events[1]) 352 } 353 if events[2].ID != event1.ID { 354 tt.Fatalf("expected to event[2] to be event1 . got %v", events[2]) 355 } 356 }) 357 358 t.Run("CreateFindSortedDESC", func(tt *testing.T) { 359 store, cleanup, err := newStore() 360 if err != nil { 361 tt.Fatalf("Failed to create a new store: %s", err) 362 } 363 defer cleanup() 364 365 event1, _ := store.Create(ctx, &event.NewEvent{Name: "c event1"}) 366 event2, _ := store.Create(ctx, &event.NewEvent{Name: "a event2"}) 367 event3, _ := store.Create(ctx, &event.NewEvent{Name: "b event3"}) 368 events, totalEvents, err := store.Find(ctx, &crud.FindParams[event.FindFilters]{ 369 Sort: "name", 370 Order: crud.OrderDesc, 371 }) 372 if err != nil { 373 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 374 } 375 if len(events) != 3 { 376 tt.Fatalf("expected to find three event. got %d", len(events)) 377 } 378 if totalEvents != 3 { 379 tt.Fatalf("expected to recieve a total of three events. got %d", totalEvents) 380 } 381 if events[0].ID != event1.ID { 382 tt.Fatalf("expected to event[0] to be event1 . got %v", events[0]) 383 } 384 if events[1].ID != event3.ID { 385 tt.Fatalf("expected to event[1] to be event3 . got %v", events[1]) 386 } 387 if events[2].ID != event2.ID { 388 tt.Fatalf("expected to event[2] to be event2 . got %v", events[2]) 389 } 390 }) 391 392 t.Run("CreateFindPaginated", func(tt *testing.T) { 393 store, cleanup, err := newStore() 394 if err != nil { 395 tt.Fatalf("Failed to create a new store: %s", err) 396 } 397 defer cleanup() 398 399 store.Create(ctx, &event.NewEvent{Name: "event1"}) 400 event2, _ := store.Create(ctx, &event.NewEvent{Name: "event2"}) 401 store.Create(ctx, &event.NewEvent{Name: "event3"}) 402 events, totalEvents, err := store.Find(ctx, &crud.FindParams[event.FindFilters]{ 403 Limit: 1, 404 Offset: 1, 405 Sort: "name", 406 Order: "ASC", 407 }) 408 if err != nil { 409 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 410 } 411 if len(events) != 1 { 412 tt.Fatalf("expected to find one event. got %d", len(events)) 413 } 414 if totalEvents != 3 { 415 tt.Fatalf("expected to recieve a total of three events. got %d", totalEvents) 416 } 417 if events[0].ID != event2.ID || events[0].Name != event2.Name { 418 tt.Fatalf("expected to find event2. got %v. want %v", events[0], event2) 419 } 420 }) 421 422 t.Run("CreateFindPaginatedAndSorted", func(tt *testing.T) { 423 store, cleanup, err := newStore() 424 if err != nil { 425 tt.Fatalf("Failed to create a new store: %s", err) 426 } 427 defer cleanup() 428 429 event1, _ := store.Create(ctx, &event.NewEvent{Name: "c event1"}) 430 store.Create(ctx, &event.NewEvent{Name: "a event2"}) 431 store.Create(ctx, &event.NewEvent{Name: "b event3"}) 432 events, totalEvents, err := store.Find(ctx, &crud.FindParams[event.FindFilters]{ 433 Limit: 1, 434 Offset: 2, 435 Sort: "name", 436 Order: crud.OrderAsc, 437 }) 438 if err != nil { 439 tt.Fatalf("expected store.Find to succeed. got %s", err.Error()) 440 } 441 if len(events) != 1 { 442 tt.Fatalf("expected to find one event. got %d", len(events)) 443 } 444 if totalEvents != 3 { 445 tt.Fatalf("expected to recieve a total of three events. got %d", totalEvents) 446 } 447 if events[0].ID != event1.ID { 448 tt.Fatalf("expected to event[0] to be event1 . got %v", events[0]) 449 } 450 }) 451 452 t.Run("Update", func(tt *testing.T) { 453 store, cleanup, err := newStore() 454 if err != nil { 455 tt.Fatalf("Failed to create a new store: %s", err) 456 } 457 defer cleanup() 458 459 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event3"}) 460 event1.Name = "event3.1" 461 462 _, err = store.Update(ctx, event1) 463 if err != nil { 464 tt.Fatalf("expected store.Update to succeed. got %s", err.Error()) 465 } 466 467 event, err := store.FindByID(ctx, event1.ID) 468 if event.Name != "event3.1" { 469 tt.Fatalf("expected event.Name to be 'event3.1. got %s", event.Name) 470 } 471 }) 472 473 t.Run("UpdateTags", func(tt *testing.T) { 474 store, cleanup, err := newStore() 475 if err != nil { 476 tt.Fatalf("Failed to create a new store: %s", err) 477 } 478 defer cleanup() 479 480 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event3", Tags: []string{"foo", "bar"}}) 481 event1.Tags = []string{"foz", "baz"} 482 483 _, err = store.Update(ctx, event1) 484 if err != nil { 485 tt.Fatalf("expected store.Update to succeed. got %s", err.Error()) 486 } 487 488 event, err := store.FindByID(ctx, event1.ID) 489 if !reflect.DeepEqual(event.Tags, []string{"foz", "baz"}) { 490 tt.Fatalf("expected event.Tags to be ['foz', 'baz']. got %v", event.Tags) 491 } 492 }) 493 494 t.Run("UpdateOwnedBy", func(tt *testing.T) { 495 store, cleanup, err := newStore() 496 if err != nil { 497 tt.Fatalf("Failed to create a new store: %s", err) 498 } 499 defer cleanup() 500 501 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event3", OwnedBy: []string{"foo", "bar"}}) 502 event1.OwnedBy = []string{"foz", "baz"} 503 504 _, err = store.Update(ctx, event1) 505 if err != nil { 506 tt.Fatalf("expected store.Update to succeed. got %s", err.Error()) 507 } 508 509 event, err := store.FindByID(ctx, event1.ID) 510 if !reflect.DeepEqual(event.OwnedBy, []string{"foz", "baz"}) { 511 tt.Fatalf("expected event.OwnedBy to be ['foz', 'baz']. got %v", event.OwnedBy) 512 } 513 }) 514 515 t.Run("Delete", func(tt *testing.T) { 516 store, cleanup, err := newStore() 517 if err != nil { 518 tt.Fatalf("Failed to create a new store: %s", err) 519 } 520 defer cleanup() 521 522 event1, _ := store.Create(ctx, &event.NewEvent{Name: "event1"}) 523 err = store.Delete(ctx, event1.ID) 524 if err != nil { 525 tt.Fatalf("expected store.Delete to succeed. got %s", err.Error()) 526 } 527 event, err := store.FindByID(ctx, event1.ID) 528 if event != nil { 529 tt.Fatal("expected event1 to be deleted") 530 } 531 }) 532 } 533 534 func strptr(str string) *string { return &str }