github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/eventdef/service_test.go (about) 1 package eventdef_test 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/kyma-incubator/compass/components/director/internal/uid" 9 10 "github.com/kyma-incubator/compass/components/director/pkg/str" 11 12 event "github.com/kyma-incubator/compass/components/director/internal/domain/eventdef" 13 "github.com/kyma-incubator/compass/components/director/internal/domain/eventdef/automock" 14 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 15 "github.com/kyma-incubator/compass/components/director/internal/model" 16 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 17 "github.com/kyma-incubator/compass/components/director/pkg/pagination" 18 "github.com/kyma-incubator/compass/components/director/pkg/resource" 19 "github.com/pkg/errors" 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/mock" 22 "github.com/stretchr/testify/require" 23 ) 24 25 func TestService_Get(t *testing.T) { 26 // GIVEN 27 testErr := errors.New("Test error") 28 29 id := "foo" 30 name := "foo" 31 32 eventDefinition := fixEventDefinitionModel(id, name) 33 34 ctx := context.TODO() 35 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 36 37 testCases := []struct { 38 Name string 39 RepositoryFn func() *automock.EventAPIRepository 40 Input model.EventDefinitionInput 41 InputID string 42 ExpectedDocument *model.EventDefinition 43 ExpectedErrMessage string 44 }{ 45 { 46 Name: "Success", 47 RepositoryFn: func() *automock.EventAPIRepository { 48 repo := &automock.EventAPIRepository{} 49 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinition, nil).Once() 50 return repo 51 }, 52 InputID: id, 53 ExpectedDocument: eventDefinition, 54 ExpectedErrMessage: "", 55 }, 56 { 57 Name: "Returns error when EventDefinition retrieval failed", 58 RepositoryFn: func() *automock.EventAPIRepository { 59 repo := &automock.EventAPIRepository{} 60 repo.On("GetByID", ctx, tenantID, id).Return(nil, testErr).Once() 61 return repo 62 }, 63 InputID: id, 64 ExpectedDocument: eventDefinition, 65 ExpectedErrMessage: testErr.Error(), 66 }, 67 } 68 69 for _, testCase := range testCases { 70 t.Run(testCase.Name, func(t *testing.T) { 71 repo := testCase.RepositoryFn() 72 svc := event.NewService(repo, nil, nil, nil) 73 74 // WHEN 75 document, err := svc.Get(ctx, testCase.InputID) 76 77 // then 78 if testCase.ExpectedErrMessage == "" { 79 require.NoError(t, err) 80 assert.Equal(t, testCase.ExpectedDocument, document) 81 } else { 82 require.Error(t, err) 83 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 84 } 85 86 repo.AssertExpectations(t) 87 }) 88 } 89 t.Run("Error when tenant not in context", func(t *testing.T) { 90 svc := event.NewService(nil, nil, nil, nil) 91 // WHEN 92 _, err := svc.Get(context.TODO(), "") 93 // THEN 94 require.Error(t, err) 95 assert.Contains(t, err.Error(), "cannot read tenant from context") 96 }) 97 } 98 99 func TestService_GetForBundle(t *testing.T) { 100 // GIVEN 101 testErr := errors.New("Test error") 102 103 id := "foo" 104 bndlID := "foobar" 105 name := "foo" 106 107 eventDefinition := fixEventDefinitionModel(id, name) 108 109 ctx := context.TODO() 110 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 111 112 testCases := []struct { 113 Name string 114 RepositoryFn func() *automock.EventAPIRepository 115 Input model.EventDefinitionInput 116 InputID string 117 BundleID string 118 ExpectedEvent *model.EventDefinition 119 ExpectedErrMessage string 120 }{ 121 { 122 Name: "Success", 123 RepositoryFn: func() *automock.EventAPIRepository { 124 repo := &automock.EventAPIRepository{} 125 repo.On("GetForBundle", ctx, tenantID, id, bndlID).Return(eventDefinition, nil).Once() 126 return repo 127 }, 128 InputID: id, 129 BundleID: bndlID, 130 ExpectedEvent: eventDefinition, 131 ExpectedErrMessage: "", 132 }, 133 { 134 Name: "Returns error when EventDefinition retrieval failed", 135 RepositoryFn: func() *automock.EventAPIRepository { 136 repo := &automock.EventAPIRepository{} 137 repo.On("GetForBundle", ctx, tenantID, id, bndlID).Return(nil, testErr).Once() 138 return repo 139 }, 140 InputID: id, 141 BundleID: bndlID, 142 ExpectedEvent: nil, 143 ExpectedErrMessage: testErr.Error(), 144 }, 145 } 146 147 for _, testCase := range testCases { 148 t.Run(testCase.Name, func(t *testing.T) { 149 repo := testCase.RepositoryFn() 150 svc := event.NewService(repo, nil, nil, nil) 151 152 // WHEN 153 eventDef, err := svc.GetForBundle(ctx, testCase.InputID, testCase.BundleID) 154 155 // then 156 if testCase.ExpectedErrMessage == "" { 157 require.NoError(t, err) 158 assert.Equal(t, testCase.ExpectedEvent, eventDef) 159 } else { 160 require.Error(t, err) 161 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 162 } 163 164 repo.AssertExpectations(t) 165 }) 166 } 167 t.Run("Error when tenant not in context", func(t *testing.T) { 168 svc := event.NewService(nil, nil, nil, nil) 169 // WHEN 170 _, err := svc.GetForBundle(context.TODO(), "", "") 171 // THEN 172 require.Error(t, err) 173 assert.Contains(t, err.Error(), "cannot read tenant from context") 174 }) 175 } 176 177 func TestService_ListByBundleIDs(t *testing.T) { 178 // GIVEN 179 testErr := errors.New("Test error") 180 181 firstEventID := "foo" 182 secondEventID := "foo2" 183 firstBundleID := "bar" 184 secondBundleID := "bar2" 185 name := "foo" 186 numberOfEventsInFirstBundle := 1 187 numberOfEventsInSecondBundle := 1 188 bundleIDs := []string{firstBundleID, secondBundleID} 189 190 eventFirstBundle := fixEventDefinitionModel(firstEventID, name) 191 eventSecondBundle := fixEventDefinitionModel(secondEventID, name) 192 193 eventFirstBundleReference := fixModelBundleReference(firstBundleID, firstEventID) 194 eventSecondBundleReference := fixModelBundleReference(secondBundleID, secondEventID) 195 bundleRefs := []*model.BundleReference{eventFirstBundleReference, eventSecondBundleReference} 196 totalCounts := map[string]int{firstBundleID: numberOfEventsInFirstBundle, secondBundleID: numberOfEventsInSecondBundle} 197 198 eventsFirstBundle := []*model.EventDefinition{eventFirstBundle} 199 eventsSecondBundle := []*model.EventDefinition{eventSecondBundle} 200 201 eventPageFirstBundle := &model.EventDefinitionPage{ 202 Data: eventsFirstBundle, 203 TotalCount: len(eventsFirstBundle), 204 PageInfo: &pagination.Page{ 205 HasNextPage: false, 206 EndCursor: "end", 207 StartCursor: "start", 208 }, 209 } 210 eventPageSecondBundle := &model.EventDefinitionPage{ 211 Data: eventsSecondBundle, 212 TotalCount: len(eventsSecondBundle), 213 PageInfo: &pagination.Page{ 214 HasNextPage: false, 215 EndCursor: "end", 216 StartCursor: "start", 217 }, 218 } 219 220 eventPages := []*model.EventDefinitionPage{eventPageFirstBundle, eventPageSecondBundle} 221 222 after := "test" 223 224 ctx := context.TODO() 225 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 226 227 testCases := []struct { 228 Name string 229 PageSize int 230 RepositoryFn func() *automock.EventAPIRepository 231 BundleRefSvcFn func() *automock.BundleReferenceService 232 ExpectedResult []*model.EventDefinitionPage 233 ExpectedErrMessage string 234 }{ 235 { 236 Name: "Success", 237 BundleRefSvcFn: func() *automock.BundleReferenceService { 238 svc := &automock.BundleReferenceService{} 239 svc.On("ListByBundleIDs", ctx, model.BundleEventReference, bundleIDs, 2, after).Return(bundleRefs, totalCounts, nil).Once() 240 return svc 241 }, 242 RepositoryFn: func() *automock.EventAPIRepository { 243 repo := &automock.EventAPIRepository{} 244 repo.On("ListByBundleIDs", ctx, tenantID, bundleIDs, bundleRefs, totalCounts, 2, after).Return(eventPages, nil).Once() 245 return repo 246 }, 247 PageSize: 2, 248 ExpectedResult: eventPages, 249 ExpectedErrMessage: "", 250 }, 251 { 252 Name: "Return error when page size is less than 1", 253 BundleRefSvcFn: func() *automock.BundleReferenceService { 254 svc := &automock.BundleReferenceService{} 255 return svc 256 }, 257 RepositoryFn: func() *automock.EventAPIRepository { 258 repo := &automock.EventAPIRepository{} 259 return repo 260 }, 261 PageSize: 0, 262 ExpectedResult: eventPages, 263 ExpectedErrMessage: "page size must be between 1 and 200", 264 }, 265 { 266 Name: "Return error when page size is bigger than 200", 267 BundleRefSvcFn: func() *automock.BundleReferenceService { 268 svc := &automock.BundleReferenceService{} 269 return svc 270 }, 271 RepositoryFn: func() *automock.EventAPIRepository { 272 repo := &automock.EventAPIRepository{} 273 return repo 274 }, 275 PageSize: 201, 276 ExpectedResult: eventPages, 277 ExpectedErrMessage: "page size must be between 1 and 200", 278 }, 279 { 280 Name: "Returns error when EventDefinition BundleReferences listing failed", 281 BundleRefSvcFn: func() *automock.BundleReferenceService { 282 svc := &automock.BundleReferenceService{} 283 svc.On("ListByBundleIDs", ctx, model.BundleEventReference, bundleIDs, 2, after).Return(nil, nil, testErr).Once() 284 return svc 285 }, 286 RepositoryFn: func() *automock.EventAPIRepository { 287 repo := &automock.EventAPIRepository{} 288 return repo 289 }, 290 PageSize: 2, 291 ExpectedResult: nil, 292 ExpectedErrMessage: testErr.Error(), 293 }, 294 { 295 Name: "Returns error when EventDefinition listing failed", 296 BundleRefSvcFn: func() *automock.BundleReferenceService { 297 svc := &automock.BundleReferenceService{} 298 svc.On("ListByBundleIDs", ctx, model.BundleEventReference, bundleIDs, 2, after).Return(bundleRefs, totalCounts, nil).Once() 299 return svc 300 }, 301 RepositoryFn: func() *automock.EventAPIRepository { 302 repo := &automock.EventAPIRepository{} 303 repo.On("ListByBundleIDs", ctx, tenantID, bundleIDs, bundleRefs, totalCounts, 2, after).Return(nil, testErr).Once() 304 return repo 305 }, 306 PageSize: 2, 307 ExpectedResult: nil, 308 ExpectedErrMessage: testErr.Error(), 309 }, 310 } 311 312 for _, testCase := range testCases { 313 t.Run(testCase.Name, func(t *testing.T) { 314 repo := testCase.RepositoryFn() 315 bndlRefSvc := testCase.BundleRefSvcFn() 316 317 svc := event.NewService(repo, nil, nil, bndlRefSvc) 318 319 // WHEN 320 events, err := svc.ListByBundleIDs(ctx, bundleIDs, testCase.PageSize, after) 321 322 // then 323 if testCase.ExpectedErrMessage == "" { 324 require.NoError(t, err) 325 assert.Equal(t, testCase.ExpectedResult, events) 326 } else { 327 require.Error(t, err) 328 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 329 } 330 331 repo.AssertExpectations(t) 332 }) 333 } 334 t.Run("Error when tenant not in context", func(t *testing.T) { 335 svc := event.NewService(nil, nil, nil, nil) 336 // WHEN 337 _, err := svc.ListByBundleIDs(context.TODO(), nil, 5, "") 338 // THEN 339 require.Error(t, err) 340 assert.Contains(t, err.Error(), "cannot read tenant from context") 341 }) 342 } 343 344 func TestService_ListByApplicationID(t *testing.T) { 345 // GIVEN 346 testErr := errors.New("Test error") 347 348 id := "foo" 349 name := "foo" 350 351 apiDefinitions := []*model.EventDefinition{ 352 fixEventDefinitionModel(id, name), 353 fixEventDefinitionModel(id, name), 354 fixEventDefinitionModel(id, name), 355 } 356 357 ctx := context.TODO() 358 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 359 360 testCases := []struct { 361 Name string 362 RepositoryFn func() *automock.EventAPIRepository 363 ExpectedResult []*model.EventDefinition 364 ExpectedErrMessage string 365 }{ 366 { 367 Name: "Success", 368 RepositoryFn: func() *automock.EventAPIRepository { 369 repo := &automock.EventAPIRepository{} 370 repo.On("ListByResourceID", ctx, tenantID, appID, resource.Application).Return(apiDefinitions, nil).Once() 371 return repo 372 }, 373 ExpectedResult: apiDefinitions, 374 ExpectedErrMessage: "", 375 }, 376 { 377 Name: "Returns error when EventDefinition listing failed", 378 RepositoryFn: func() *automock.EventAPIRepository { 379 repo := &automock.EventAPIRepository{} 380 repo.On("ListByResourceID", ctx, tenantID, appID, resource.Application).Return(nil, testErr).Once() 381 return repo 382 }, 383 ExpectedResult: nil, 384 ExpectedErrMessage: testErr.Error(), 385 }, 386 } 387 388 for _, testCase := range testCases { 389 t.Run(testCase.Name, func(t *testing.T) { 390 repo := testCase.RepositoryFn() 391 392 svc := event.NewService(repo, nil, nil, nil) 393 394 // WHEN 395 docs, err := svc.ListByApplicationID(ctx, appID) 396 397 // then 398 if testCase.ExpectedErrMessage == "" { 399 require.NoError(t, err) 400 assert.Equal(t, testCase.ExpectedResult, docs) 401 } else { 402 require.Error(t, err) 403 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 404 } 405 406 repo.AssertExpectations(t) 407 }) 408 } 409 t.Run("Error when tenant not in context", func(t *testing.T) { 410 svc := event.NewService(nil, nil, nil, nil) 411 // WHEN 412 _, err := svc.ListByApplicationID(context.TODO(), "") 413 // THEN 414 require.Error(t, err) 415 assert.Contains(t, err.Error(), "cannot read tenant from context") 416 }) 417 } 418 419 func TestService_ListByApplicationTemplateVersionID(t *testing.T) { 420 // GIVEN 421 testErr := errors.New("Test error") 422 423 id := "foo" 424 name := "foo" 425 426 apiDefinitions := []*model.EventDefinition{ 427 fixEventDefinitionModel(id, name), 428 fixEventDefinitionModel(id, name), 429 fixEventDefinitionModel(id, name), 430 } 431 432 ctx := context.TODO() 433 434 testCases := []struct { 435 Name string 436 RepositoryFn func() *automock.EventAPIRepository 437 ExpectedResult []*model.EventDefinition 438 ExpectedErrMessage string 439 }{ 440 { 441 Name: "Success", 442 RepositoryFn: func() *automock.EventAPIRepository { 443 repo := &automock.EventAPIRepository{} 444 repo.On("ListByResourceID", ctx, "", appTemplateVersionID, resource.ApplicationTemplateVersion).Return(apiDefinitions, nil).Once() 445 return repo 446 }, 447 ExpectedResult: apiDefinitions, 448 ExpectedErrMessage: "", 449 }, 450 { 451 Name: "Returns error when EventDefinition listing failed", 452 RepositoryFn: func() *automock.EventAPIRepository { 453 repo := &automock.EventAPIRepository{} 454 repo.On("ListByResourceID", ctx, "", appTemplateVersionID, resource.ApplicationTemplateVersion).Return(nil, testErr).Once() 455 return repo 456 }, 457 ExpectedResult: nil, 458 ExpectedErrMessage: testErr.Error(), 459 }, 460 } 461 462 for _, testCase := range testCases { 463 t.Run(testCase.Name, func(t *testing.T) { 464 repo := testCase.RepositoryFn() 465 466 svc := event.NewService(repo, nil, nil, nil) 467 468 // WHEN 469 docs, err := svc.ListByApplicationTemplateVersionID(ctx, appTemplateVersionID) 470 471 // then 472 if testCase.ExpectedErrMessage == "" { 473 require.NoError(t, err) 474 assert.Equal(t, testCase.ExpectedResult, docs) 475 } else { 476 require.Error(t, err) 477 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 478 } 479 480 repo.AssertExpectations(t) 481 }) 482 } 483 } 484 485 func TestService_ListByApplicationIDPage(t *testing.T) { 486 // GIVEN 487 testErr := errors.New("Test error") 488 489 id := "foo" 490 name := "foo" 491 pageSize := 1 492 invalidPageSize := 0 493 cursor := "" 494 495 eventDefinitions := []*model.EventDefinition{ 496 fixEventDefinitionModel(id, name), 497 fixEventDefinitionModel(id, name), 498 fixEventDefinitionModel(id, name), 499 } 500 501 eventDefinitionsPage := &model.EventDefinitionPage{ 502 Data: eventDefinitions, 503 PageInfo: &pagination.Page{ 504 StartCursor: "", 505 EndCursor: "", 506 HasNextPage: false, 507 }, 508 TotalCount: len(eventDefinitions), 509 } 510 511 ctx := context.TODO() 512 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 513 514 testCases := []struct { 515 Name string 516 PageSize int 517 RepositoryFn func() *automock.EventAPIRepository 518 ExpectedResult *model.EventDefinitionPage 519 ExpectedErrMessage string 520 }{ 521 { 522 Name: "Success", 523 PageSize: pageSize, 524 RepositoryFn: func() *automock.EventAPIRepository { 525 repo := &automock.EventAPIRepository{} 526 repo.On("ListByApplicationIDPage", ctx, tenantID, appID, pageSize, cursor).Return(eventDefinitionsPage, nil).Once() 527 return repo 528 }, 529 ExpectedResult: eventDefinitionsPage, 530 ExpectedErrMessage: "", 531 }, 532 { 533 Name: "Returns error when EventDefinition paging failed", 534 PageSize: pageSize, 535 RepositoryFn: func() *automock.EventAPIRepository { 536 repo := &automock.EventAPIRepository{} 537 repo.On("ListByApplicationIDPage", ctx, tenantID, appID, pageSize, cursor).Return(nil, testErr).Once() 538 return repo 539 }, 540 ExpectedResult: nil, 541 ExpectedErrMessage: testErr.Error(), 542 }, 543 { 544 Name: "Returns error when pageSize is out of the range 1-200", 545 PageSize: invalidPageSize, 546 RepositoryFn: func() *automock.EventAPIRepository { 547 repo := &automock.EventAPIRepository{} 548 return repo 549 }, 550 ExpectedResult: nil, 551 ExpectedErrMessage: "page size must be between 1 and 200", 552 }, 553 } 554 555 for _, testCase := range testCases { 556 t.Run(testCase.Name, func(t *testing.T) { 557 repo := testCase.RepositoryFn() 558 559 svc := event.NewService(repo, nil, nil, nil) 560 561 // WHEN 562 docs, err := svc.ListByApplicationIDPage(ctx, appID, testCase.PageSize, cursor) 563 564 // THEN 565 if testCase.ExpectedErrMessage == "" { 566 require.NoError(t, err) 567 assert.Equal(t, testCase.ExpectedResult, docs) 568 } else { 569 require.Error(t, err) 570 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 571 } 572 573 repo.AssertExpectations(t) 574 }) 575 } 576 t.Run("Error when tenant not in context", func(t *testing.T) { 577 svc := event.NewService(nil, nil, nil, nil) 578 // WHEN 579 _, err := svc.ListByApplicationID(context.TODO(), "") 580 // THEN 581 require.Error(t, err) 582 assert.Contains(t, err.Error(), "cannot read tenant from context") 583 }) 584 } 585 586 func TestService_Create(t *testing.T) { 587 // GIVEN 588 testErr := errors.New("Test error") 589 590 id := "foo" 591 bundleID := "bndlid" 592 bundleID2 := "bndlid2" 593 packageID := packageID 594 name := "Foo" 595 596 timestamp := time.Now() 597 frURL := "foo.bar" 598 spec := "test" 599 spec2 := "test2" 600 601 modelInput := model.EventDefinitionInput{ 602 Name: name, 603 VersionInput: &model.VersionInput{}, 604 } 605 606 modelSpecsInput := []*model.SpecInput{ 607 { 608 Data: &spec, 609 FetchRequest: &model.FetchRequestInput{ 610 URL: frURL, 611 }, 612 }, 613 { 614 Data: &spec2, 615 FetchRequest: &model.FetchRequestInput{ 616 URL: frURL, 617 }, 618 }, 619 } 620 621 modelEventDefinition := &model.EventDefinition{ 622 PackageID: &packageID, 623 ApplicationID: &appID, 624 Name: name, 625 Version: &model.Version{}, 626 BaseEntity: &model.BaseEntity{ 627 ID: id, 628 Ready: true, 629 }, 630 } 631 632 bundleReferenceInput := &model.BundleReferenceInput{} 633 isDefault := true 634 bundleReferenceInputWithDefaultBundle := &model.BundleReferenceInput{IsDefaultBundle: &isDefault} 635 bundleIDs := []string{bundleID, bundleID2} 636 637 ctx := context.TODO() 638 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 639 640 testCases := []struct { 641 Name string 642 RepositoryFn func() *automock.EventAPIRepository 643 UIDServiceFn func() *automock.UIDService 644 SpecServiceFn func() *automock.SpecService 645 BundleReferenceFn func() *automock.BundleReferenceService 646 Input model.EventDefinitionInput 647 SpecsInput []*model.SpecInput 648 BundleIDs []string 649 DefaultBundleID string 650 ResourceType resource.Type 651 ResourceID string 652 ExpectedErr error 653 }{ 654 { 655 Name: "Success", 656 RepositoryFn: func() *automock.EventAPIRepository { 657 repo := &automock.EventAPIRepository{} 658 repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once() 659 return repo 660 }, 661 UIDServiceFn: func() *automock.UIDService { 662 svc := &automock.UIDService{} 663 svc.On("Generate").Return(id).Once() 664 return svc 665 }, 666 SpecServiceFn: func() *automock.SpecService { 667 svc := &automock.SpecService{} 668 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 669 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[1], resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 670 return svc 671 }, 672 BundleReferenceFn: func() *automock.BundleReferenceService { 673 svc := &automock.BundleReferenceService{} 674 svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID)).Return(nil).Once() 675 return svc 676 }, 677 Input: modelInput, 678 SpecsInput: modelSpecsInput, 679 ResourceType: resource.Application, 680 ResourceID: appID, 681 }, 682 { 683 Name: "Success in ORD scenario where many bundle ids are passed", 684 RepositoryFn: func() *automock.EventAPIRepository { 685 repo := &automock.EventAPIRepository{} 686 repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once() 687 return repo 688 }, 689 UIDServiceFn: func() *automock.UIDService { 690 svc := &automock.UIDService{} 691 svc.On("Generate").Return(id).Once() 692 return svc 693 }, 694 SpecServiceFn: func() *automock.SpecService { 695 svc := &automock.SpecService{} 696 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 697 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[1], resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 698 return svc 699 }, 700 BundleReferenceFn: func() *automock.BundleReferenceService { 701 svc := &automock.BundleReferenceService{} 702 svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInputWithDefaultBundle, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID)).Return(nil).Once() 703 svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID2)).Return(nil).Once() 704 return svc 705 }, 706 Input: modelInput, 707 SpecsInput: modelSpecsInput, 708 BundleIDs: bundleIDs, 709 DefaultBundleID: bundleID, 710 ResourceID: appID, 711 ResourceType: resource.Application, 712 }, 713 { 714 Name: "Error - Event Creation", 715 RepositoryFn: func() *automock.EventAPIRepository { 716 repo := &automock.EventAPIRepository{} 717 repo.On("Create", ctx, tenantID, modelEventDefinition).Return(testErr).Once() 718 return repo 719 }, 720 UIDServiceFn: func() *automock.UIDService { 721 svc := &automock.UIDService{} 722 svc.On("Generate").Return(id).Once() 723 return svc 724 }, 725 SpecServiceFn: emptySpecService, 726 BundleReferenceFn: func() *automock.BundleReferenceService { 727 return &automock.BundleReferenceService{} 728 }, 729 Input: modelInput, 730 SpecsInput: modelSpecsInput, 731 ResourceID: appID, 732 ResourceType: resource.Application, 733 ExpectedErr: testErr, 734 }, 735 { 736 Name: "Error - Spec Creation", 737 RepositoryFn: func() *automock.EventAPIRepository { 738 repo := &automock.EventAPIRepository{} 739 repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once() 740 return repo 741 }, 742 UIDServiceFn: func() *automock.UIDService { 743 svc := &automock.UIDService{} 744 svc.On("Generate").Return(id).Once() 745 return svc 746 }, 747 SpecServiceFn: func() *automock.SpecService { 748 svc := &automock.SpecService{} 749 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("", testErr).Once() 750 return svc 751 }, 752 BundleReferenceFn: func() *automock.BundleReferenceService { 753 return &automock.BundleReferenceService{} 754 }, 755 Input: modelInput, 756 SpecsInput: modelSpecsInput, 757 ResourceID: appID, 758 ResourceType: resource.Application, 759 ExpectedErr: testErr, 760 }, 761 { 762 Name: "Error - BundleReference Event Creation", 763 RepositoryFn: func() *automock.EventAPIRepository { 764 repo := &automock.EventAPIRepository{} 765 repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once() 766 return repo 767 }, 768 UIDServiceFn: func() *automock.UIDService { 769 svc := &automock.UIDService{} 770 svc.On("Generate").Return(id).Once() 771 return svc 772 }, 773 SpecServiceFn: func() *automock.SpecService { 774 svc := &automock.SpecService{} 775 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 776 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[1], resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 777 return svc 778 }, 779 BundleReferenceFn: func() *automock.BundleReferenceService { 780 svc := &automock.BundleReferenceService{} 781 svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID)).Return(testErr).Once() 782 return svc 783 }, 784 Input: modelInput, 785 SpecsInput: modelSpecsInput, 786 ResourceID: appID, 787 ResourceType: resource.Application, 788 ExpectedErr: testErr, 789 }, 790 { 791 Name: "Error in ORD scenario - BundleReference Event Creation", 792 RepositoryFn: func() *automock.EventAPIRepository { 793 repo := &automock.EventAPIRepository{} 794 repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once() 795 return repo 796 }, 797 UIDServiceFn: func() *automock.UIDService { 798 svc := &automock.UIDService{} 799 svc.On("Generate").Return(id).Once() 800 return svc 801 }, 802 SpecServiceFn: func() *automock.SpecService { 803 svc := &automock.SpecService{} 804 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 805 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[1], resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 806 return svc 807 }, 808 BundleReferenceFn: func() *automock.BundleReferenceService { 809 svc := &automock.BundleReferenceService{} 810 svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID)).Return(nil).Once() 811 svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID2)).Return(testErr).Once() 812 return svc 813 }, 814 Input: modelInput, 815 SpecsInput: modelSpecsInput, 816 BundleIDs: bundleIDs, 817 ResourceID: appID, 818 ResourceType: resource.Application, 819 ExpectedErr: testErr, 820 }, 821 } 822 823 for _, testCase := range testCases { 824 t.Run(testCase.Name, func(t *testing.T) { 825 // GIVEN 826 repo := testCase.RepositoryFn() 827 uidService := testCase.UIDServiceFn() 828 specService := testCase.SpecServiceFn() 829 bundleReferenceService := testCase.BundleReferenceFn() 830 831 svc := event.NewService(repo, uidService, specService, bundleReferenceService) 832 svc.SetTimestampGen(func() time.Time { return timestamp }) 833 834 // WHEN 835 result, err := svc.Create(ctx, testCase.ResourceType, testCase.ResourceID, &bundleID, &packageID, testCase.Input, testCase.SpecsInput, testCase.BundleIDs, 0, testCase.DefaultBundleID) 836 837 // then 838 if testCase.ExpectedErr != nil { 839 require.Error(t, err) 840 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 841 } else { 842 assert.IsType(t, "string", result) 843 } 844 845 repo.AssertExpectations(t) 846 specService.AssertExpectations(t) 847 uidService.AssertExpectations(t) 848 bundleReferenceService.AssertExpectations(t) 849 }) 850 } 851 t.Run("Error when tenant not in context", func(t *testing.T) { 852 svc := event.NewService(nil, fixUIDSvc(), nil, nil) 853 // WHEN 854 _, err := svc.Create(context.TODO(), resource.Application, "", nil, nil, model.EventDefinitionInput{}, []*model.SpecInput{}, []string{}, 0, "") 855 // THEN 856 require.Error(t, err) 857 assert.Contains(t, err.Error(), "cannot read tenant from context") 858 }) 859 } 860 861 func TestService_CreateInApplication(t *testing.T) { 862 // GIVEN 863 testErr := errors.New("Test error") 864 865 id := "foo" 866 name := "Foo" 867 868 timestamp := time.Now() 869 frURL := "foo.bar" 870 spec := "test" 871 872 modelInput := model.EventDefinitionInput{ 873 Name: name, 874 VersionInput: &model.VersionInput{}, 875 } 876 877 modelSpecInput := &model.SpecInput{ 878 Data: &spec, 879 FetchRequest: &model.FetchRequestInput{ 880 URL: frURL, 881 }, 882 } 883 884 modelSpecsInput := []*model.SpecInput{ 885 modelSpecInput, 886 } 887 888 modelEventDefinition := &model.EventDefinition{ 889 ApplicationID: &appID, 890 Name: name, 891 Version: &model.Version{}, 892 BaseEntity: &model.BaseEntity{ 893 ID: id, 894 Ready: true, 895 }, 896 } 897 898 ctx := context.TODO() 899 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 900 901 testCases := []struct { 902 Name string 903 RepositoryFn func() *automock.EventAPIRepository 904 UIDServiceFn func() *automock.UIDService 905 SpecServiceFn func() *automock.SpecService 906 Input model.EventDefinitionInput 907 SpecsInput *model.SpecInput 908 DefaultTargetURLPerBundle map[string]string 909 DefaultBundleID string 910 ExpectedErr error 911 }{ 912 { 913 Name: "Success", 914 RepositoryFn: func() *automock.EventAPIRepository { 915 repo := &automock.EventAPIRepository{} 916 repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once() 917 return repo 918 }, 919 UIDServiceFn: func() *automock.UIDService { 920 svc := &automock.UIDService{} 921 svc.On("Generate").Return(id).Once() 922 return svc 923 }, 924 SpecServiceFn: func() *automock.SpecService { 925 svc := &automock.SpecService{} 926 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 927 return svc 928 }, 929 Input: modelInput, 930 SpecsInput: modelSpecInput, 931 }, 932 { 933 Name: "Error - API Creation", 934 RepositoryFn: func() *automock.EventAPIRepository { 935 repo := &automock.EventAPIRepository{} 936 repo.On("Create", ctx, tenantID, modelEventDefinition).Return(testErr).Once() 937 return repo 938 }, 939 UIDServiceFn: func() *automock.UIDService { 940 svc := &automock.UIDService{} 941 svc.On("Generate").Return(id).Once() 942 return svc 943 }, 944 SpecServiceFn: emptySpecService, 945 Input: modelInput, 946 SpecsInput: modelSpecInput, 947 ExpectedErr: testErr, 948 }, 949 { 950 Name: "Error - Spec Creation", 951 RepositoryFn: func() *automock.EventAPIRepository { 952 repo := &automock.EventAPIRepository{} 953 repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once() 954 return repo 955 }, 956 UIDServiceFn: func() *automock.UIDService { 957 svc := &automock.UIDService{} 958 svc.On("Generate").Return(id).Once() 959 return svc 960 }, 961 SpecServiceFn: func() *automock.SpecService { 962 svc := &automock.SpecService{} 963 svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("", testErr).Once() 964 return svc 965 }, 966 Input: modelInput, 967 SpecsInput: modelSpecInput, 968 ExpectedErr: testErr, 969 }, 970 } 971 972 for _, testCase := range testCases { 973 t.Run(testCase.Name, func(t *testing.T) { 974 // GIVEN 975 repo := testCase.RepositoryFn() 976 uidService := testCase.UIDServiceFn() 977 specService := testCase.SpecServiceFn() 978 defer mock.AssertExpectationsForObjects(t, repo, uidService, specService) 979 980 svc := event.NewService(repo, uidService, specService, nil) 981 svc.SetTimestampGen(func() time.Time { return timestamp }) 982 983 // WHEN 984 result, err := svc.CreateInApplication(ctx, appID, testCase.Input, testCase.SpecsInput) 985 986 // THEN 987 if testCase.ExpectedErr != nil { 988 require.Error(t, err) 989 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 990 } else { 991 assert.IsType(t, "string", result) 992 } 993 }) 994 } 995 t.Run("Error when tenant not in context", func(t *testing.T) { 996 svc := event.NewService(nil, uid.NewService(), nil, nil) 997 // WHEN 998 _, err := svc.CreateInApplication(context.TODO(), "", model.EventDefinitionInput{}, &model.SpecInput{}) 999 // THEN 1000 require.Error(t, err) 1001 assert.Contains(t, err.Error(), "cannot read tenant from context") 1002 }) 1003 } 1004 1005 func TestService_Update(t *testing.T) { 1006 // GIVEN 1007 testErr := errors.New("Test error") 1008 1009 id := "foo" 1010 timestamp := time.Now() 1011 frURL := "foo.bar" 1012 spec := "spec" 1013 1014 modelInput := model.EventDefinitionInput{ 1015 Name: "Foo", 1016 VersionInput: &model.VersionInput{}, 1017 } 1018 1019 modelSpecInput := model.SpecInput{ 1020 Data: &spec, 1021 FetchRequest: &model.FetchRequestInput{ 1022 URL: frURL, 1023 }, 1024 } 1025 1026 modelSpec := &model.Spec{ 1027 ID: id, 1028 ObjectType: model.EventSpecReference, 1029 ObjectID: id, 1030 Data: &spec, 1031 } 1032 1033 inputEventDefinitionModel := mock.MatchedBy(func(event *model.EventDefinition) bool { 1034 return event.Name == modelInput.Name 1035 }) 1036 1037 eventDefinitionModelForApp := &model.EventDefinition{ 1038 Name: "Bar", 1039 Version: &model.Version{}, 1040 ApplicationID: &appID, 1041 } 1042 1043 eventDefinitionModelForAppTemplateVersion := &model.EventDefinition{ 1044 Name: "Bar", 1045 Version: &model.Version{}, 1046 ApplicationTemplateVersionID: &appTemplateVersionID, 1047 } 1048 1049 ctx := context.TODO() 1050 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 1051 1052 testCases := []struct { 1053 Name string 1054 RepositoryFn func() *automock.EventAPIRepository 1055 SpecServiceFn func() *automock.SpecService 1056 Input model.EventDefinitionInput 1057 InputID string 1058 SpecInput *model.SpecInput 1059 ResourceType resource.Type 1060 ExpectedErr error 1061 }{ 1062 { 1063 Name: "Success When Spec is Found should update it for Application Template Version", 1064 RepositoryFn: func() *automock.EventAPIRepository { 1065 repo := &automock.EventAPIRepository{} 1066 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModelForAppTemplateVersion, nil).Once() 1067 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1068 return repo 1069 }, 1070 SpecServiceFn: func() *automock.SpecService { 1071 svc := &automock.SpecService{} 1072 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once() 1073 svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once() 1074 return svc 1075 }, 1076 InputID: "foo", 1077 Input: modelInput, 1078 SpecInput: &modelSpecInput, 1079 ResourceType: resource.Application, 1080 ExpectedErr: nil, 1081 }, 1082 { 1083 Name: "Success When Spec is Found should update it for Application", 1084 RepositoryFn: func() *automock.EventAPIRepository { 1085 repo := &automock.EventAPIRepository{} 1086 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModelForApp, nil).Once() 1087 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1088 return repo 1089 }, 1090 SpecServiceFn: func() *automock.SpecService { 1091 svc := &automock.SpecService{} 1092 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once() 1093 svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once() 1094 return svc 1095 }, 1096 InputID: "foo", 1097 Input: modelInput, 1098 SpecInput: &modelSpecInput, 1099 ResourceType: resource.Application, 1100 ExpectedErr: nil, 1101 }, 1102 { 1103 Name: "Success When Spec is not found should create in", 1104 RepositoryFn: func() *automock.EventAPIRepository { 1105 repo := &automock.EventAPIRepository{} 1106 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModelForApp, nil).Once() 1107 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1108 return repo 1109 }, 1110 SpecServiceFn: func() *automock.SpecService { 1111 svc := &automock.SpecService{} 1112 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, nil).Once() 1113 svc.On("CreateByReferenceObjectID", ctx, modelSpecInput, resource.Application, model.EventSpecReference, id).Return("id", nil).Once() 1114 return svc 1115 }, 1116 InputID: "foo", 1117 Input: modelInput, 1118 SpecInput: &modelSpecInput, 1119 ResourceType: resource.Application, 1120 ExpectedErr: nil, 1121 }, 1122 { 1123 Name: "Update Error", 1124 RepositoryFn: func() *automock.EventAPIRepository { 1125 repo := &automock.EventAPIRepository{} 1126 repo.On("GetByID", ctx, tenantID, "foo").Return(eventDefinitionModelForApp, nil).Once() 1127 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(testErr).Once() 1128 return repo 1129 }, 1130 SpecServiceFn: emptySpecService, 1131 InputID: "foo", 1132 Input: modelInput, 1133 SpecInput: &modelSpecInput, 1134 ResourceType: resource.Application, 1135 ExpectedErr: testErr, 1136 }, 1137 { 1138 Name: "Get Spec Error", 1139 RepositoryFn: func() *automock.EventAPIRepository { 1140 repo := &automock.EventAPIRepository{} 1141 repo.On("GetByID", ctx, tenantID, "foo").Return(eventDefinitionModelForApp, nil).Once() 1142 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1143 return repo 1144 }, 1145 SpecServiceFn: func() *automock.SpecService { 1146 svc := &automock.SpecService{} 1147 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, testErr).Once() 1148 return svc 1149 }, 1150 InputID: "foo", 1151 Input: modelInput, 1152 SpecInput: &modelSpecInput, 1153 ResourceType: resource.Application, 1154 ExpectedErr: testErr, 1155 }, 1156 { 1157 Name: "Spec Creation Error", 1158 RepositoryFn: func() *automock.EventAPIRepository { 1159 repo := &automock.EventAPIRepository{} 1160 repo.On("GetByID", ctx, tenantID, "foo").Return(eventDefinitionModelForApp, nil).Once() 1161 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1162 return repo 1163 }, 1164 SpecServiceFn: func() *automock.SpecService { 1165 svc := &automock.SpecService{} 1166 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, nil).Once() 1167 svc.On("CreateByReferenceObjectID", ctx, modelSpecInput, resource.Application, model.EventSpecReference, id).Return("", testErr).Once() 1168 return svc 1169 }, 1170 InputID: "foo", 1171 Input: modelInput, 1172 SpecInput: &modelSpecInput, 1173 ResourceType: resource.Application, 1174 ExpectedErr: testErr, 1175 }, 1176 { 1177 Name: "Spec Update Error", 1178 RepositoryFn: func() *automock.EventAPIRepository { 1179 repo := &automock.EventAPIRepository{} 1180 repo.On("GetByID", ctx, tenantID, "foo").Return(eventDefinitionModelForApp, nil).Once() 1181 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1182 return repo 1183 }, 1184 SpecServiceFn: func() *automock.SpecService { 1185 svc := &automock.SpecService{} 1186 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once() 1187 svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(testErr).Once() 1188 return svc 1189 }, 1190 InputID: "foo", 1191 Input: modelInput, 1192 SpecInput: &modelSpecInput, 1193 ResourceType: resource.Application, 1194 ExpectedErr: testErr, 1195 }, 1196 } 1197 1198 for _, testCase := range testCases { 1199 t.Run(testCase.Name, func(t *testing.T) { 1200 // GIVEN 1201 repo := testCase.RepositoryFn() 1202 specSvc := testCase.SpecServiceFn() 1203 1204 svc := event.NewService(repo, nil, specSvc, nil) 1205 svc.SetTimestampGen(func() time.Time { return timestamp }) 1206 1207 // WHEN 1208 err := svc.Update(ctx, testCase.ResourceType, testCase.InputID, testCase.Input, testCase.SpecInput) 1209 1210 // then 1211 if testCase.ExpectedErr == nil { 1212 require.NoError(t, err) 1213 } else { 1214 require.Error(t, err) 1215 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 1216 } 1217 1218 repo.AssertExpectations(t) 1219 specSvc.AssertExpectations(t) 1220 }) 1221 } 1222 t.Run("Error when tenant not in context", func(t *testing.T) { 1223 svc := event.NewService(nil, nil, nil, nil) 1224 // WHEN 1225 err := svc.Update(context.TODO(), resource.Application, "", model.EventDefinitionInput{}, &model.SpecInput{}) 1226 // THEN 1227 require.Error(t, err) 1228 assert.Contains(t, err.Error(), "cannot read tenant from context") 1229 }) 1230 } 1231 1232 func TestService_UpdateManyBundles(t *testing.T) { 1233 // GIVEN 1234 testErr := errors.New("Test error") 1235 1236 id := "foo" 1237 bndlID1 := "id1" 1238 bndlID2 := "id2" 1239 bndlID3 := "id3" 1240 bndlID4 := "id4" 1241 bndlID5 := "id5" 1242 timestamp := time.Now() 1243 frURL := "foo.bar" 1244 spec := "spec" 1245 1246 modelInput := model.EventDefinitionInput{ 1247 Name: "Foo", 1248 VersionInput: &model.VersionInput{}, 1249 } 1250 1251 modelSpecInput := model.SpecInput{ 1252 Data: &spec, 1253 FetchRequest: &model.FetchRequestInput{ 1254 URL: frURL, 1255 }, 1256 } 1257 1258 modelSpec := &model.Spec{ 1259 ID: id, 1260 ObjectType: model.EventSpecReference, 1261 ObjectID: id, 1262 Data: &spec, 1263 } 1264 1265 inputEventDefinitionModel := mock.MatchedBy(func(event *model.EventDefinition) bool { 1266 return event.Name == modelInput.Name 1267 }) 1268 1269 eventDefinitionModel := &model.EventDefinition{ 1270 Name: "Bar", 1271 Version: &model.Version{}, 1272 } 1273 1274 isDefault := true 1275 bundleReferenceInputWithDefaultBundle := &model.BundleReferenceInput{ 1276 IsDefaultBundle: &isDefault, 1277 } 1278 1279 bundleIDsForCreation := []string{bndlID1, bndlID2} 1280 bundleIDsForDeletion := []string{bndlID3, bndlID4} 1281 bundleIDsFromBundleReference := []string{bndlID5} 1282 1283 ctx := context.TODO() 1284 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 1285 1286 testCases := []struct { 1287 Name string 1288 RepositoryFn func() *automock.EventAPIRepository 1289 SpecServiceFn func() *automock.SpecService 1290 BundleReferenceServiceFn func() *automock.BundleReferenceService 1291 Input model.EventDefinitionInput 1292 InputID string 1293 SpecInput *model.SpecInput 1294 BundleIDsForCreation []string 1295 BundleIDsForDeletion []string 1296 BundleIDsFromBundleReference []string 1297 DefaultBundleID string 1298 ResourceType resource.Type 1299 ExpectedErr error 1300 }{ 1301 { 1302 Name: "Success in ORD case", 1303 RepositoryFn: func() *automock.EventAPIRepository { 1304 repo := &automock.EventAPIRepository{} 1305 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1306 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1307 return repo 1308 }, 1309 SpecServiceFn: func() *automock.SpecService { 1310 svc := &automock.SpecService{} 1311 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once() 1312 svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once() 1313 return svc 1314 }, 1315 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 1316 svc := &automock.BundleReferenceService{} 1317 svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID1).Return(nil).Once() 1318 svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID2).Return(nil).Once() 1319 svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID3).Return(nil).Once() 1320 svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID4).Return(nil).Once() 1321 svc.On("UpdateByReferenceObjectID", ctx, *bundleReferenceInputWithDefaultBundle, model.BundleEventReference, &id, &bndlID5).Return(nil).Once() 1322 return svc 1323 }, 1324 InputID: "foo", 1325 Input: modelInput, 1326 SpecInput: &modelSpecInput, 1327 BundleIDsForCreation: bundleIDsForCreation, 1328 BundleIDsForDeletion: bundleIDsForDeletion, 1329 BundleIDsFromBundleReference: bundleIDsFromBundleReference, 1330 DefaultBundleID: bndlID5, 1331 ResourceType: resource.Application, 1332 ExpectedErr: nil, 1333 }, 1334 { 1335 Name: "Success in ORD case when there is defaultBundle for BundleReference that has to be created", 1336 RepositoryFn: func() *automock.EventAPIRepository { 1337 repo := &automock.EventAPIRepository{} 1338 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1339 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1340 return repo 1341 }, 1342 SpecServiceFn: func() *automock.SpecService { 1343 svc := &automock.SpecService{} 1344 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once() 1345 svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once() 1346 return svc 1347 }, 1348 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 1349 svc := &automock.BundleReferenceService{} 1350 svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInputWithDefaultBundle, model.BundleEventReference, &id, &bndlID1).Return(nil).Once() 1351 svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID2).Return(nil).Once() 1352 svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID3).Return(nil).Once() 1353 svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID4).Return(nil).Once() 1354 svc.On("UpdateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID5).Return(nil).Once() 1355 return svc 1356 }, 1357 InputID: "foo", 1358 Input: modelInput, 1359 SpecInput: &modelSpecInput, 1360 BundleIDsForCreation: bundleIDsForCreation, 1361 BundleIDsForDeletion: bundleIDsForDeletion, 1362 BundleIDsFromBundleReference: bundleIDsFromBundleReference, 1363 DefaultBundleID: bndlID1, 1364 ResourceType: resource.Application, 1365 ExpectedErr: nil, 1366 }, 1367 { 1368 Name: "Error on BundleReference creation", 1369 RepositoryFn: func() *automock.EventAPIRepository { 1370 repo := &automock.EventAPIRepository{} 1371 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1372 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1373 return repo 1374 }, 1375 SpecServiceFn: emptySpecService, 1376 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 1377 svc := &automock.BundleReferenceService{} 1378 svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID1).Return(nil).Once() 1379 svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID2).Return(testErr).Once() 1380 return svc 1381 }, 1382 InputID: "foo", 1383 Input: modelInput, 1384 SpecInput: &modelSpecInput, 1385 BundleIDsForCreation: bundleIDsForCreation, 1386 BundleIDsForDeletion: bundleIDsForDeletion, 1387 ResourceType: resource.Application, 1388 ExpectedErr: testErr, 1389 }, 1390 { 1391 Name: "Error on BundleReference deletion", 1392 RepositoryFn: func() *automock.EventAPIRepository { 1393 repo := &automock.EventAPIRepository{} 1394 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1395 repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once() 1396 return repo 1397 }, 1398 SpecServiceFn: emptySpecService, 1399 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 1400 svc := &automock.BundleReferenceService{} 1401 svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID1).Return(nil).Once() 1402 svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID2).Return(nil).Once() 1403 svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID3).Return(nil).Once() 1404 svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID4).Return(testErr).Once() 1405 return svc 1406 }, 1407 InputID: "foo", 1408 Input: modelInput, 1409 SpecInput: &modelSpecInput, 1410 BundleIDsForCreation: bundleIDsForCreation, 1411 BundleIDsForDeletion: bundleIDsForDeletion, 1412 ResourceType: resource.Application, 1413 ExpectedErr: testErr, 1414 }, 1415 } 1416 1417 for _, testCase := range testCases { 1418 t.Run(testCase.Name, func(t *testing.T) { 1419 // GIVEN 1420 repo := testCase.RepositoryFn() 1421 specSvc := testCase.SpecServiceFn() 1422 bndlRefSvc := testCase.BundleReferenceServiceFn() 1423 1424 svc := event.NewService(repo, nil, specSvc, bndlRefSvc) 1425 svc.SetTimestampGen(func() time.Time { return timestamp }) 1426 1427 // WHEN 1428 err := svc.UpdateInManyBundles(ctx, testCase.ResourceType, testCase.InputID, testCase.Input, testCase.SpecInput, testCase.BundleIDsFromBundleReference, testCase.BundleIDsForCreation, testCase.BundleIDsForDeletion, 0, testCase.DefaultBundleID) 1429 1430 // then 1431 if testCase.ExpectedErr == nil { 1432 require.NoError(t, err) 1433 } else { 1434 require.Error(t, err) 1435 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 1436 } 1437 1438 repo.AssertExpectations(t) 1439 specSvc.AssertExpectations(t) 1440 bndlRefSvc.AssertExpectations(t) 1441 }) 1442 } 1443 t.Run("Error when tenant not in context", func(t *testing.T) { 1444 svc := event.NewService(nil, uid.NewService(), nil, nil) 1445 // WHEN 1446 err := svc.UpdateInManyBundles(context.TODO(), resource.Application, "", model.EventDefinitionInput{}, &model.SpecInput{}, []string{}, []string{}, []string{}, 0, "") 1447 // THEN 1448 require.Error(t, err) 1449 assert.Contains(t, err.Error(), "cannot read tenant from context") 1450 }) 1451 } 1452 1453 func TestService_UpdateForApplication(t *testing.T) { 1454 // GIVEN 1455 testErr := errors.New("Test error") 1456 1457 id := "foo" 1458 timestamp := time.Now() 1459 frURL := "foo.bar" 1460 spec := "spec" 1461 1462 modelInput := model.EventDefinitionInput{ 1463 Name: "Foo", 1464 VersionInput: &model.VersionInput{}, 1465 } 1466 1467 modelSpecInput := model.SpecInput{ 1468 Data: &spec, 1469 FetchRequest: &model.FetchRequestInput{ 1470 URL: frURL, 1471 }, 1472 } 1473 1474 modelSpec := &model.Spec{ 1475 ID: id, 1476 ObjectType: model.EventSpecReference, 1477 ObjectID: id, 1478 Data: &spec, 1479 } 1480 1481 inputAPIDefinitionModel := mock.MatchedBy(func(api *model.EventDefinition) bool { 1482 return api.Name == modelInput.Name 1483 }) 1484 1485 eventDefinitionModel := &model.EventDefinition{ 1486 Name: "Bar", 1487 Version: &model.Version{}, 1488 } 1489 1490 ctx := context.TODO() 1491 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 1492 1493 testCases := []struct { 1494 Name string 1495 RepositoryFn func() *automock.EventAPIRepository 1496 SpecServiceFn func() *automock.SpecService 1497 BundleReferenceFn func() *automock.BundleReferenceService 1498 SpecInput *model.SpecInput 1499 Input model.EventDefinitionInput 1500 InputID string 1501 ExpectedErr error 1502 }{ 1503 { 1504 Name: "Success with spec update", 1505 RepositoryFn: func() *automock.EventAPIRepository { 1506 repo := &automock.EventAPIRepository{} 1507 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1508 repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once() 1509 return repo 1510 }, 1511 SpecServiceFn: func() *automock.SpecService { 1512 svc := &automock.SpecService{} 1513 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once() 1514 svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once() 1515 return svc 1516 }, 1517 SpecInput: &modelSpecInput, 1518 InputID: "foo", 1519 Input: modelInput, 1520 ExpectedErr: nil, 1521 }, 1522 { 1523 Name: "Success with spec create", 1524 RepositoryFn: func() *automock.EventAPIRepository { 1525 repo := &automock.EventAPIRepository{} 1526 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1527 repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once() 1528 return repo 1529 }, 1530 SpecServiceFn: func() *automock.SpecService { 1531 svc := &automock.SpecService{} 1532 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, nil).Once() 1533 svc.On("CreateByReferenceObjectID", ctx, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(specID, nil).Once() 1534 return svc 1535 }, 1536 SpecInput: &modelSpecInput, 1537 InputID: "foo", 1538 Input: modelInput, 1539 ExpectedErr: nil, 1540 }, 1541 { 1542 Name: "Success without specs", 1543 RepositoryFn: func() *automock.EventAPIRepository { 1544 repo := &automock.EventAPIRepository{} 1545 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1546 repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once() 1547 return repo 1548 }, 1549 SpecServiceFn: emptySpecService, 1550 SpecInput: nil, 1551 InputID: "foo", 1552 Input: modelInput, 1553 ExpectedErr: nil, 1554 }, 1555 { 1556 Name: "Error when getting Event", 1557 RepositoryFn: func() *automock.EventAPIRepository { 1558 repo := &automock.EventAPIRepository{} 1559 repo.On("GetByID", ctx, tenantID, id).Return(nil, testErr).Once() 1560 return repo 1561 }, 1562 SpecServiceFn: emptySpecService, 1563 SpecInput: &modelSpecInput, 1564 InputID: "foo", 1565 Input: modelInput, 1566 ExpectedErr: testErr, 1567 }, 1568 { 1569 Name: "Error when updating Event", 1570 RepositoryFn: func() *automock.EventAPIRepository { 1571 repo := &automock.EventAPIRepository{} 1572 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1573 repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(testErr).Once() 1574 return repo 1575 }, 1576 SpecServiceFn: emptySpecService, 1577 SpecInput: &modelSpecInput, 1578 InputID: "foo", 1579 Input: modelInput, 1580 ExpectedErr: testErr, 1581 }, 1582 { 1583 Name: "Error when getting specs after Event update", 1584 RepositoryFn: func() *automock.EventAPIRepository { 1585 repo := &automock.EventAPIRepository{} 1586 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1587 repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once() 1588 return repo 1589 }, 1590 SpecServiceFn: func() *automock.SpecService { 1591 svc := &automock.SpecService{} 1592 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, testErr).Once() 1593 return svc 1594 }, 1595 SpecInput: &modelSpecInput, 1596 InputID: "foo", 1597 Input: modelInput, 1598 ExpectedErr: testErr, 1599 }, 1600 { 1601 Name: "Error when creating specs after API update", 1602 RepositoryFn: func() *automock.EventAPIRepository { 1603 repo := &automock.EventAPIRepository{} 1604 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1605 repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once() 1606 return repo 1607 }, 1608 SpecServiceFn: func() *automock.SpecService { 1609 svc := &automock.SpecService{} 1610 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, nil).Once() 1611 svc.On("CreateByReferenceObjectID", ctx, modelSpecInput, resource.Application, model.EventSpecReference, id).Return("", testErr).Once() 1612 return svc 1613 }, 1614 SpecInput: &modelSpecInput, 1615 InputID: "foo", 1616 Input: modelInput, 1617 ExpectedErr: testErr, 1618 }, 1619 { 1620 Name: "Error when updating specs after API update", 1621 RepositoryFn: func() *automock.EventAPIRepository { 1622 repo := &automock.EventAPIRepository{} 1623 repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once() 1624 repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once() 1625 return repo 1626 }, 1627 SpecServiceFn: func() *automock.SpecService { 1628 svc := &automock.SpecService{} 1629 svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once() 1630 svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(testErr).Once() 1631 return svc 1632 }, 1633 SpecInput: &modelSpecInput, 1634 InputID: "foo", 1635 Input: modelInput, 1636 ExpectedErr: testErr, 1637 }, 1638 } 1639 1640 for _, testCase := range testCases { 1641 t.Run(testCase.Name, func(t *testing.T) { 1642 // GIVEN 1643 repo := testCase.RepositoryFn() 1644 specSvc := testCase.SpecServiceFn() 1645 defer mock.AssertExpectationsForObjects(t, repo, specSvc) 1646 1647 svc := event.NewService(repo, nil, specSvc, nil) 1648 svc.SetTimestampGen(func() time.Time { return timestamp }) 1649 1650 // WHEN 1651 err := svc.UpdateForApplication(ctx, testCase.InputID, testCase.Input, testCase.SpecInput) 1652 1653 // then 1654 if testCase.ExpectedErr == nil { 1655 require.NoError(t, err) 1656 } else { 1657 require.Error(t, err) 1658 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 1659 } 1660 }) 1661 } 1662 t.Run("Error when tenant not in context", func(t *testing.T) { 1663 svc := event.NewService(nil, nil, nil, nil) 1664 // WHEN 1665 err := svc.UpdateForApplication(context.TODO(), "", model.EventDefinitionInput{}, &model.SpecInput{}) 1666 // THEN 1667 require.Error(t, err) 1668 assert.Contains(t, err.Error(), "cannot read tenant from context") 1669 }) 1670 } 1671 1672 func TestService_Delete(t *testing.T) { 1673 // GIVEN 1674 testErr := errors.New("Test error") 1675 1676 id := "foo" 1677 1678 ctx := context.TODO() 1679 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 1680 1681 testCases := []struct { 1682 Name string 1683 RepositoryFn func() *automock.EventAPIRepository 1684 Input model.EventDefinitionInput 1685 InputID string 1686 ResourceType resource.Type 1687 ExpectedErr error 1688 }{ 1689 { 1690 Name: "Success for Application", 1691 RepositoryFn: func() *automock.EventAPIRepository { 1692 repo := &automock.EventAPIRepository{} 1693 repo.On("Delete", ctx, tenantID, id).Return(nil).Once() 1694 return repo 1695 }, 1696 InputID: id, 1697 ResourceType: resource.Application, 1698 ExpectedErr: nil, 1699 }, 1700 { 1701 Name: "Success for Application Template Version", 1702 RepositoryFn: func() *automock.EventAPIRepository { 1703 repo := &automock.EventAPIRepository{} 1704 repo.On("DeleteGlobal", ctx, id).Return(nil).Once() 1705 return repo 1706 }, 1707 InputID: id, 1708 ResourceType: resource.ApplicationTemplateVersion, 1709 ExpectedErr: nil, 1710 }, 1711 { 1712 Name: "Delete Error for Application", 1713 RepositoryFn: func() *automock.EventAPIRepository { 1714 repo := &automock.EventAPIRepository{} 1715 repo.On("Delete", ctx, tenantID, id).Return(testErr).Once() 1716 return repo 1717 }, 1718 InputID: id, 1719 ResourceType: resource.Application, 1720 ExpectedErr: testErr, 1721 }, 1722 { 1723 Name: "Delete Error for Application Template Version", 1724 RepositoryFn: func() *automock.EventAPIRepository { 1725 repo := &automock.EventAPIRepository{} 1726 repo.On("DeleteGlobal", ctx, id).Return(testErr).Once() 1727 return repo 1728 }, 1729 InputID: id, 1730 ResourceType: resource.ApplicationTemplateVersion, 1731 ExpectedErr: testErr, 1732 }, 1733 } 1734 1735 for _, testCase := range testCases { 1736 t.Run(testCase.Name, func(t *testing.T) { 1737 // GIVEN 1738 repo := testCase.RepositoryFn() 1739 1740 svc := event.NewService(repo, nil, nil, nil) 1741 1742 // WHEN 1743 err := svc.Delete(ctx, testCase.ResourceType, testCase.InputID) 1744 1745 // then 1746 if testCase.ExpectedErr == nil { 1747 require.NoError(t, err) 1748 } else { 1749 require.Error(t, err) 1750 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 1751 } 1752 1753 repo.AssertExpectations(t) 1754 }) 1755 } 1756 t.Run("Error when tenant not in context", func(t *testing.T) { 1757 svc := event.NewService(nil, nil, nil, nil) 1758 // WHEN 1759 err := svc.Delete(context.TODO(), resource.Application, "") 1760 // THEN 1761 require.Error(t, err) 1762 assert.Contains(t, err.Error(), "cannot read tenant from context") 1763 }) 1764 } 1765 1766 func TestService_DeleteAllByBundleID(t *testing.T) { 1767 // GIVEN 1768 testErr := errors.New("Test error") 1769 id := "foo" 1770 1771 ctx := context.TODO() 1772 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 1773 1774 testCases := []struct { 1775 Name string 1776 RepositoryFn func() *automock.EventAPIRepository 1777 Input model.EventDefinitionInput 1778 InputID string 1779 ExpectedErr error 1780 }{ 1781 { 1782 Name: "Success", 1783 RepositoryFn: func() *automock.EventAPIRepository { 1784 repo := &automock.EventAPIRepository{} 1785 repo.On("DeleteAllByBundleID", ctx, tenantID, id).Return(nil).Once() 1786 return repo 1787 }, 1788 InputID: id, 1789 ExpectedErr: nil, 1790 }, 1791 { 1792 Name: "Delete Error", 1793 RepositoryFn: func() *automock.EventAPIRepository { 1794 repo := &automock.EventAPIRepository{} 1795 repo.On("DeleteAllByBundleID", ctx, tenantID, id).Return(testErr).Once() 1796 return repo 1797 }, 1798 InputID: id, 1799 ExpectedErr: testErr, 1800 }, 1801 } 1802 1803 for _, testCase := range testCases { 1804 t.Run(testCase.Name, func(t *testing.T) { 1805 // GIVEN 1806 repo := testCase.RepositoryFn() 1807 1808 svc := event.NewService(repo, nil, nil, nil) 1809 1810 // WHEN 1811 err := svc.DeleteAllByBundleID(ctx, testCase.InputID) 1812 1813 // then 1814 if testCase.ExpectedErr == nil { 1815 require.NoError(t, err) 1816 } else { 1817 require.Error(t, err) 1818 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 1819 } 1820 1821 repo.AssertExpectations(t) 1822 }) 1823 } 1824 t.Run("Error when tenant not in context", func(t *testing.T) { 1825 svc := event.NewService(nil, nil, nil, nil) 1826 // WHEN 1827 err := svc.DeleteAllByBundleID(context.TODO(), "") 1828 // THEN 1829 require.Error(t, err) 1830 assert.Contains(t, err.Error(), "cannot read tenant from context") 1831 }) 1832 } 1833 1834 func TestService_ListFetchRequests(t *testing.T) { 1835 // GIVEN 1836 ctx := context.TODO() 1837 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 1838 1839 testErr := errors.New("Test error") 1840 1841 frURL := "foo.bar" 1842 firstFRID := "frID" 1843 secondFRID := "frID2" 1844 firstSpecID := "specID" 1845 secondSpecID := "specID2" 1846 specIDs := []string{firstSpecID, secondSpecID} 1847 timestamp := time.Now() 1848 1849 firstFetchRequest := fixModelFetchRequest(firstFRID, frURL, timestamp) 1850 secondFetchRequest := fixModelFetchRequest(secondFRID, frURL, timestamp) 1851 fetchRequests := []*model.FetchRequest{firstFetchRequest, secondFetchRequest} 1852 1853 testCases := []struct { 1854 Name string 1855 SpecServiceFn func() *automock.SpecService 1856 ExpectedFetchRequests []*model.FetchRequest 1857 ExpectedErrMessage string 1858 }{ 1859 { 1860 Name: "Success", 1861 SpecServiceFn: func() *automock.SpecService { 1862 svc := &automock.SpecService{} 1863 svc.On("ListFetchRequestsByReferenceObjectIDs", ctx, tenantID, specIDs, model.EventSpecReference).Return(fetchRequests, nil).Once() 1864 return svc 1865 }, 1866 ExpectedFetchRequests: fetchRequests, 1867 }, 1868 { 1869 Name: "Success - Fetch Request Not Found", 1870 SpecServiceFn: func() *automock.SpecService { 1871 svc := &automock.SpecService{} 1872 svc.On("ListFetchRequestsByReferenceObjectIDs", ctx, tenantID, specIDs, model.EventSpecReference).Return(nil, apperrors.NewNotFoundError(resource.FetchRequest, "")).Once() 1873 return svc 1874 }, 1875 ExpectedFetchRequests: nil, 1876 }, 1877 { 1878 Name: "Error while listing Fetch Requests", 1879 SpecServiceFn: func() *automock.SpecService { 1880 svc := &automock.SpecService{} 1881 svc.On("ListFetchRequestsByReferenceObjectIDs", ctx, tenantID, specIDs, model.EventSpecReference).Return(nil, testErr).Once() 1882 return svc 1883 }, 1884 ExpectedFetchRequests: nil, 1885 ExpectedErrMessage: testErr.Error(), 1886 }, 1887 } 1888 1889 for _, testCase := range testCases { 1890 t.Run(testCase.Name, func(t *testing.T) { 1891 specService := testCase.SpecServiceFn() 1892 1893 svc := event.NewService(nil, nil, specService, nil) 1894 1895 // WHEN 1896 frs, err := svc.ListFetchRequests(ctx, specIDs) 1897 1898 // then 1899 if testCase.ExpectedErrMessage == "" { 1900 require.NoError(t, err) 1901 assert.Equal(t, frs, testCase.ExpectedFetchRequests) 1902 } else { 1903 require.Error(t, err) 1904 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 1905 } 1906 1907 specService.AssertExpectations(t) 1908 }) 1909 } 1910 t.Run("Returns error on loading tenant", func(t *testing.T) { 1911 svc := event.NewService(nil, nil, nil, nil) 1912 // WHEN 1913 _, err := svc.ListFetchRequests(context.TODO(), nil) 1914 assert.True(t, apperrors.IsCannotReadTenant(err)) 1915 }) 1916 } 1917 1918 func fixUIDSvc() *automock.UIDService { 1919 svc := &automock.UIDService{} 1920 svc.On("Generate").Return(eventID) 1921 return svc 1922 } 1923 1924 func emptySpecService() *automock.SpecService { 1925 svc := &automock.SpecService{} 1926 return svc 1927 }