github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/package/service_test.go (about) 1 package ordpackage_test 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/kyma-incubator/compass/components/director/pkg/resource" 8 9 ordpackage "github.com/kyma-incubator/compass/components/director/internal/domain/package" 10 "github.com/kyma-incubator/compass/components/director/internal/domain/package/automock" 11 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 12 "github.com/kyma-incubator/compass/components/director/internal/model" 13 "github.com/pkg/errors" 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/mock" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestService_Create(t *testing.T) { 20 // GIVEN 21 testErr := errors.New("Test error") 22 23 ctx := context.TODO() 24 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 25 26 modelPackageForApp := fixPackageModelForApp() 27 modelPackageForAppTemplateVersion := fixPackageModelForAppTemplateVersion() 28 modelInput := *fixPackageModelInput() 29 30 testCases := []struct { 31 Name string 32 RepositoryFn func() *automock.PackageRepository 33 UIDServiceFn func() *automock.UIDService 34 Input model.PackageInput 35 ResourceType resource.Type 36 ResourceID string 37 ExpectedErr error 38 }{ 39 { 40 Name: "Success for Application", 41 RepositoryFn: func() *automock.PackageRepository { 42 repo := &automock.PackageRepository{} 43 repo.On("Create", ctx, tenantID, modelPackageForApp).Return(nil).Once() 44 return repo 45 }, 46 UIDServiceFn: func() *automock.UIDService { 47 svc := &automock.UIDService{} 48 svc.On("Generate").Return(packageID) 49 return svc 50 }, 51 Input: modelInput, 52 ResourceType: resource.Application, 53 ResourceID: appID, 54 ExpectedErr: nil, 55 }, 56 { 57 Name: "Success for Application Template Version", 58 RepositoryFn: func() *automock.PackageRepository { 59 repo := &automock.PackageRepository{} 60 repo.On("CreateGlobal", ctx, modelPackageForAppTemplateVersion).Return(nil).Once() 61 return repo 62 }, 63 UIDServiceFn: func() *automock.UIDService { 64 svc := &automock.UIDService{} 65 svc.On("Generate").Return(packageID) 66 return svc 67 }, 68 Input: modelInput, 69 ResourceType: resource.ApplicationTemplateVersion, 70 ResourceID: appTemplateVersionID, 71 ExpectedErr: nil, 72 }, 73 { 74 Name: "Error - Package creation for Application", 75 RepositoryFn: func() *automock.PackageRepository { 76 repo := &automock.PackageRepository{} 77 repo.On("Create", ctx, tenantID, modelPackageForApp).Return(testErr).Once() 78 return repo 79 }, 80 UIDServiceFn: func() *automock.UIDService { 81 svc := &automock.UIDService{} 82 svc.On("Generate").Return(packageID).Once() 83 return svc 84 }, 85 Input: modelInput, 86 ResourceType: resource.Application, 87 ResourceID: appID, 88 ExpectedErr: testErr, 89 }, 90 { 91 Name: "Error - Package creation for Application Template Version", 92 RepositoryFn: func() *automock.PackageRepository { 93 repo := &automock.PackageRepository{} 94 repo.On("CreateGlobal", ctx, modelPackageForAppTemplateVersion).Return(testErr).Once() 95 return repo 96 }, 97 UIDServiceFn: func() *automock.UIDService { 98 svc := &automock.UIDService{} 99 svc.On("Generate").Return(packageID).Once() 100 return svc 101 }, 102 Input: modelInput, 103 ResourceType: resource.ApplicationTemplateVersion, 104 ResourceID: appTemplateVersionID, 105 ExpectedErr: testErr, 106 }, 107 } 108 109 for _, testCase := range testCases { 110 t.Run(testCase.Name, func(t *testing.T) { 111 // GIVEN 112 repo := testCase.RepositoryFn() 113 upackageIDService := testCase.UIDServiceFn() 114 115 svc := ordpackage.NewService(repo, upackageIDService) 116 117 // WHEN 118 result, err := svc.Create(ctx, testCase.ResourceType, testCase.ResourceID, testCase.Input, uint64(123456)) 119 120 // THEN 121 if testCase.ExpectedErr != nil { 122 require.Error(t, err) 123 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 124 } else { 125 assert.IsType(t, "string", result) 126 } 127 128 mock.AssertExpectationsForObjects(t, repo, upackageIDService) 129 }) 130 } 131 t.Run("Error when tenant not in context", func(t *testing.T) { 132 svc := ordpackage.NewService(nil, fixUIDService()) 133 // WHEN 134 _, err := svc.Create(context.TODO(), resource.Application, "", model.PackageInput{}, 0) 135 // THEN 136 require.Error(t, err) 137 assert.Contains(t, err.Error(), "cannot read tenant from context") 138 }) 139 } 140 141 func TestService_Update(t *testing.T) { 142 // GIVEN 143 testErr := errors.New("Test error") 144 145 modelPackageForApp := fixPackageModelForApp() 146 modelPackageForAppTemplateVersion := fixPackageModelForAppTemplateVersion() 147 modelInput := *fixPackageModelInput() 148 149 inputPackageModel := mock.MatchedBy(func(pkg *model.Package) bool { 150 return pkg.Title == modelInput.Title 151 }) 152 153 ctx := context.TODO() 154 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 155 156 testCases := []struct { 157 Name string 158 RepositoryFn func() *automock.PackageRepository 159 Input model.PackageInput 160 InputID string 161 ResourceType resource.Type 162 ExpectedErr error 163 }{ 164 { 165 Name: "Success for Application", 166 RepositoryFn: func() *automock.PackageRepository { 167 repo := &automock.PackageRepository{} 168 repo.On("GetByID", ctx, tenantID, packageID).Return(modelPackageForApp, nil).Once() 169 repo.On("Update", ctx, tenantID, inputPackageModel).Return(nil).Once() 170 return repo 171 }, 172 InputID: packageID, 173 Input: modelInput, 174 ResourceType: resource.Application, 175 ExpectedErr: nil, 176 }, 177 { 178 Name: "Success for Application Template Version", 179 RepositoryFn: func() *automock.PackageRepository { 180 repo := &automock.PackageRepository{} 181 repo.On("GetByIDGlobal", ctx, packageID).Return(modelPackageForAppTemplateVersion, nil).Once() 182 repo.On("UpdateGlobal", ctx, inputPackageModel).Return(nil).Once() 183 return repo 184 }, 185 InputID: packageID, 186 Input: modelInput, 187 ResourceType: resource.ApplicationTemplateVersion, 188 ExpectedErr: nil, 189 }, 190 { 191 Name: "Update Error for Application", 192 RepositoryFn: func() *automock.PackageRepository { 193 repo := &automock.PackageRepository{} 194 repo.On("GetByID", ctx, tenantID, packageID).Return(modelPackageForApp, nil).Once() 195 repo.On("Update", ctx, tenantID, inputPackageModel).Return(testErr).Once() 196 return repo 197 }, 198 InputID: packageID, 199 Input: modelInput, 200 ResourceType: resource.Application, 201 ExpectedErr: testErr, 202 }, 203 { 204 Name: "Update Error for Application Template Version", 205 RepositoryFn: func() *automock.PackageRepository { 206 repo := &automock.PackageRepository{} 207 repo.On("GetByIDGlobal", ctx, packageID).Return(modelPackageForAppTemplateVersion, nil).Once() 208 repo.On("UpdateGlobal", ctx, inputPackageModel).Return(testErr).Once() 209 return repo 210 }, 211 InputID: packageID, 212 Input: modelInput, 213 ResourceType: resource.ApplicationTemplateVersion, 214 ExpectedErr: testErr, 215 }, 216 { 217 Name: "Get Error for Application", 218 RepositoryFn: func() *automock.PackageRepository { 219 repo := &automock.PackageRepository{} 220 repo.On("GetByID", ctx, tenantID, packageID).Return(nil, testErr).Once() 221 return repo 222 }, 223 InputID: packageID, 224 Input: modelInput, 225 ResourceType: resource.Application, 226 ExpectedErr: testErr, 227 }, 228 { 229 Name: "Get Error for Application Template Version", 230 RepositoryFn: func() *automock.PackageRepository { 231 repo := &automock.PackageRepository{} 232 repo.On("GetByIDGlobal", ctx, packageID).Return(nil, testErr).Once() 233 return repo 234 }, 235 InputID: packageID, 236 Input: modelInput, 237 ResourceType: resource.ApplicationTemplateVersion, 238 ExpectedErr: testErr, 239 }, 240 } 241 242 for _, testCase := range testCases { 243 t.Run(testCase.Name, func(t *testing.T) { 244 // GIVEN 245 repo := testCase.RepositoryFn() 246 247 svc := ordpackage.NewService(repo, nil) 248 249 // WHEN 250 err := svc.Update(ctx, testCase.ResourceType, testCase.InputID, testCase.Input, 0) 251 252 // THEN 253 if testCase.ExpectedErr == nil { 254 require.NoError(t, err) 255 } else { 256 require.Error(t, err) 257 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 258 } 259 260 repo.AssertExpectations(t) 261 }) 262 } 263 t.Run("Error when tenant not in context", func(t *testing.T) { 264 svc := ordpackage.NewService(nil, fixUIDService()) 265 // WHEN 266 err := svc.Update(context.TODO(), resource.Application, "", model.PackageInput{}, 0) 267 // THEN 268 require.Error(t, err) 269 assert.Contains(t, err.Error(), "cannot read tenant from context") 270 }) 271 } 272 273 func TestService_Delete(t *testing.T) { 274 // GIVEN 275 testErr := errors.New("Test error") 276 277 ctx := context.TODO() 278 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 279 280 testCases := []struct { 281 Name string 282 RepositoryFn func() *automock.PackageRepository 283 Input model.PackageInput 284 InputID string 285 ResourceType resource.Type 286 ExpectedErr error 287 }{ 288 { 289 Name: "Success for Application", 290 RepositoryFn: func() *automock.PackageRepository { 291 repo := &automock.PackageRepository{} 292 repo.On("Delete", ctx, tenantID, packageID).Return(nil).Once() 293 return repo 294 }, 295 InputID: packageID, 296 ResourceType: resource.Application, 297 ExpectedErr: nil, 298 }, 299 { 300 Name: "Success for Application", 301 RepositoryFn: func() *automock.PackageRepository { 302 repo := &automock.PackageRepository{} 303 repo.On("DeleteGlobal", ctx, packageID).Return(nil).Once() 304 return repo 305 }, 306 InputID: packageID, 307 ResourceType: resource.ApplicationTemplateVersion, 308 ExpectedErr: nil, 309 }, 310 { 311 Name: "Delete Error for Application", 312 RepositoryFn: func() *automock.PackageRepository { 313 repo := &automock.PackageRepository{} 314 repo.On("Delete", ctx, tenantID, packageID).Return(testErr).Once() 315 return repo 316 }, 317 InputID: packageID, 318 ResourceType: resource.Application, 319 ExpectedErr: testErr, 320 }, 321 { 322 Name: "Delete Error for Application Template Version", 323 RepositoryFn: func() *automock.PackageRepository { 324 repo := &automock.PackageRepository{} 325 repo.On("DeleteGlobal", ctx, packageID).Return(testErr).Once() 326 return repo 327 }, 328 InputID: packageID, 329 ResourceType: resource.ApplicationTemplateVersion, 330 ExpectedErr: testErr, 331 }, 332 } 333 334 for _, testCase := range testCases { 335 t.Run(testCase.Name, func(t *testing.T) { 336 // GIVEN 337 repo := testCase.RepositoryFn() 338 339 svc := ordpackage.NewService(repo, nil) 340 341 // WHEN 342 err := svc.Delete(ctx, testCase.ResourceType, testCase.InputID) 343 344 // THEN 345 if testCase.ExpectedErr == nil { 346 require.NoError(t, err) 347 } else { 348 require.Error(t, err) 349 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 350 } 351 352 repo.AssertExpectations(t) 353 }) 354 } 355 t.Run("Error when tenant not in context", func(t *testing.T) { 356 svc := ordpackage.NewService(nil, nil) 357 // WHEN 358 err := svc.Delete(context.TODO(), resource.Application, "") 359 // THEN 360 require.Error(t, err) 361 assert.Contains(t, err.Error(), "cannot read tenant from context") 362 }) 363 } 364 365 func TestService_Exist(t *testing.T) { 366 // GIVEN 367 testErr := errors.New("Test error") 368 ctx := tenant.SaveToContext(context.TODO(), tenantID, externalTenantID) 369 packageID := packageID 370 371 testCases := []struct { 372 Name string 373 RepoFn func() *automock.PackageRepository 374 ExpectedError error 375 ExpectedOutput bool 376 }{ 377 { 378 Name: "Success", 379 RepoFn: func() *automock.PackageRepository { 380 pkgRepo := &automock.PackageRepository{} 381 pkgRepo.On("Exists", ctx, tenantID, packageID).Return(true, nil).Once() 382 return pkgRepo 383 }, 384 ExpectedOutput: true, 385 }, 386 { 387 Name: "Error when getting Package", 388 RepoFn: func() *automock.PackageRepository { 389 pkgRepo := &automock.PackageRepository{} 390 pkgRepo.On("Exists", ctx, tenantID, packageID).Return(false, testErr).Once() 391 return pkgRepo 392 }, 393 ExpectedError: testErr, 394 ExpectedOutput: false, 395 }, 396 } 397 398 for _, testCase := range testCases { 399 t.Run(testCase.Name, func(t *testing.T) { 400 pkgRepo := testCase.RepoFn() 401 svc := ordpackage.NewService(pkgRepo, nil) 402 403 // WHEN 404 result, err := svc.Exist(ctx, packageID) 405 406 // THEN 407 if testCase.ExpectedError != nil { 408 require.Error(t, err) 409 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 410 } else { 411 assert.NoError(t, err) 412 } 413 assert.Equal(t, testCase.ExpectedOutput, result) 414 415 pkgRepo.AssertExpectations(t) 416 }) 417 } 418 419 t.Run("Error when tenant not in context", func(t *testing.T) { 420 svc := ordpackage.NewService(nil, nil) 421 // WHEN 422 _, err := svc.Exist(context.TODO(), "") 423 // THEN 424 require.Error(t, err) 425 assert.Contains(t, err.Error(), "cannot read tenant from context") 426 }) 427 } 428 429 func TestService_Get(t *testing.T) { 430 // GIVEN 431 testErr := errors.New("Test error") 432 433 pkg := fixPackageModelForApp() 434 435 ctx := context.TODO() 436 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 437 438 testCases := []struct { 439 Name string 440 RepositoryFn func() *automock.PackageRepository 441 Input model.PackageInput 442 InputID string 443 ExpectedPackage *model.Package 444 ExpectedErrMessage string 445 }{ 446 { 447 Name: "Success", 448 RepositoryFn: func() *automock.PackageRepository { 449 repo := &automock.PackageRepository{} 450 repo.On("GetByID", ctx, tenantID, packageID).Return(pkg, nil).Once() 451 return repo 452 }, 453 InputID: packageID, 454 ExpectedPackage: pkg, 455 ExpectedErrMessage: "", 456 }, 457 { 458 Name: "Returns error when Package retrieval failed", 459 RepositoryFn: func() *automock.PackageRepository { 460 repo := &automock.PackageRepository{} 461 repo.On("GetByID", ctx, tenantID, packageID).Return(nil, testErr).Once() 462 return repo 463 }, 464 InputID: packageID, 465 ExpectedPackage: pkg, 466 ExpectedErrMessage: testErr.Error(), 467 }, 468 } 469 470 for _, testCase := range testCases { 471 t.Run(testCase.Name, func(t *testing.T) { 472 repo := testCase.RepositoryFn() 473 svc := ordpackage.NewService(repo, nil) 474 475 // WHEN 476 pkg, err := svc.Get(ctx, testCase.InputID) 477 478 // then 479 if testCase.ExpectedErrMessage == "" { 480 require.NoError(t, err) 481 assert.Equal(t, testCase.ExpectedPackage, pkg) 482 } else { 483 require.Error(t, err) 484 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 485 } 486 487 repo.AssertExpectations(t) 488 }) 489 } 490 t.Run("Error when tenant not in context", func(t *testing.T) { 491 svc := ordpackage.NewService(nil, nil) 492 // WHEN 493 _, err := svc.Get(context.TODO(), "") 494 // THEN 495 require.Error(t, err) 496 assert.Contains(t, err.Error(), "cannot read tenant from context") 497 }) 498 } 499 500 func TestService_ListByApplicationID(t *testing.T) { 501 // GIVEN 502 testErr := errors.New("Test error") 503 504 pkgs := []*model.Package{ 505 fixPackageModelForApp(), 506 fixPackageModelForApp(), 507 fixPackageModelForApp(), 508 } 509 510 ctx := context.TODO() 511 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 512 513 testCases := []struct { 514 Name string 515 PageSize int 516 RepositoryFn func() *automock.PackageRepository 517 ExpectedResult []*model.Package 518 ExpectedErrMessage string 519 }{ 520 { 521 Name: "Success", 522 RepositoryFn: func() *automock.PackageRepository { 523 repo := &automock.PackageRepository{} 524 repo.On("ListByResourceID", ctx, tenantID, appID, resource.Application).Return(pkgs, nil).Once() 525 return repo 526 }, 527 PageSize: 2, 528 ExpectedResult: pkgs, 529 ExpectedErrMessage: "", 530 }, 531 { 532 Name: "Returns error when Package listing failed", 533 RepositoryFn: func() *automock.PackageRepository { 534 repo := &automock.PackageRepository{} 535 repo.On("ListByResourceID", ctx, tenantID, appID, resource.Application).Return(nil, testErr).Once() 536 return repo 537 }, 538 PageSize: 2, 539 ExpectedResult: nil, 540 ExpectedErrMessage: testErr.Error(), 541 }, 542 } 543 544 for _, testCase := range testCases { 545 t.Run(testCase.Name, func(t *testing.T) { 546 repo := testCase.RepositoryFn() 547 548 svc := ordpackage.NewService(repo, nil) 549 550 // WHEN 551 docs, err := svc.ListByApplicationID(ctx, appID) 552 553 // then 554 if testCase.ExpectedErrMessage == "" { 555 require.NoError(t, err) 556 assert.Equal(t, testCase.ExpectedResult, docs) 557 } else { 558 require.Error(t, err) 559 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 560 } 561 562 repo.AssertExpectations(t) 563 }) 564 } 565 t.Run("Error when tenant not in context", func(t *testing.T) { 566 svc := ordpackage.NewService(nil, nil) 567 // WHEN 568 _, err := svc.ListByApplicationID(context.TODO(), "") 569 // THEN 570 require.Error(t, err) 571 assert.Contains(t, err.Error(), "cannot read tenant from context") 572 }) 573 } 574 575 func TestService_ListByApplicationTemplateVersionID(t *testing.T) { 576 // GIVEN 577 testErr := errors.New("Test error") 578 579 pkgs := []*model.Package{ 580 fixPackageModelForApp(), 581 fixPackageModelForApp(), 582 fixPackageModelForApp(), 583 } 584 585 ctx := context.TODO() 586 587 testCases := []struct { 588 Name string 589 PageSize int 590 RepositoryFn func() *automock.PackageRepository 591 ExpectedResult []*model.Package 592 ExpectedErrMessage string 593 }{ 594 { 595 Name: "Success", 596 RepositoryFn: func() *automock.PackageRepository { 597 repo := &automock.PackageRepository{} 598 repo.On("ListByResourceID", ctx, "", appTemplateVersionID, resource.ApplicationTemplateVersion).Return(pkgs, nil).Once() 599 return repo 600 }, 601 PageSize: 2, 602 ExpectedResult: pkgs, 603 ExpectedErrMessage: "", 604 }, 605 { 606 Name: "Returns error when Package listing failed", 607 RepositoryFn: func() *automock.PackageRepository { 608 repo := &automock.PackageRepository{} 609 repo.On("ListByResourceID", ctx, "", appTemplateVersionID, resource.ApplicationTemplateVersion).Return(nil, testErr).Once() 610 return repo 611 }, 612 PageSize: 2, 613 ExpectedResult: nil, 614 ExpectedErrMessage: testErr.Error(), 615 }, 616 } 617 618 for _, testCase := range testCases { 619 t.Run(testCase.Name, func(t *testing.T) { 620 repo := testCase.RepositoryFn() 621 622 svc := ordpackage.NewService(repo, nil) 623 624 // WHEN 625 docs, err := svc.ListByApplicationTemplateVersionID(ctx, appTemplateVersionID) 626 627 // then 628 if testCase.ExpectedErrMessage == "" { 629 require.NoError(t, err) 630 assert.Equal(t, testCase.ExpectedResult, docs) 631 } else { 632 require.Error(t, err) 633 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 634 } 635 636 repo.AssertExpectations(t) 637 }) 638 } 639 } 640 641 func fixUIDService() *automock.UIDService { 642 uidSvc := &automock.UIDService{} 643 uidSvc.On("Generate").Return(packageID) 644 return uidSvc 645 }