github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/tombstone/service_test.go (about) 1 package tombstone_test 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/kyma-incubator/compass/components/director/pkg/resource" 8 9 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 10 "github.com/kyma-incubator/compass/components/director/internal/domain/tombstone" 11 "github.com/kyma-incubator/compass/components/director/internal/domain/tombstone/automock" 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 modelTombstoneForApp := fixTombstoneModelForApp() 27 modelTombstoneForAppTemplateVersion := fixTombstoneModelForAppTemplateVersion() 28 modelInput := *fixTombstoneModelInput() 29 30 testCases := []struct { 31 Name string 32 RepositoryFn func() *automock.TombstoneRepository 33 UIDServiceFn func() *automock.UIDService 34 Input model.TombstoneInput 35 ResourceType resource.Type 36 ResourceID string 37 ExpectedErr error 38 }{ 39 { 40 Name: "Success for Application", 41 RepositoryFn: func() *automock.TombstoneRepository { 42 repo := &automock.TombstoneRepository{} 43 repo.On("Create", ctx, tenantID, modelTombstoneForApp).Return(nil).Once() 44 return repo 45 }, 46 UIDServiceFn: func() *automock.UIDService { 47 svc := &automock.UIDService{} 48 svc.On("Generate").Return(tombstoneID) 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.TombstoneRepository { 59 repo := &automock.TombstoneRepository{} 60 repo.On("CreateGlobal", ctx, modelTombstoneForAppTemplateVersion).Return(nil).Once() 61 return repo 62 }, 63 UIDServiceFn: func() *automock.UIDService { 64 svc := &automock.UIDService{} 65 svc.On("Generate").Return(tombstoneID) 66 return svc 67 }, 68 Input: modelInput, 69 ResourceType: resource.ApplicationTemplateVersion, 70 ResourceID: appTemplateVersionID, 71 ExpectedErr: nil, 72 }, 73 { 74 Name: "Error - Tombstone creation for Application", 75 RepositoryFn: func() *automock.TombstoneRepository { 76 repo := &automock.TombstoneRepository{} 77 repo.On("Create", ctx, tenantID, modelTombstoneForApp).Return(testErr).Once() 78 return repo 79 }, 80 UIDServiceFn: func() *automock.UIDService { 81 svc := &automock.UIDService{} 82 svc.On("Generate").Return(tombstoneID) 83 return svc 84 }, 85 Input: modelInput, 86 ResourceType: resource.Application, 87 ResourceID: appID, 88 ExpectedErr: testErr, 89 }, 90 { 91 Name: "Error - Tombstone creation for Application Template Version", 92 RepositoryFn: func() *automock.TombstoneRepository { 93 repo := &automock.TombstoneRepository{} 94 repo.On("CreateGlobal", ctx, modelTombstoneForAppTemplateVersion).Return(testErr).Once() 95 return repo 96 }, 97 UIDServiceFn: func() *automock.UIDService { 98 svc := &automock.UIDService{} 99 svc.On("Generate").Return(tombstoneID) 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 uidSvc := testCase.UIDServiceFn() 114 115 svc := tombstone.NewService(repo, uidSvc) 116 117 // WHEN 118 result, err := svc.Create(ctx, testCase.ResourceType, testCase.ResourceID, testCase.Input) 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) 129 }) 130 } 131 t.Run("Error when tenant not in context", func(t *testing.T) { 132 svc := tombstone.NewService(nil, fixUIDService()) 133 // WHEN 134 _, err := svc.Create(context.TODO(), resource.Application, "", model.TombstoneInput{}) 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 modelTombstoneForApp := fixTombstoneModelForApp() 146 modelTombstoneForAppTemplateVersion := fixTombstoneModelForAppTemplateVersion() 147 modelInput := *fixTombstoneModelInput() 148 149 inputTombstoneModel := mock.MatchedBy(func(ts *model.Tombstone) bool { 150 return ts.OrdID == modelInput.OrdID 151 }) 152 153 ctx := context.TODO() 154 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 155 156 testCases := []struct { 157 Name string 158 RepositoryFn func() *automock.TombstoneRepository 159 Input model.TombstoneInput 160 InputID string 161 ResourceType resource.Type 162 ExpectedErr error 163 }{ 164 { 165 Name: "Success for Application", 166 RepositoryFn: func() *automock.TombstoneRepository { 167 repo := &automock.TombstoneRepository{} 168 repo.On("GetByID", ctx, tenantID, tombstoneID).Return(modelTombstoneForApp, nil).Once() 169 repo.On("Update", ctx, tenantID, inputTombstoneModel).Return(nil).Once() 170 return repo 171 }, 172 InputID: tombstoneID, 173 Input: modelInput, 174 ResourceType: resource.Application, 175 ExpectedErr: nil, 176 }, 177 { 178 Name: "Success for Application Template Version", 179 RepositoryFn: func() *automock.TombstoneRepository { 180 repo := &automock.TombstoneRepository{} 181 repo.On("GetByIDGlobal", ctx, tombstoneID).Return(modelTombstoneForAppTemplateVersion, nil).Once() 182 repo.On("UpdateGlobal", ctx, inputTombstoneModel).Return(nil).Once() 183 return repo 184 }, 185 InputID: tombstoneID, 186 Input: modelInput, 187 ResourceType: resource.ApplicationTemplateVersion, 188 ExpectedErr: nil, 189 }, 190 { 191 Name: "Update Error for Application", 192 RepositoryFn: func() *automock.TombstoneRepository { 193 repo := &automock.TombstoneRepository{} 194 repo.On("GetByID", ctx, tenantID, tombstoneID).Return(modelTombstoneForApp, nil).Once() 195 repo.On("Update", ctx, tenantID, inputTombstoneModel).Return(testErr).Once() 196 return repo 197 }, 198 InputID: tombstoneID, 199 Input: modelInput, 200 ResourceType: resource.Application, 201 ExpectedErr: testErr, 202 }, 203 { 204 Name: "Update Error for Application Template Version", 205 RepositoryFn: func() *automock.TombstoneRepository { 206 repo := &automock.TombstoneRepository{} 207 repo.On("GetByIDGlobal", ctx, tombstoneID).Return(modelTombstoneForAppTemplateVersion, nil).Once() 208 repo.On("UpdateGlobal", ctx, inputTombstoneModel).Return(testErr).Once() 209 return repo 210 }, 211 InputID: tombstoneID, 212 Input: modelInput, 213 ResourceType: resource.ApplicationTemplateVersion, 214 ExpectedErr: testErr, 215 }, 216 { 217 Name: "Get Error for Application", 218 RepositoryFn: func() *automock.TombstoneRepository { 219 repo := &automock.TombstoneRepository{} 220 repo.On("GetByID", ctx, tenantID, tombstoneID).Return(nil, testErr).Once() 221 return repo 222 }, 223 InputID: tombstoneID, 224 Input: modelInput, 225 ResourceType: resource.Application, 226 ExpectedErr: testErr, 227 }, 228 { 229 Name: "Get Error for Application Template Version", 230 RepositoryFn: func() *automock.TombstoneRepository { 231 repo := &automock.TombstoneRepository{} 232 repo.On("GetByIDGlobal", ctx, tombstoneID).Return(nil, testErr).Once() 233 return repo 234 }, 235 InputID: tombstoneID, 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 := tombstone.NewService(repo, nil) 248 249 // WHEN 250 err := svc.Update(ctx, testCase.ResourceType, testCase.InputID, testCase.Input) 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 := tombstone.NewService(nil, fixUIDService()) 265 // WHEN 266 err := svc.Update(context.TODO(), resource.Application, "", model.TombstoneInput{}) 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.TombstoneRepository 283 Input model.TombstoneInput 284 InputID string 285 ExpectedErr error 286 }{ 287 { 288 Name: "Success", 289 RepositoryFn: func() *automock.TombstoneRepository { 290 repo := &automock.TombstoneRepository{} 291 repo.On("Delete", ctx, tenantID, tombstoneID).Return(nil).Once() 292 return repo 293 }, 294 InputID: tombstoneID, 295 ExpectedErr: nil, 296 }, 297 { 298 Name: "Delete Error", 299 RepositoryFn: func() *automock.TombstoneRepository { 300 repo := &automock.TombstoneRepository{} 301 repo.On("Delete", ctx, tenantID, tombstoneID).Return(testErr).Once() 302 return repo 303 }, 304 InputID: tombstoneID, 305 ExpectedErr: testErr, 306 }, 307 } 308 309 for _, testCase := range testCases { 310 t.Run(testCase.Name, func(t *testing.T) { 311 // GIVEN 312 repo := testCase.RepositoryFn() 313 314 svc := tombstone.NewService(repo, nil) 315 316 // WHEN 317 err := svc.Delete(ctx, testCase.InputID) 318 319 // then 320 if testCase.ExpectedErr == nil { 321 require.NoError(t, err) 322 } else { 323 require.Error(t, err) 324 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 325 } 326 327 repo.AssertExpectations(t) 328 }) 329 } 330 t.Run("Error when tenant not in context", func(t *testing.T) { 331 svc := tombstone.NewService(nil, nil) 332 // WHEN 333 err := svc.Delete(context.TODO(), "") 334 // THEN 335 require.Error(t, err) 336 assert.Contains(t, err.Error(), "cannot read tenant from context") 337 }) 338 } 339 340 func TestService_Exist(t *testing.T) { 341 // GIVEN 342 testErr := errors.New("Test error") 343 ctx := tenant.SaveToContext(context.TODO(), tenantID, externalTenantID) 344 345 testCases := []struct { 346 Name string 347 RepoFn func() *automock.TombstoneRepository 348 ExpectedError error 349 ExpectedOutput bool 350 }{ 351 { 352 Name: "Success", 353 RepoFn: func() *automock.TombstoneRepository { 354 pkgRepo := &automock.TombstoneRepository{} 355 pkgRepo.On("Exists", ctx, tenantID, tombstoneID).Return(true, nil).Once() 356 return pkgRepo 357 }, 358 ExpectedOutput: true, 359 }, 360 { 361 Name: "Error when getting Tombstone", 362 RepoFn: func() *automock.TombstoneRepository { 363 pkgRepo := &automock.TombstoneRepository{} 364 pkgRepo.On("Exists", ctx, tenantID, tombstoneID).Return(false, testErr).Once() 365 return pkgRepo 366 }, 367 ExpectedError: testErr, 368 ExpectedOutput: false, 369 }, 370 } 371 372 for _, testCase := range testCases { 373 t.Run(testCase.Name, func(t *testing.T) { 374 tombstoneRepo := testCase.RepoFn() 375 svc := tombstone.NewService(tombstoneRepo, nil) 376 377 // WHEN 378 result, err := svc.Exist(ctx, tombstoneID) 379 380 // THEN 381 if testCase.ExpectedError != nil { 382 require.Error(t, err) 383 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 384 } else { 385 assert.NoError(t, err) 386 } 387 assert.Equal(t, testCase.ExpectedOutput, result) 388 389 tombstoneRepo.AssertExpectations(t) 390 }) 391 } 392 393 t.Run("Error when tenant not in context", func(t *testing.T) { 394 svc := tombstone.NewService(nil, nil) 395 // WHEN 396 _, err := svc.Exist(context.TODO(), "") 397 // THEN 398 require.Error(t, err) 399 assert.Contains(t, err.Error(), "cannot read tenant from context") 400 }) 401 } 402 403 func TestService_Get(t *testing.T) { 404 // GIVEN 405 testErr := errors.New("Test error") 406 407 tsModel := fixTombstoneModelForApp() 408 409 ctx := context.TODO() 410 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 411 412 testCases := []struct { 413 Name string 414 RepositoryFn func() *automock.TombstoneRepository 415 Input model.TombstoneInput 416 InputID string 417 ExpectedTombstone *model.Tombstone 418 ExpectedErrMessage string 419 }{ 420 { 421 Name: "Success", 422 RepositoryFn: func() *automock.TombstoneRepository { 423 repo := &automock.TombstoneRepository{} 424 repo.On("GetByID", ctx, tenantID, tombstoneID).Return(tsModel, nil).Once() 425 return repo 426 }, 427 InputID: tombstoneID, 428 ExpectedTombstone: tsModel, 429 ExpectedErrMessage: "", 430 }, 431 { 432 Name: "Returns error when Tombstone retrieval failed", 433 RepositoryFn: func() *automock.TombstoneRepository { 434 repo := &automock.TombstoneRepository{} 435 repo.On("GetByID", ctx, tenantID, tombstoneID).Return(nil, testErr).Once() 436 return repo 437 }, 438 InputID: tombstoneID, 439 ExpectedTombstone: tsModel, 440 ExpectedErrMessage: testErr.Error(), 441 }, 442 } 443 444 for _, testCase := range testCases { 445 t.Run(testCase.Name, func(t *testing.T) { 446 repo := testCase.RepositoryFn() 447 svc := tombstone.NewService(repo, nil) 448 449 // WHEN 450 ts, err := svc.Get(ctx, testCase.InputID) 451 452 // then 453 if testCase.ExpectedErrMessage == "" { 454 require.NoError(t, err) 455 assert.Equal(t, testCase.ExpectedTombstone, ts) 456 } else { 457 require.Error(t, err) 458 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 459 } 460 461 repo.AssertExpectations(t) 462 }) 463 } 464 t.Run("Error when tenant not in context", func(t *testing.T) { 465 svc := tombstone.NewService(nil, nil) 466 // WHEN 467 _, err := svc.Get(context.TODO(), "") 468 // THEN 469 require.Error(t, err) 470 assert.Contains(t, err.Error(), "cannot read tenant from context") 471 }) 472 } 473 474 func TestService_ListByApplicationID(t *testing.T) { 475 // GIVEN 476 testErr := errors.New("Test error") 477 478 tombstones := []*model.Tombstone{ 479 fixTombstoneModelForApp(), 480 fixTombstoneModelForApp(), 481 fixTombstoneModelForApp(), 482 } 483 484 ctx := context.TODO() 485 ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID) 486 487 testCases := []struct { 488 Name string 489 PageSize int 490 RepositoryFn func() *automock.TombstoneRepository 491 ExpectedResult []*model.Tombstone 492 ExpectedErrMessage string 493 }{ 494 { 495 Name: "Success", 496 RepositoryFn: func() *automock.TombstoneRepository { 497 repo := &automock.TombstoneRepository{} 498 repo.On("ListByResourceID", ctx, tenantID, appID, resource.Application).Return(tombstones, nil).Once() 499 return repo 500 }, 501 PageSize: 2, 502 ExpectedResult: tombstones, 503 ExpectedErrMessage: "", 504 }, 505 { 506 Name: "Returns error when Tombstone listing failed", 507 RepositoryFn: func() *automock.TombstoneRepository { 508 repo := &automock.TombstoneRepository{} 509 repo.On("ListByResourceID", ctx, tenantID, appID, resource.Application).Return(nil, testErr).Once() 510 return repo 511 }, 512 PageSize: 2, 513 ExpectedResult: nil, 514 ExpectedErrMessage: testErr.Error(), 515 }, 516 } 517 518 for _, testCase := range testCases { 519 t.Run(testCase.Name, func(t *testing.T) { 520 repo := testCase.RepositoryFn() 521 522 svc := tombstone.NewService(repo, nil) 523 524 // WHEN 525 docs, err := svc.ListByApplicationID(ctx, appID) 526 527 // then 528 if testCase.ExpectedErrMessage == "" { 529 require.NoError(t, err) 530 assert.Equal(t, testCase.ExpectedResult, docs) 531 } else { 532 require.Error(t, err) 533 assert.Contains(t, err.Error(), testCase.ExpectedErrMessage) 534 } 535 536 repo.AssertExpectations(t) 537 }) 538 } 539 t.Run("Error when tenant not in context", func(t *testing.T) { 540 svc := tombstone.NewService(nil, nil) 541 // WHEN 542 _, err := svc.ListByApplicationID(context.TODO(), "") 543 // THEN 544 require.Error(t, err) 545 assert.Contains(t, err.Error(), "cannot read tenant from context") 546 }) 547 } 548 549 func fixUIDService() *automock.UIDService { 550 svc := &automock.UIDService{} 551 svc.On("Generate").Return(tombstoneID).Once() 552 return svc 553 }