github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/application/resolver_test.go (about) 1 package application_test 2 3 import ( 4 "context" 5 "fmt" 6 "testing" 7 "time" 8 9 "github.com/kyma-incubator/compass/components/director/internal/domain/scenarioassignment" 10 "github.com/kyma-incubator/compass/components/director/pkg/consumer" 11 "github.com/kyma-incubator/compass/components/hydrator/pkg/oathkeeper" 12 13 pkgmodel "github.com/kyma-incubator/compass/components/director/pkg/model" 14 15 dataloader "github.com/kyma-incubator/compass/components/director/internal/dataloaders" 16 "github.com/kyma-incubator/compass/components/director/internal/tokens" 17 18 "github.com/kyma-incubator/compass/components/director/pkg/resource" 19 20 "github.com/kyma-incubator/compass/components/director/pkg/str" 21 22 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 23 24 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 25 "github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest" 26 27 "github.com/google/uuid" 28 "github.com/kyma-incubator/compass/components/director/internal/domain/application" 29 "github.com/kyma-incubator/compass/components/director/internal/domain/application/automock" 30 "github.com/kyma-incubator/compass/components/director/internal/labelfilter" 31 "github.com/kyma-incubator/compass/components/director/internal/model" 32 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 33 persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock" 34 "github.com/pkg/errors" 35 "github.com/stretchr/testify/assert" 36 "github.com/stretchr/testify/mock" 37 "github.com/stretchr/testify/require" 38 ) 39 40 var contextParam = txtest.CtxWithDBMatcher() 41 42 func TestResolver_RegisterApplication(t *testing.T) { 43 // GIVEN 44 modelApplication := fixModelApplication("foo", "tenant-foo", "Foo", "Lorem ipsum") 45 gqlApplication := fixGQLApplication("foo", "Foo", "Lorem ipsum") 46 testErr := errors.New("Test error") 47 48 desc := "Lorem ipsum" 49 gqlInput := graphql.ApplicationRegisterInput{ 50 Name: "Foo", 51 Description: &desc, 52 } 53 modelInput := model.ApplicationRegisterInput{ 54 Name: "Foo", 55 Description: &desc, 56 } 57 58 modelInputWithLabel := model.ApplicationRegisterInput{ 59 Name: modelInput.Name, 60 Description: modelInput.Description, 61 Labels: map[string]interface{}{"managed": "false"}, 62 } 63 txGen := txtest.NewTransactionContextGenerator(testErr) 64 65 testCases := []struct { 66 Name string 67 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 68 ServiceFn func() *automock.ApplicationService 69 ConverterFn func() *automock.ApplicationConverter 70 Input graphql.ApplicationRegisterInput 71 ExpectedApplication *graphql.Application 72 ExpectedErr error 73 }{ 74 { 75 Name: "Success", 76 TransactionerFn: txGen.ThatDoesntStartTransaction, 77 ServiceFn: func() *automock.ApplicationService { 78 svc := &automock.ApplicationService{} 79 svc.On("Get", context.TODO(), "foo").Return(modelApplication, nil).Once() 80 svc.On("Create", context.TODO(), modelInputWithLabel).Return("foo", nil).Once() 81 return svc 82 }, 83 ConverterFn: func() *automock.ApplicationConverter { 84 conv := &automock.ApplicationConverter{} 85 conv.On("CreateInputFromGraphQL", mock.Anything, gqlInput).Return(modelInput, nil).Once() 86 conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once() 87 return conv 88 }, 89 Input: gqlInput, 90 ExpectedApplication: gqlApplication, 91 ExpectedErr: nil, 92 }, 93 { 94 Name: "Returns error when application creation failed", 95 TransactionerFn: txGen.ThatDoesntStartTransaction, 96 ServiceFn: func() *automock.ApplicationService { 97 svc := &automock.ApplicationService{} 98 svc.On("Create", context.TODO(), modelInputWithLabel).Return("", testErr).Once() 99 return svc 100 }, 101 ConverterFn: func() *automock.ApplicationConverter { 102 conv := &automock.ApplicationConverter{} 103 conv.On("CreateInputFromGraphQL", mock.Anything, gqlInput).Return(modelInput, nil).Once() 104 return conv 105 }, 106 Input: gqlInput, 107 ExpectedApplication: nil, 108 ExpectedErr: testErr, 109 }, 110 { 111 Name: "Returns error when application fetch failed", 112 TransactionerFn: txGen.ThatDoesntStartTransaction, 113 ServiceFn: func() *automock.ApplicationService { 114 svc := &automock.ApplicationService{} 115 svc.On("Create", context.TODO(), modelInputWithLabel).Return("foo", nil).Once() 116 svc.On("Get", context.TODO(), "foo").Return(nil, testErr).Once() 117 return svc 118 }, 119 ConverterFn: func() *automock.ApplicationConverter { 120 conv := &automock.ApplicationConverter{} 121 conv.On("CreateInputFromGraphQL", mock.Anything, gqlInput).Return(modelInput, nil).Once() 122 return conv 123 }, 124 Input: gqlInput, 125 ExpectedApplication: nil, 126 ExpectedErr: testErr, 127 }, 128 } 129 130 for _, testCase := range testCases { 131 t.Run(testCase.Name, func(t *testing.T) { 132 persistTx, transact := testCase.TransactionerFn() 133 svc := testCase.ServiceFn() 134 converter := testCase.ConverterFn() 135 resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 136 resolver.SetConverter(converter) 137 138 // WHEN 139 result, err := resolver.RegisterApplication(context.TODO(), testCase.Input) 140 141 // then 142 assert.Equal(t, testCase.ExpectedApplication, result) 143 assert.Equal(t, testCase.ExpectedErr, err) 144 145 svc.AssertExpectations(t) 146 converter.AssertExpectations(t) 147 transact.AssertExpectations(t) 148 persistTx.AssertExpectations(t) 149 }) 150 } 151 } 152 153 func TestResolver_UpdateApplication(t *testing.T) { 154 // GIVEN 155 modelApplication := fixModelApplication("foo", "tenant-foo", "Foo", "Lorem ipsum") 156 gqlApplication := fixGQLApplication("foo", "Foo", "Lorem ipsum") 157 testErr := errors.New("Test error") 158 159 desc := "Lorem ipsum" 160 gqlInput := graphql.ApplicationUpdateInput{ 161 Description: &desc, 162 } 163 modelInput := model.ApplicationUpdateInput{ 164 Description: &desc, 165 } 166 applicationID := "foo" 167 168 txGen := txtest.NewTransactionContextGenerator(testErr) 169 170 testCases := []struct { 171 Name string 172 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 173 ServiceFn func() *automock.ApplicationService 174 ConverterFn func() *automock.ApplicationConverter 175 ApplicationID string 176 Input graphql.ApplicationUpdateInput 177 ExpectedApplication *graphql.Application 178 ExpectedErr error 179 }{ 180 { 181 Name: "Success", 182 TransactionerFn: txGen.ThatDoesntStartTransaction, 183 ServiceFn: func() *automock.ApplicationService { 184 svc := &automock.ApplicationService{} 185 svc.On("Get", context.TODO(), "foo").Return(modelApplication, nil).Once() 186 svc.On("Update", context.TODO(), applicationID, modelInput).Return(nil).Once() 187 return svc 188 }, 189 ConverterFn: func() *automock.ApplicationConverter { 190 conv := &automock.ApplicationConverter{} 191 conv.On("UpdateInputFromGraphQL", gqlInput).Return(modelInput).Once() 192 conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once() 193 return conv 194 }, 195 ApplicationID: applicationID, 196 Input: gqlInput, 197 ExpectedApplication: gqlApplication, 198 ExpectedErr: nil, 199 }, 200 { 201 Name: "Returns error when application update failed", 202 TransactionerFn: txGen.ThatDoesntStartTransaction, 203 ServiceFn: func() *automock.ApplicationService { 204 svc := &automock.ApplicationService{} 205 svc.On("Update", context.TODO(), applicationID, modelInput).Return(testErr).Once() 206 return svc 207 }, 208 ConverterFn: func() *automock.ApplicationConverter { 209 conv := &automock.ApplicationConverter{} 210 conv.On("UpdateInputFromGraphQL", gqlInput).Return(modelInput).Once() 211 return conv 212 }, 213 ApplicationID: applicationID, 214 Input: gqlInput, 215 ExpectedApplication: nil, 216 ExpectedErr: testErr, 217 }, 218 { 219 Name: "Returns error when application retrieval failed", 220 TransactionerFn: txGen.ThatDoesntStartTransaction, 221 ServiceFn: func() *automock.ApplicationService { 222 svc := &automock.ApplicationService{} 223 svc.On("Update", context.TODO(), applicationID, modelInput).Return(nil).Once() 224 svc.On("Get", context.TODO(), "foo").Return(nil, testErr).Once() 225 return svc 226 }, 227 ConverterFn: func() *automock.ApplicationConverter { 228 conv := &automock.ApplicationConverter{} 229 conv.On("UpdateInputFromGraphQL", gqlInput).Return(modelInput).Once() 230 return conv 231 }, 232 ApplicationID: applicationID, 233 Input: gqlInput, 234 ExpectedApplication: nil, 235 ExpectedErr: testErr, 236 }, 237 } 238 239 for _, testCase := range testCases { 240 t.Run(testCase.Name, func(t *testing.T) { 241 persistTx, transact := testCase.TransactionerFn() 242 svc := testCase.ServiceFn() 243 converter := testCase.ConverterFn() 244 245 resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 246 resolver.SetConverter(converter) 247 248 // WHEN 249 result, err := resolver.UpdateApplication(context.TODO(), testCase.ApplicationID, testCase.Input) 250 251 // then 252 assert.Equal(t, testCase.ExpectedApplication, result) 253 assert.Equal(t, testCase.ExpectedErr, err) 254 255 svc.AssertExpectations(t) 256 converter.AssertExpectations(t) 257 transact.AssertExpectations(t) 258 persistTx.AssertExpectations(t) 259 }) 260 } 261 } 262 263 func TestResolver_UnregisterApplication(t *testing.T) { 264 // GIVEN 265 appID := uuid.New() 266 modelApplication := fixModelApplication(appID.String(), "tenant-foo", "Foo", "Bar") 267 gqlApplication := fixGQLApplication(appID.String(), "Foo", "Bar") 268 testErr := errors.New("Test error") 269 testAuths := fixOAuths() 270 txGen := txtest.NewTransactionContextGenerator(testErr) 271 272 testCases := []struct { 273 Name string 274 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 275 ServiceFn func() *automock.ApplicationService 276 ConverterFn func() *automock.ApplicationConverter 277 EventingSvcFn func() *automock.EventingService 278 SysAuthServiceFn func() *automock.SystemAuthService 279 OAuth20ServiceFn func() *automock.OAuth20Service 280 InputID string 281 ExpectedApplication *graphql.Application 282 ExpectedErr error 283 }{ 284 { 285 Name: "Success", 286 TransactionerFn: txGen.ThatDoesntStartTransaction, 287 ServiceFn: func() *automock.ApplicationService { 288 svc := &automock.ApplicationService{} 289 svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once() 290 svc.On("Delete", context.TODO(), appID.String()).Return(nil).Once() 291 return svc 292 }, 293 ConverterFn: func() *automock.ApplicationConverter { 294 conv := &automock.ApplicationConverter{} 295 conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once() 296 return conv 297 }, 298 EventingSvcFn: func() *automock.EventingService { 299 svc := &automock.EventingService{} 300 svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, nil).Once() 301 return svc 302 }, 303 SysAuthServiceFn: func() *automock.SystemAuthService { 304 svc := &automock.SystemAuthService{} 305 svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil) 306 return svc 307 }, 308 OAuth20ServiceFn: func() *automock.OAuth20Service { 309 svc := &automock.OAuth20Service{} 310 svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(nil) 311 return svc 312 }, 313 InputID: appID.String(), 314 ExpectedApplication: gqlApplication, 315 ExpectedErr: nil, 316 }, 317 { 318 Name: "Returns error when application deletion failed", 319 TransactionerFn: txGen.ThatDoesntStartTransaction, 320 ServiceFn: func() *automock.ApplicationService { 321 svc := &automock.ApplicationService{} 322 svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once() 323 svc.On("Delete", context.TODO(), appID.String()).Return(testErr).Once() 324 return svc 325 }, 326 ConverterFn: func() *automock.ApplicationConverter { 327 conv := &automock.ApplicationConverter{} 328 return conv 329 }, 330 EventingSvcFn: func() *automock.EventingService { 331 svc := &automock.EventingService{} 332 svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, nil).Once() 333 return svc 334 }, 335 SysAuthServiceFn: func() *automock.SystemAuthService { 336 svc := &automock.SystemAuthService{} 337 svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil) 338 return svc 339 }, 340 OAuth20ServiceFn: func() *automock.OAuth20Service { 341 svc := &automock.OAuth20Service{} 342 svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(nil) 343 344 return svc 345 }, 346 InputID: appID.String(), 347 ExpectedApplication: nil, 348 ExpectedErr: testErr, 349 }, 350 { 351 Name: "Returns error when application retrieval failed", 352 TransactionerFn: txGen.ThatDoesntStartTransaction, 353 ServiceFn: func() *automock.ApplicationService { 354 svc := &automock.ApplicationService{} 355 svc.On("Get", context.TODO(), appID.String()).Return(nil, testErr).Once() 356 return svc 357 }, 358 ConverterFn: func() *automock.ApplicationConverter { 359 conv := &automock.ApplicationConverter{} 360 return conv 361 }, 362 EventingSvcFn: func() *automock.EventingService { 363 svc := &automock.EventingService{} 364 return svc 365 }, 366 SysAuthServiceFn: func() *automock.SystemAuthService { 367 svc := &automock.SystemAuthService{} 368 return svc 369 }, 370 OAuth20ServiceFn: func() *automock.OAuth20Service { 371 svc := &automock.OAuth20Service{} 372 return svc 373 }, 374 InputID: appID.String(), 375 ExpectedApplication: nil, 376 ExpectedErr: testErr, 377 }, 378 { 379 Name: "Return error when listing all auths failed", 380 TransactionerFn: txGen.ThatDoesntStartTransaction, 381 ServiceFn: func() *automock.ApplicationService { 382 svc := &automock.ApplicationService{} 383 svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once() 384 return svc 385 }, 386 ConverterFn: func() *automock.ApplicationConverter { 387 conv := &automock.ApplicationConverter{} 388 return conv 389 }, 390 EventingSvcFn: func() *automock.EventingService { 391 svc := &automock.EventingService{} 392 svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, nil).Once() 393 return svc 394 }, 395 SysAuthServiceFn: func() *automock.SystemAuthService { 396 svc := &automock.SystemAuthService{} 397 svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(nil, testErr) 398 return svc 399 }, 400 OAuth20ServiceFn: func() *automock.OAuth20Service { 401 svc := &automock.OAuth20Service{} 402 return svc 403 }, 404 InputID: appID.String(), 405 ExpectedApplication: nil, 406 ExpectedErr: testErr, 407 }, 408 { 409 Name: "Return error when removing oauth from hydra", 410 TransactionerFn: txGen.ThatDoesntStartTransaction, 411 ServiceFn: func() *automock.ApplicationService { 412 svc := &automock.ApplicationService{} 413 svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once() 414 return svc 415 }, 416 ConverterFn: func() *automock.ApplicationConverter { 417 conv := &automock.ApplicationConverter{} 418 return conv 419 }, 420 EventingSvcFn: func() *automock.EventingService { 421 svc := &automock.EventingService{} 422 svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, nil).Once() 423 return svc 424 }, 425 SysAuthServiceFn: func() *automock.SystemAuthService { 426 svc := &automock.SystemAuthService{} 427 svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil) 428 return svc 429 }, 430 OAuth20ServiceFn: func() *automock.OAuth20Service { 431 svc := &automock.OAuth20Service{} 432 svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(testErr) 433 return svc 434 }, 435 InputID: appID.String(), 436 ExpectedApplication: nil, 437 ExpectedErr: testErr, 438 }, { 439 Name: "Returns error when removing default eventing labels", 440 TransactionerFn: txGen.ThatDoesntStartTransaction, 441 ServiceFn: func() *automock.ApplicationService { 442 svc := &automock.ApplicationService{} 443 svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once() 444 return svc 445 }, 446 ConverterFn: func() *automock.ApplicationConverter { 447 conv := &automock.ApplicationConverter{} 448 return conv 449 }, 450 EventingSvcFn: func() *automock.EventingService { 451 svc := &automock.EventingService{} 452 svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, testErr).Once() 453 return svc 454 }, 455 SysAuthServiceFn: func() *automock.SystemAuthService { 456 svc := &automock.SystemAuthService{} 457 return svc 458 }, 459 OAuth20ServiceFn: func() *automock.OAuth20Service { 460 svc := &automock.OAuth20Service{} 461 return svc 462 }, 463 InputID: appID.String(), 464 ExpectedApplication: nil, 465 ExpectedErr: testErr, 466 }, 467 } 468 469 for _, testCase := range testCases { 470 t.Run(testCase.Name, func(t *testing.T) { 471 svc := testCase.ServiceFn() 472 converter := testCase.ConverterFn() 473 eventingSvc := testCase.EventingSvcFn() 474 persistTx, transact := testCase.TransactionerFn() 475 sysAuthSvc := testCase.SysAuthServiceFn() 476 oAuth20Svc := testCase.OAuth20ServiceFn() 477 resolver := application.NewResolver(transact, svc, nil, oAuth20Svc, sysAuthSvc, nil, nil, nil, eventingSvc, nil, nil, nil, nil, nil, nil, "", "") 478 resolver.SetConverter(converter) 479 480 // WHEN 481 result, err := resolver.UnregisterApplication(context.TODO(), testCase.InputID) 482 483 // then 484 assert.Equal(t, testCase.ExpectedApplication, result) 485 if testCase.ExpectedErr != nil { 486 assert.EqualError(t, testCase.ExpectedErr, err.Error()) 487 } else { 488 assert.NoError(t, err) 489 } 490 491 mock.AssertExpectationsForObjects(t, svc, converter, persistTx, transact, sysAuthSvc, oAuth20Svc, eventingSvc) 492 }) 493 } 494 } 495 496 func TestResolver_UnpairApplication(t *testing.T) { 497 // GIVEN 498 appID := uuid.New() 499 modelApplication := fixModelApplication(appID.String(), "tenant-foo", "Foo", "Bar") 500 gqlApplication := fixGQLApplication(appID.String(), "Foo", "Bar") 501 testErr := errors.New("Test error") 502 testAuths := fixOAuths() 503 txGen := txtest.NewTransactionContextGenerator(testErr) 504 505 testCases := []struct { 506 Name string 507 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 508 ServiceFn func() *automock.ApplicationService 509 ConverterFn func() *automock.ApplicationConverter 510 EventingSvcFn func() *automock.EventingService 511 SysAuthServiceFn func() *automock.SystemAuthService 512 OAuth20ServiceFn func() *automock.OAuth20Service 513 InputID string 514 ExpectedApplication *graphql.Application 515 ExpectedErr error 516 }{ 517 { 518 Name: "Success", 519 TransactionerFn: txGen.ThatDoesntStartTransaction, 520 ServiceFn: func() *automock.ApplicationService { 521 svc := &automock.ApplicationService{} 522 svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once() 523 svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once() 524 return svc 525 }, 526 ConverterFn: func() *automock.ApplicationConverter { 527 conv := &automock.ApplicationConverter{} 528 conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once() 529 return conv 530 }, 531 SysAuthServiceFn: func() *automock.SystemAuthService { 532 svc := &automock.SystemAuthService{} 533 svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil).Once() 534 svc.On("DeleteMultipleByIDForObject", context.TODO(), testAuths).Return(nil).Once() 535 return svc 536 }, 537 OAuth20ServiceFn: func() *automock.OAuth20Service { 538 svc := &automock.OAuth20Service{} 539 svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(nil).Once() 540 return svc 541 }, 542 InputID: appID.String(), 543 ExpectedApplication: gqlApplication, 544 ExpectedErr: nil, 545 }, 546 { 547 Name: "Returns error when application unpairing failed", 548 TransactionerFn: txGen.ThatDoesntStartTransaction, 549 ServiceFn: func() *automock.ApplicationService { 550 svc := &automock.ApplicationService{} 551 svc.AssertNotCalled(t, "Get") 552 svc.On("Unpair", context.TODO(), appID.String()).Return(testErr).Once() 553 return svc 554 }, 555 ConverterFn: func() *automock.ApplicationConverter { 556 conv := &automock.ApplicationConverter{} 557 return conv 558 }, 559 SysAuthServiceFn: func() *automock.SystemAuthService { 560 svc := &automock.SystemAuthService{} 561 svc.AssertNotCalled(t, "DeleteMultipleByIDForObject") 562 svc.AssertNotCalled(t, "ListForObject") 563 return svc 564 }, 565 OAuth20ServiceFn: func() *automock.OAuth20Service { 566 svc := &automock.OAuth20Service{} 567 svc.AssertNotCalled(t, "DeleteMultipleClientCredentials") 568 569 return svc 570 }, 571 InputID: appID.String(), 572 ExpectedApplication: nil, 573 ExpectedErr: testErr, 574 }, 575 { 576 Name: "Returns error when application retrieval failed", 577 TransactionerFn: txGen.ThatDoesntStartTransaction, 578 ServiceFn: func() *automock.ApplicationService { 579 svc := &automock.ApplicationService{} 580 svc.On("Get", context.TODO(), appID.String()).Return(nil, testErr).Once() 581 svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once() 582 return svc 583 }, 584 ConverterFn: func() *automock.ApplicationConverter { 585 conv := &automock.ApplicationConverter{} 586 return conv 587 }, 588 SysAuthServiceFn: func() *automock.SystemAuthService { 589 svc := &automock.SystemAuthService{} 590 svc.AssertNotCalled(t, "DeleteMultipleByIDForObject") 591 svc.AssertNotCalled(t, "ListForObject") 592 return svc 593 }, 594 OAuth20ServiceFn: func() *automock.OAuth20Service { 595 svc := &automock.OAuth20Service{} 596 svc.AssertNotCalled(t, "DeleteMultipleClientCredentials") 597 return svc 598 }, 599 InputID: appID.String(), 600 ExpectedApplication: nil, 601 ExpectedErr: testErr, 602 }, 603 { 604 Name: "Return error when listing all auths failed", 605 TransactionerFn: txGen.ThatDoesntStartTransaction, 606 ServiceFn: func() *automock.ApplicationService { 607 svc := &automock.ApplicationService{} 608 svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once() 609 svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once() 610 return svc 611 }, 612 ConverterFn: func() *automock.ApplicationConverter { 613 conv := &automock.ApplicationConverter{} 614 conv.AssertNotCalled(t, "ToGraphQL") 615 return conv 616 }, 617 SysAuthServiceFn: func() *automock.SystemAuthService { 618 svc := &automock.SystemAuthService{} 619 svc.AssertNotCalled(t, "DeleteMultipleClientCredentials") 620 svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(nil, testErr) 621 return svc 622 }, 623 OAuth20ServiceFn: func() *automock.OAuth20Service { 624 svc := &automock.OAuth20Service{} 625 svc.AssertNotCalled(t, "DeleteMultipleClientCredentials") 626 return svc 627 }, 628 InputID: appID.String(), 629 ExpectedApplication: nil, 630 ExpectedErr: testErr, 631 }, 632 { 633 Name: "Return error when removing oauth from hydra", 634 TransactionerFn: txGen.ThatDoesntStartTransaction, 635 ServiceFn: func() *automock.ApplicationService { 636 svc := &automock.ApplicationService{} 637 svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once() 638 svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once() 639 640 return svc 641 }, 642 ConverterFn: func() *automock.ApplicationConverter { 643 conv := &automock.ApplicationConverter{} 644 conv.AssertNotCalled(t, "ToGraphQL") 645 646 return conv 647 }, 648 SysAuthServiceFn: func() *automock.SystemAuthService { 649 svc := &automock.SystemAuthService{} 650 svc.On("DeleteMultipleByIDForObject", context.TODO(), testAuths).Return(nil).Once() 651 svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil) 652 return svc 653 }, 654 OAuth20ServiceFn: func() *automock.OAuth20Service { 655 svc := &automock.OAuth20Service{} 656 svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(testErr) 657 return svc 658 }, 659 InputID: appID.String(), 660 ExpectedApplication: nil, 661 ExpectedErr: testErr, 662 }, 663 { 664 Name: "Return error when removing system auths", 665 TransactionerFn: txGen.ThatDoesntStartTransaction, 666 ServiceFn: func() *automock.ApplicationService { 667 svc := &automock.ApplicationService{} 668 svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once() 669 svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once() 670 return svc 671 }, 672 ConverterFn: func() *automock.ApplicationConverter { 673 conv := &automock.ApplicationConverter{} 674 conv.AssertNotCalled(t, "ToGraphQL") 675 return conv 676 }, 677 SysAuthServiceFn: func() *automock.SystemAuthService { 678 svc := &automock.SystemAuthService{} 679 svc.On("DeleteMultipleByIDForObject", context.TODO(), testAuths).Return(testErr).Once() 680 svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil) 681 return svc 682 }, 683 OAuth20ServiceFn: func() *automock.OAuth20Service { 684 svc := &automock.OAuth20Service{} 685 svc.AssertNotCalled(t, "DeleteMultipleClientCredentials") 686 return svc 687 }, 688 InputID: appID.String(), 689 ExpectedApplication: nil, 690 ExpectedErr: testErr, 691 }, 692 } 693 694 for _, testCase := range testCases { 695 t.Run(testCase.Name, func(t *testing.T) { 696 svc := testCase.ServiceFn() 697 converter := testCase.ConverterFn() 698 persistTx, transact := testCase.TransactionerFn() 699 sysAuthSvc := testCase.SysAuthServiceFn() 700 oAuth20Svc := testCase.OAuth20ServiceFn() 701 resolver := application.NewResolver(transact, svc, nil, oAuth20Svc, sysAuthSvc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 702 resolver.SetConverter(converter) 703 704 // WHEN 705 result, err := resolver.UnpairApplication(context.TODO(), testCase.InputID) 706 707 // then 708 assert.Equal(t, testCase.ExpectedApplication, result) 709 if testCase.ExpectedErr != nil { 710 assert.EqualError(t, testCase.ExpectedErr, err.Error()) 711 } else { 712 assert.NoError(t, err) 713 } 714 715 mock.AssertExpectationsForObjects(t, svc, converter, persistTx, transact, sysAuthSvc, oAuth20Svc) 716 }) 717 } 718 } 719 720 func TestResolver_MergeApplications(t *testing.T) { 721 // GIVEN 722 srcAppID := "srcID" 723 destAppID := "destID" 724 725 modelApplication := fixModelApplication(destAppID, "tenant-foo", "Foo", "Lorem ipsum") 726 gqlApplication := fixGQLApplication(destAppID, "Foo", "Lorem ipsum") 727 728 testErr := errors.New("Test error") 729 730 testCases := []struct { 731 Name string 732 PersistenceFn func() *persistenceautomock.PersistenceTx 733 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 734 ServiceFn func() *automock.ApplicationService 735 ApplicationConverterFn func() *automock.ApplicationConverter 736 ExpectedResult *graphql.Application 737 ExpectedErr error 738 }{ 739 { 740 Name: "Success", 741 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 742 TransactionerFn: txtest.TransactionerThatSucceeds, 743 ApplicationConverterFn: func() *automock.ApplicationConverter { 744 conv := &automock.ApplicationConverter{} 745 conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once() 746 747 return conv 748 }, 749 ServiceFn: func() *automock.ApplicationService { 750 svc := &automock.ApplicationService{} 751 svc.On("Merge", txtest.CtxWithDBMatcher(), destAppID, srcAppID).Return(modelApplication, nil).Once() 752 753 return svc 754 }, 755 ExpectedResult: gqlApplication, 756 ExpectedErr: nil, 757 }, 758 { 759 Name: "Returns error when webhook conversion to graphql fails", 760 TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner { 761 transact := &persistenceautomock.Transactioner{} 762 transact.On("Begin").Return(nil, testErr).Once() 763 return transact 764 }, 765 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 766 ApplicationConverterFn: func() *automock.ApplicationConverter { 767 conv := &automock.ApplicationConverter{} 768 conv.AssertNotCalled(t, "ToGraphQL") 769 770 return conv 771 }, 772 ServiceFn: func() *automock.ApplicationService { 773 svc := &automock.ApplicationService{} 774 svc.AssertNotCalled(t, "Merge") 775 776 return svc 777 }, 778 ExpectedResult: nil, 779 ExpectedErr: testErr, 780 }, 781 { 782 Name: "Returns error on committing transaction", 783 PersistenceFn: func() *persistenceautomock.PersistenceTx { 784 persistTx := &persistenceautomock.PersistenceTx{} 785 persistTx.On("Commit").Return(testErr).Once() 786 return persistTx 787 }, 788 TransactionerFn: txtest.TransactionerThatSucceeds, 789 ApplicationConverterFn: func() *automock.ApplicationConverter { 790 conv := &automock.ApplicationConverter{} 791 conv.AssertNotCalled(t, "ToGraphQL") 792 793 return conv 794 }, 795 ServiceFn: func() *automock.ApplicationService { 796 svc := &automock.ApplicationService{} 797 svc.On("Merge", txtest.CtxWithDBMatcher(), destAppID, srcAppID).Return(modelApplication, nil).Once() 798 799 return svc 800 }, 801 ExpectedErr: testErr, 802 }, 803 { 804 Name: "Returns error then Merge fails", 805 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 806 ApplicationConverterFn: func() *automock.ApplicationConverter { 807 conv := &automock.ApplicationConverter{} 808 conv.AssertNotCalled(t, "ToGraphQL") 809 810 return conv 811 }, 812 ServiceFn: func() *automock.ApplicationService { 813 svc := &automock.ApplicationService{} 814 svc.On("Merge", txtest.CtxWithDBMatcher(), destAppID, srcAppID).Return(nil, testErr).Once() 815 816 return svc 817 }, 818 TransactionerFn: txtest.TransactionerThatSucceeds, 819 ExpectedResult: nil, 820 ExpectedErr: testErr, 821 }, 822 } 823 824 for _, testCase := range testCases { 825 t.Run(testCase.Name, func(t *testing.T) { 826 svc := testCase.ServiceFn() 827 converter := testCase.ApplicationConverterFn() 828 829 mockPersistence := testCase.PersistenceFn() 830 mockTransactioner := testCase.TransactionerFn(mockPersistence) 831 832 resolver := application.NewResolver(mockTransactioner, svc, nil, nil, nil, converter, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 833 834 // WHEN 835 result, err := resolver.MergeApplications(context.TODO(), destAppID, srcAppID) 836 837 // then 838 assert.Equal(t, testCase.ExpectedResult, result) 839 assert.Equal(t, testCase.ExpectedErr, err) 840 841 svc.AssertExpectations(t) 842 mockPersistence.AssertExpectations(t) 843 mockTransactioner.AssertExpectations(t) 844 }) 845 } 846 } 847 848 func TestResolver_ApplicationBySystemNumber(t *testing.T) { 849 // GIVEN 850 systemNumber := "18" 851 modelApplication := fixModelApplication("foo", "tenant-foo", appName, "Bar") 852 gqlApplication := fixGQLApplication("foo", appName, "Bar") 853 testErr := errors.New("Test error") 854 855 testCases := []struct { 856 Name string 857 PersistenceFn func() *persistenceautomock.PersistenceTx 858 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 859 ServiceFn func() *automock.ApplicationService 860 ConverterFn func() *automock.ApplicationConverter 861 SystemNumber string 862 ExpectedApplication *graphql.Application 863 ExpectedErr error 864 }{ 865 { 866 Name: "Success", 867 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 868 TransactionerFn: txtest.TransactionerThatSucceeds, 869 ServiceFn: func() *automock.ApplicationService { 870 svc := &automock.ApplicationService{} 871 svc.On("GetBySystemNumber", contextParam, systemNumber).Return(modelApplication, nil).Once() 872 873 return svc 874 }, 875 ConverterFn: func() *automock.ApplicationConverter { 876 conv := &automock.ApplicationConverter{} 877 conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once() 878 return conv 879 }, 880 SystemNumber: systemNumber, 881 ExpectedApplication: gqlApplication, 882 }, 883 { 884 Name: "GetBySystemNumber returns NotFound error", 885 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 886 TransactionerFn: txtest.TransactionerThatSucceeds, 887 ServiceFn: func() *automock.ApplicationService { 888 svc := &automock.ApplicationService{} 889 svc.On("GetBySystemNumber", contextParam, systemNumber).Return(nil, apperrors.NewNotFoundError(resource.Application, "foo")).Once() 890 return svc 891 }, 892 ConverterFn: func() *automock.ApplicationConverter { 893 conv := &automock.ApplicationConverter{} 894 conv.AssertNotCalled(t, "ToGraphQL") 895 return conv 896 }, 897 SystemNumber: systemNumber, 898 ExpectedApplication: nil, 899 ExpectedErr: nil, 900 }, 901 { 902 Name: "GetBySystemNumber returns error", 903 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 904 TransactionerFn: txtest.TransactionerThatSucceeds, 905 ServiceFn: func() *automock.ApplicationService { 906 svc := &automock.ApplicationService{} 907 svc.On("GetBySystemNumber", contextParam, systemNumber).Return(nil, testErr).Once() 908 return svc 909 }, 910 ConverterFn: func() *automock.ApplicationConverter { 911 conv := &automock.ApplicationConverter{} 912 conv.AssertNotCalled(t, "ToGraphQL") 913 return conv 914 }, 915 SystemNumber: systemNumber, 916 ExpectedApplication: nil, 917 ExpectedErr: testErr, 918 }, 919 { 920 Name: "Returns error when starting transaction failed", 921 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 922 ServiceFn: func() *automock.ApplicationService { 923 appSvc := &automock.ApplicationService{} 924 return appSvc 925 }, 926 ConverterFn: func() *automock.ApplicationConverter { 927 conv := &automock.ApplicationConverter{} 928 conv.AssertNotCalled(t, "ToGraphQL") 929 return conv 930 }, 931 TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner { 932 transact := &persistenceautomock.Transactioner{} 933 transact.On("Begin").Return(nil, testErr).Once() 934 return transact 935 }, 936 SystemNumber: systemNumber, 937 ExpectedApplication: nil, 938 ExpectedErr: testErr, 939 }, 940 { 941 Name: "Returns error when transaction commit failed", 942 PersistenceFn: func() *persistenceautomock.PersistenceTx { 943 persistTx := &persistenceautomock.PersistenceTx{} 944 persistTx.On("Commit").Return(testErr).Once() 945 return persistTx 946 }, 947 ServiceFn: func() *automock.ApplicationService { 948 svc := &automock.ApplicationService{} 949 svc.On("GetBySystemNumber", contextParam, systemNumber).Return(modelApplication, nil).Once() 950 return svc 951 }, 952 ConverterFn: func() *automock.ApplicationConverter { 953 conv := &automock.ApplicationConverter{} 954 conv.AssertNotCalled(t, "ToGraphQL") 955 return conv 956 }, 957 TransactionerFn: txtest.TransactionerThatSucceeds, 958 SystemNumber: systemNumber, 959 ExpectedApplication: nil, 960 ExpectedErr: testErr, 961 }, 962 } 963 964 for _, testCase := range testCases { 965 t.Run(testCase.Name, func(t *testing.T) { 966 persistTx := testCase.PersistenceFn() 967 transact := testCase.TransactionerFn(persistTx) 968 svc := testCase.ServiceFn() 969 converter := testCase.ConverterFn() 970 971 resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 972 resolver.SetConverter(converter) 973 974 // WHEN 975 result, err := resolver.ApplicationBySystemNumber(context.TODO(), testCase.SystemNumber) 976 977 // then 978 assert.Equal(t, testCase.ExpectedApplication, result) 979 assert.Equal(t, testCase.ExpectedErr, err) 980 981 svc.AssertExpectations(t) 982 converter.AssertExpectations(t) 983 }) 984 } 985 } 986 987 func TestResolver_Application(t *testing.T) { 988 // GIVEN 989 modelApplication := fixModelApplication("foo", "tenant-foo", "Foo", "Bar") 990 gqlApplication := fixGQLApplication("foo", "Foo", "Bar") 991 testErr := errors.New("Test error") 992 993 testCases := []struct { 994 Name string 995 PersistenceFn func() *persistenceautomock.PersistenceTx 996 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 997 ServiceFn func() *automock.ApplicationService 998 ConverterFn func() *automock.ApplicationConverter 999 InputID string 1000 ExpectedApplication *graphql.Application 1001 ExpectedErr error 1002 }{ 1003 { 1004 Name: "Success", 1005 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1006 TransactionerFn: txtest.TransactionerThatSucceeds, 1007 ServiceFn: func() *automock.ApplicationService { 1008 svc := &automock.ApplicationService{} 1009 svc.On("Get", contextParam, "foo").Return(modelApplication, nil).Once() 1010 1011 return svc 1012 }, 1013 ConverterFn: func() *automock.ApplicationConverter { 1014 conv := &automock.ApplicationConverter{} 1015 conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once() 1016 return conv 1017 }, 1018 InputID: "foo", 1019 ExpectedApplication: gqlApplication, 1020 ExpectedErr: nil, 1021 }, 1022 { 1023 Name: "Success returns nil when application not found", 1024 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1025 TransactionerFn: txtest.TransactionerThatSucceeds, 1026 ServiceFn: func() *automock.ApplicationService { 1027 svc := &automock.ApplicationService{} 1028 svc.On("Get", contextParam, "foo").Return(nil, apperrors.NewNotFoundError(resource.Application, "foo")).Once() 1029 1030 return svc 1031 }, 1032 ConverterFn: func() *automock.ApplicationConverter { 1033 conv := &automock.ApplicationConverter{} 1034 return conv 1035 }, 1036 InputID: "foo", 1037 ExpectedApplication: nil, 1038 ExpectedErr: nil, 1039 }, 1040 { 1041 Name: "Returns error when application retrieval failed", 1042 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1043 TransactionerFn: txtest.TransactionerThatSucceeds, 1044 ServiceFn: func() *automock.ApplicationService { 1045 svc := &automock.ApplicationService{} 1046 svc.On("Get", contextParam, "foo").Return(nil, testErr).Once() 1047 1048 return svc 1049 }, 1050 ConverterFn: func() *automock.ApplicationConverter { 1051 conv := &automock.ApplicationConverter{} 1052 return conv 1053 }, 1054 InputID: "foo", 1055 ExpectedApplication: nil, 1056 ExpectedErr: testErr, 1057 }, 1058 } 1059 1060 for _, testCase := range testCases { 1061 t.Run(testCase.Name, func(t *testing.T) { 1062 persistTx := testCase.PersistenceFn() 1063 transact := testCase.TransactionerFn(persistTx) 1064 svc := testCase.ServiceFn() 1065 converter := testCase.ConverterFn() 1066 1067 resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 1068 resolver.SetConverter(converter) 1069 1070 // WHEN 1071 result, err := resolver.Application(context.TODO(), testCase.InputID) 1072 1073 // then 1074 assert.Equal(t, testCase.ExpectedApplication, result) 1075 assert.Equal(t, testCase.ExpectedErr, err) 1076 1077 svc.AssertExpectations(t) 1078 converter.AssertExpectations(t) 1079 }) 1080 } 1081 } 1082 1083 func TestResolver_Applications(t *testing.T) { 1084 // GIVEN 1085 modelApplications := []*model.Application{ 1086 fixModelApplication("foo", "tenant-foo", "Foo", "Lorem Ipsum"), 1087 fixModelApplication("bar", "tenant-bar", "Bar", "Lorem Ipsum"), 1088 } 1089 1090 gqlApplications := []*graphql.Application{ 1091 fixGQLApplication("foo", "Foo", "Lorem Ipsum"), 1092 fixGQLApplication("bar", "Bar", "Lorem Ipsum"), 1093 } 1094 1095 first := 2 1096 gqlAfter := graphql.PageCursor("test") 1097 after := "test" 1098 query := "foo" 1099 filter := []*labelfilter.LabelFilter{ 1100 {Key: "", Query: &query}, 1101 } 1102 gqlFilter := []*graphql.LabelFilter{ 1103 {Key: "", Query: &query}, 1104 } 1105 testErr := errors.New("Test error") 1106 1107 testCases := []struct { 1108 Name string 1109 PersistenceFn func() *persistenceautomock.PersistenceTx 1110 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 1111 ServiceFn func() *automock.ApplicationService 1112 ConverterFn func() *automock.ApplicationConverter 1113 InputLabelFilters []*graphql.LabelFilter 1114 ExpectedResult *graphql.ApplicationPage 1115 ExpectedErr error 1116 }{ 1117 { 1118 Name: "Success", 1119 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1120 TransactionerFn: txtest.TransactionerThatSucceeds, 1121 ServiceFn: func() *automock.ApplicationService { 1122 svc := &automock.ApplicationService{} 1123 svc.On("List", contextParam, filter, first, after).Return(fixApplicationPage(modelApplications), nil).Once() 1124 return svc 1125 }, 1126 ConverterFn: func() *automock.ApplicationConverter { 1127 conv := &automock.ApplicationConverter{} 1128 conv.On("MultipleToGraphQL", modelApplications).Return(gqlApplications).Once() 1129 return conv 1130 }, 1131 InputLabelFilters: gqlFilter, 1132 ExpectedResult: fixGQLApplicationPage(gqlApplications), 1133 ExpectedErr: nil, 1134 }, 1135 { 1136 Name: "Returns error when application listing failed", 1137 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1138 TransactionerFn: txtest.TransactionerThatSucceeds, 1139 ServiceFn: func() *automock.ApplicationService { 1140 svc := &automock.ApplicationService{} 1141 svc.On("List", contextParam, filter, first, after).Return(nil, testErr).Once() 1142 return svc 1143 }, 1144 ConverterFn: func() *automock.ApplicationConverter { 1145 conv := &automock.ApplicationConverter{} 1146 return conv 1147 }, 1148 InputLabelFilters: gqlFilter, 1149 ExpectedResult: nil, 1150 ExpectedErr: testErr, 1151 }, 1152 } 1153 1154 for _, testCase := range testCases { 1155 t.Run(testCase.Name, func(t *testing.T) { 1156 persistTx := testCase.PersistenceFn() 1157 transact := testCase.TransactionerFn(persistTx) 1158 svc := testCase.ServiceFn() 1159 converter := testCase.ConverterFn() 1160 1161 resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 1162 resolver.SetConverter(converter) 1163 1164 // WHEN 1165 ctx := consumer.SaveToContext(context.TODO(), consumer.Consumer{ConsumerID: "testConsumerID"}) 1166 result, err := resolver.Applications(ctx, testCase.InputLabelFilters, &first, &gqlAfter) 1167 1168 // then 1169 assert.Equal(t, testCase.ExpectedErr, err) 1170 assert.Equal(t, testCase.ExpectedResult, result) 1171 1172 svc.AssertExpectations(t) 1173 converter.AssertExpectations(t) 1174 }) 1175 } 1176 } 1177 1178 func TestResolver_Applications_DoubleAuthFlow(t *testing.T) { 1179 // GIVEN 1180 appTemplateID := "12345678-ae7e-4d1a-8027-520a96d5319d" 1181 1182 modelApplication := fixModelApplication("foo", "tenant-foo", "Foo", "Bar") 1183 gqlApplication := fixGQLApplication("foo", "Foo", "Bar") 1184 1185 modelApplication.ApplicationTemplateID = &appTemplateID 1186 gqlApplication.ApplicationTemplateID = &appTemplateID 1187 1188 modelApplicationList := []*model.Application{ 1189 modelApplication, 1190 } 1191 modelApplicationListWithNoMatchingRecord := []*model.Application{ 1192 fixModelApplication("foo", "tenant-foo", "Foo", "Bar"), 1193 } 1194 1195 consumerID := "abcd1122-ae7e-4d1a-8027-520a96d5319d" 1196 onBehalfOf := "a9653128-gs3e-4d1a-8sdj-52a96dd5301d" 1197 region := "eu-1" 1198 tokenClientID := "sb-token-client-id" 1199 strippedTokenClientID := "token-client-id" 1200 selfRegisterDistinguishLabelKey := "test-distinguish-label-key" 1201 1202 certConsumer := consumer.Consumer{ 1203 ConsumerID: consumerID, 1204 ConsumerType: consumer.ExternalCertificate, 1205 Flow: oathkeeper.CertificateFlow, 1206 OnBehalfOf: onBehalfOf, 1207 Region: region, 1208 TokenClientID: tokenClientID, 1209 } 1210 ctxWithConsumerInfo := consumer.SaveToContext(context.TODO(), certConsumer) 1211 1212 appTmplFilters := []*labelfilter.LabelFilter{ 1213 labelfilter.NewForKeyWithQuery(scenarioassignment.SubaccountIDKey, fmt.Sprintf("\"%s\"", consumerID)), 1214 labelfilter.NewForKeyWithQuery(tenant.RegionLabelKey, fmt.Sprintf("\"%s\"", region)), 1215 labelfilter.NewForKeyWithQuery(selfRegisterDistinguishLabelKey, fmt.Sprintf("\"%s\"", strippedTokenClientID)), 1216 } 1217 1218 appTemplate := fixModelApplicationTemplate(appTemplateID, "app-template") 1219 1220 testErr := errors.New("Test error") 1221 1222 testCases := []struct { 1223 Name string 1224 PersistenceFn func() *persistenceautomock.PersistenceTx 1225 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 1226 ServiceFn func() *automock.ApplicationService 1227 AppTemplateServiceFn func() *automock.ApplicationTemplateService 1228 ConverterFn func() *automock.ApplicationConverter 1229 Context context.Context 1230 ExpectedApplicationPage *graphql.ApplicationPage 1231 ExpectedErr error 1232 }{ 1233 { 1234 Name: "Success", 1235 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1236 TransactionerFn: txtest.TransactionerThatSucceeds, 1237 ServiceFn: func() *automock.ApplicationService { 1238 svc := &automock.ApplicationService{} 1239 svc.On("ListAll", contextParam).Return(modelApplicationList, nil).Once() 1240 1241 return svc 1242 }, 1243 ConverterFn: func() *automock.ApplicationConverter { 1244 conv := &automock.ApplicationConverter{} 1245 conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once() 1246 return conv 1247 }, 1248 AppTemplateServiceFn: func() *automock.ApplicationTemplateService { 1249 svc := &automock.ApplicationTemplateService{} 1250 svc.On("GetByFilters", contextParam, appTmplFilters).Return(appTemplate, nil).Once() 1251 1252 return svc 1253 }, 1254 Context: ctxWithConsumerInfo, 1255 ExpectedApplicationPage: &graphql.ApplicationPage{ 1256 Data: []*graphql.Application{gqlApplication}, 1257 TotalCount: 1, 1258 PageInfo: &graphql.PageInfo{ 1259 StartCursor: "1", 1260 EndCursor: "1", 1261 HasNextPage: false, 1262 }, 1263 }, 1264 ExpectedErr: nil, 1265 }, 1266 { 1267 Name: "Error when no consumer is found in the context", 1268 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1269 TransactionerFn: txtest.NoopTransactioner, 1270 ServiceFn: func() *automock.ApplicationService { 1271 svc := &automock.ApplicationService{} 1272 svc.AssertNotCalled(t, "ListAll") 1273 1274 return svc 1275 }, 1276 ConverterFn: func() *automock.ApplicationConverter { 1277 conv := &automock.ApplicationConverter{} 1278 conv.AssertNotCalled(t, "ToGraphQL") 1279 return conv 1280 }, 1281 AppTemplateServiceFn: func() *automock.ApplicationTemplateService { 1282 svc := &automock.ApplicationTemplateService{} 1283 svc.AssertNotCalled(t, "GetByFilters") 1284 1285 return svc 1286 }, 1287 Context: context.TODO(), 1288 ExpectedErr: errors.New("cannot read consumer from context"), 1289 }, 1290 { 1291 Name: "Error when getting application template", 1292 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1293 TransactionerFn: txtest.TransactionerThatSucceeds, 1294 ServiceFn: func() *automock.ApplicationService { 1295 svc := &automock.ApplicationService{} 1296 svc.AssertNotCalled(t, "ListAll") 1297 1298 return svc 1299 }, 1300 ConverterFn: func() *automock.ApplicationConverter { 1301 conv := &automock.ApplicationConverter{} 1302 conv.AssertNotCalled(t, "ToGraphQL") 1303 return conv 1304 }, 1305 AppTemplateServiceFn: func() *automock.ApplicationTemplateService { 1306 svc := &automock.ApplicationTemplateService{} 1307 svc.On("GetByFilters", contextParam, appTmplFilters).Return(nil, testErr).Once() 1308 1309 return svc 1310 }, 1311 Context: ctxWithConsumerInfo, 1312 ExpectedErr: testErr, 1313 }, 1314 { 1315 Name: "Error when listing applications template", 1316 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1317 TransactionerFn: txtest.TransactionerThatSucceeds, 1318 ServiceFn: func() *automock.ApplicationService { 1319 svc := &automock.ApplicationService{} 1320 svc.On("ListAll", contextParam).Return(nil, testErr).Once() 1321 1322 return svc 1323 }, 1324 ConverterFn: func() *automock.ApplicationConverter { 1325 conv := &automock.ApplicationConverter{} 1326 conv.AssertNotCalled(t, "ToGraphQL") 1327 return conv 1328 }, 1329 AppTemplateServiceFn: func() *automock.ApplicationTemplateService { 1330 svc := &automock.ApplicationTemplateService{} 1331 svc.On("GetByFilters", contextParam, appTmplFilters).Return(appTemplate, nil).Once() 1332 1333 return svc 1334 }, 1335 Context: ctxWithConsumerInfo, 1336 ExpectedErr: testErr, 1337 }, 1338 { 1339 Name: "Error when no application found", 1340 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1341 TransactionerFn: txtest.TransactionerThatSucceeds, 1342 ServiceFn: func() *automock.ApplicationService { 1343 svc := &automock.ApplicationService{} 1344 svc.On("ListAll", contextParam).Return(modelApplicationListWithNoMatchingRecord, nil).Once() 1345 1346 return svc 1347 }, 1348 ConverterFn: func() *automock.ApplicationConverter { 1349 conv := &automock.ApplicationConverter{} 1350 conv.AssertNotCalled(t, "ToGraphQL") 1351 return conv 1352 }, 1353 AppTemplateServiceFn: func() *automock.ApplicationTemplateService { 1354 svc := &automock.ApplicationTemplateService{} 1355 svc.On("GetByFilters", contextParam, appTmplFilters).Return(appTemplate, nil).Once() 1356 1357 return svc 1358 }, 1359 Context: ctxWithConsumerInfo, 1360 ExpectedErr: errors.New("No application found for template with ID \"12345678-ae7e-4d1a-8027-520a96d5319d\""), 1361 }, 1362 { 1363 Name: "Error when committing", 1364 PersistenceFn: func() *persistenceautomock.PersistenceTx { 1365 persistTx := &persistenceautomock.PersistenceTx{} 1366 persistTx.On("Commit").Return(testErr).Once() 1367 return persistTx 1368 }, 1369 TransactionerFn: txtest.TransactionerThatSucceeds, 1370 ServiceFn: func() *automock.ApplicationService { 1371 svc := &automock.ApplicationService{} 1372 svc.On("ListAll", contextParam).Return(modelApplicationList, nil).Once() 1373 1374 return svc 1375 }, 1376 ConverterFn: func() *automock.ApplicationConverter { 1377 conv := &automock.ApplicationConverter{} 1378 conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once() 1379 return conv 1380 }, 1381 AppTemplateServiceFn: func() *automock.ApplicationTemplateService { 1382 svc := &automock.ApplicationTemplateService{} 1383 svc.On("GetByFilters", contextParam, appTmplFilters).Return(appTemplate, nil).Once() 1384 1385 return svc 1386 }, 1387 Context: ctxWithConsumerInfo, 1388 ExpectedErr: testErr, 1389 }, 1390 } 1391 1392 for _, testCase := range testCases { 1393 t.Run(testCase.Name, func(t *testing.T) { 1394 persistTx := testCase.PersistenceFn() 1395 transact := testCase.TransactionerFn(persistTx) 1396 svc := testCase.ServiceFn() 1397 appTemplateSvc := testCase.AppTemplateServiceFn() 1398 converter := testCase.ConverterFn() 1399 1400 resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, appTemplateSvc, nil, nil, nil, selfRegisterDistinguishLabelKey, "sb-") 1401 resolver.SetConverter(converter) 1402 1403 first := 2 1404 gqlAfter := graphql.PageCursor("test") 1405 query := "foo" 1406 gqlFilter := []*graphql.LabelFilter{ 1407 {Key: "", Query: &query}, 1408 } 1409 1410 // WHEN 1411 result, err := resolver.Applications(testCase.Context, gqlFilter, &first, &gqlAfter) 1412 1413 // then 1414 assert.Equal(t, testCase.ExpectedApplicationPage, result) 1415 1416 if testCase.ExpectedErr != nil { 1417 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 1418 } 1419 1420 mock.AssertExpectationsForObjects(t, svc, converter, appTemplateSvc) 1421 }) 1422 } 1423 } 1424 1425 func TestResolver_ApplicationsForRuntime(t *testing.T) { 1426 testError := errors.New("test error") 1427 1428 modelApplications := []*model.Application{ 1429 fixModelApplication("id1", "tenant-foo", "name", "desc"), 1430 fixModelApplication("id2", "tenant-bar", "name", "desc"), 1431 } 1432 1433 applicationGraphQL := []*graphql.Application{ 1434 fixGQLApplication("id1", "name", "desc"), 1435 fixGQLApplication("id2", "name", "desc"), 1436 } 1437 1438 first := 10 1439 after := "test" 1440 gqlAfter := graphql.PageCursor(after) 1441 1442 txGen := txtest.NewTransactionContextGenerator(testError) 1443 1444 runtimeUUID := uuid.New() 1445 runtimeID := runtimeUUID.String() 1446 testCases := []struct { 1447 Name string 1448 AppConverterFn func() *automock.ApplicationConverter 1449 AppServiceFn func() *automock.ApplicationService 1450 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 1451 InputRuntimeID string 1452 ExpectedResult *graphql.ApplicationPage 1453 ExpectedError error 1454 }{ 1455 { 1456 Name: "Success", 1457 AppServiceFn: func() *automock.ApplicationService { 1458 appService := &automock.ApplicationService{} 1459 appService.On("ListByRuntimeID", contextParam, runtimeUUID, first, after).Return(fixApplicationPage(modelApplications), nil).Once() 1460 return appService 1461 }, 1462 AppConverterFn: func() *automock.ApplicationConverter { 1463 appConverter := &automock.ApplicationConverter{} 1464 appConverter.On("MultipleToGraphQL", modelApplications).Return(applicationGraphQL).Once() 1465 return appConverter 1466 }, 1467 TransactionerFn: txGen.ThatSucceeds, 1468 InputRuntimeID: runtimeID, 1469 ExpectedResult: fixGQLApplicationPage(applicationGraphQL), 1470 ExpectedError: nil, 1471 }, 1472 { 1473 Name: "Returns error when transaction commit failed", 1474 TransactionerFn: txGen.ThatFailsOnCommit, 1475 AppServiceFn: func() *automock.ApplicationService { 1476 appService := &automock.ApplicationService{} 1477 appService.On("ListByRuntimeID", contextParam, runtimeUUID, first, after).Return(fixApplicationPage(modelApplications), nil).Once() 1478 return appService 1479 }, 1480 AppConverterFn: func() *automock.ApplicationConverter { 1481 appConverter := &automock.ApplicationConverter{} 1482 return appConverter 1483 }, 1484 InputRuntimeID: runtimeID, 1485 ExpectedResult: nil, 1486 ExpectedError: testError, 1487 }, 1488 { 1489 Name: "Returns error when application listing failed", 1490 AppServiceFn: func() *automock.ApplicationService { 1491 appSvc := &automock.ApplicationService{} 1492 appSvc.On("ListByRuntimeID", contextParam, runtimeUUID, first, after).Return(nil, testError).Once() 1493 return appSvc 1494 }, 1495 AppConverterFn: func() *automock.ApplicationConverter { 1496 appConverter := &automock.ApplicationConverter{} 1497 return appConverter 1498 }, 1499 TransactionerFn: txGen.ThatDoesntExpectCommit, 1500 InputRuntimeID: runtimeID, 1501 ExpectedResult: nil, 1502 ExpectedError: testError, 1503 }, 1504 { 1505 Name: "Returns error when starting transaction failed", 1506 AppServiceFn: func() *automock.ApplicationService { 1507 appSvc := &automock.ApplicationService{} 1508 return appSvc 1509 }, 1510 AppConverterFn: func() *automock.ApplicationConverter { 1511 appConverter := &automock.ApplicationConverter{} 1512 return appConverter 1513 }, 1514 TransactionerFn: txGen.ThatFailsOnBegin, 1515 InputRuntimeID: runtimeID, 1516 ExpectedResult: nil, 1517 ExpectedError: testError, 1518 }, 1519 { 1520 Name: "Returns error when runtimeID is not UUID", 1521 AppServiceFn: func() *automock.ApplicationService { 1522 appSvc := &automock.ApplicationService{} 1523 return appSvc 1524 }, 1525 AppConverterFn: func() *automock.ApplicationConverter { 1526 appConverter := &automock.ApplicationConverter{} 1527 return appConverter 1528 }, 1529 TransactionerFn: txGen.ThatDoesntExpectCommit, 1530 InputRuntimeID: "blabla", 1531 ExpectedResult: nil, 1532 ExpectedError: errors.New("invalid UUID length"), 1533 }, 1534 } 1535 1536 for _, testCase := range testCases { 1537 t.Run(testCase.Name, func(t *testing.T) { 1538 // GIVEN 1539 applicationSvc := testCase.AppServiceFn() 1540 applicationConverter := testCase.AppConverterFn() 1541 persistTx, transact := testCase.TransactionerFn() 1542 1543 resolver := application.NewResolver(transact, applicationSvc, nil, nil, nil, applicationConverter, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 1544 1545 // WHEN 1546 result, err := resolver.ApplicationsForRuntime(context.TODO(), testCase.InputRuntimeID, &first, &gqlAfter) 1547 1548 // THEN 1549 if testCase.ExpectedError != nil { 1550 require.NotNil(t, err) 1551 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 1552 } else { 1553 require.NoError(t, err) 1554 } 1555 assert.Equal(t, testCase.ExpectedResult, result) 1556 applicationSvc.AssertExpectations(t) 1557 applicationConverter.AssertExpectations(t) 1558 persistTx.AssertExpectations(t) 1559 transact.AssertExpectations(t) 1560 }) 1561 } 1562 } 1563 1564 func TestResolver_SetApplicationLabel(t *testing.T) { 1565 // GIVEN 1566 testErr := errors.New("Test error") 1567 1568 applicationID := "foo" 1569 gqlLabel := &graphql.Label{ 1570 Key: "key", 1571 Value: []string{"foo", "bar"}, 1572 } 1573 modelLabel := &model.LabelInput{ 1574 Key: "key", 1575 Value: []string{"foo", "bar"}, 1576 ObjectID: applicationID, 1577 ObjectType: model.ApplicationLabelableObject, 1578 } 1579 1580 testCases := []struct { 1581 Name string 1582 PersistenceFn func() *persistenceautomock.PersistenceTx 1583 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 1584 ServiceFn func() *automock.ApplicationService 1585 ConverterFn func() *automock.ApplicationConverter 1586 InputApplicationID string 1587 InputKey string 1588 InputValue interface{} 1589 ExpectedLabel *graphql.Label 1590 ExpectedErr error 1591 }{ 1592 { 1593 Name: "Success", 1594 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1595 TransactionerFn: txtest.TransactionerThatSucceeds, 1596 ServiceFn: func() *automock.ApplicationService { 1597 svc := &automock.ApplicationService{} 1598 svc.On("SetLabel", contextParam, modelLabel).Return(nil).Once() 1599 return svc 1600 }, 1601 ConverterFn: func() *automock.ApplicationConverter { 1602 conv := &automock.ApplicationConverter{} 1603 return conv 1604 }, 1605 InputApplicationID: applicationID, 1606 InputKey: gqlLabel.Key, 1607 InputValue: gqlLabel.Value, 1608 ExpectedLabel: gqlLabel, 1609 ExpectedErr: nil, 1610 }, 1611 { 1612 Name: "Returns error when adding label to application failed", 1613 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1614 TransactionerFn: txtest.TransactionerThatSucceeds, 1615 ServiceFn: func() *automock.ApplicationService { 1616 svc := &automock.ApplicationService{} 1617 svc.On("SetLabel", contextParam, modelLabel).Return(testErr).Once() 1618 return svc 1619 }, 1620 ConverterFn: func() *automock.ApplicationConverter { 1621 conv := &automock.ApplicationConverter{} 1622 return conv 1623 }, 1624 InputApplicationID: applicationID, 1625 InputKey: gqlLabel.Key, 1626 InputValue: gqlLabel.Value, 1627 ExpectedLabel: nil, 1628 ExpectedErr: testErr, 1629 }, 1630 } 1631 1632 for _, testCase := range testCases { 1633 t.Run(testCase.Name, func(t *testing.T) { 1634 svc := testCase.ServiceFn() 1635 converter := testCase.ConverterFn() 1636 persistTx := testCase.PersistenceFn() 1637 transactioner := testCase.TransactionerFn(persistTx) 1638 1639 resolver := application.NewResolver(transactioner, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 1640 resolver.SetConverter(converter) 1641 1642 // WHEN 1643 result, err := resolver.SetApplicationLabel(context.TODO(), testCase.InputApplicationID, testCase.InputKey, testCase.InputValue) 1644 1645 // then 1646 assert.Equal(t, testCase.ExpectedLabel, result) 1647 assert.Equal(t, testCase.ExpectedErr, err) 1648 1649 svc.AssertExpectations(t) 1650 converter.AssertExpectations(t) 1651 persistTx.AssertExpectations(t) 1652 }) 1653 } 1654 1655 t.Run("Returns error when Label input validation failed", func(t *testing.T) { 1656 resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 1657 1658 // WHEN 1659 result, err := resolver.SetApplicationLabel(context.TODO(), "", "", "") 1660 1661 // then 1662 require.Nil(t, result) 1663 require.Error(t, err) 1664 assert.Contains(t, err.Error(), "key=cannot be blank") 1665 assert.Contains(t, err.Error(), "value=cannot be blank") 1666 assert.Contains(t, err.Error(), "validation error for type LabelInput:") 1667 }) 1668 } 1669 1670 func TestResolver_DeleteApplicationLabel(t *testing.T) { 1671 // GIVEN 1672 testErr := errors.New("Test error") 1673 1674 applicationID := "foo" 1675 1676 labelKey := "key" 1677 1678 gqlLabel := &graphql.Label{ 1679 Key: labelKey, 1680 Value: []string{"foo", "bar"}, 1681 } 1682 1683 modelLabel := &model.Label{ 1684 ID: "b39ba24d-87fe-43fe-ac55-7f2e5ee04bcb", 1685 Tenant: str.Ptr("tnt"), 1686 Key: labelKey, 1687 Value: []string{"foo", "bar"}, 1688 ObjectID: applicationID, 1689 ObjectType: model.ApplicationLabelableObject, 1690 } 1691 1692 testCases := []struct { 1693 Name string 1694 PersistenceFn func() *persistenceautomock.PersistenceTx 1695 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 1696 ServiceFn func() *automock.ApplicationService 1697 ConverterFn func() *automock.ApplicationConverter 1698 InputApplicationID string 1699 InputKey string 1700 ExpectedLabel *graphql.Label 1701 ExpectedErr error 1702 }{ 1703 { 1704 Name: "Success", 1705 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1706 TransactionerFn: txtest.TransactionerThatSucceeds, 1707 ServiceFn: func() *automock.ApplicationService { 1708 svc := &automock.ApplicationService{} 1709 svc.On("GetLabel", contextParam, applicationID, labelKey).Return(modelLabel, nil).Once() 1710 svc.On("DeleteLabel", contextParam, applicationID, labelKey).Return(nil).Once() 1711 return svc 1712 }, 1713 ConverterFn: func() *automock.ApplicationConverter { 1714 conv := &automock.ApplicationConverter{} 1715 return conv 1716 }, 1717 InputApplicationID: applicationID, 1718 InputKey: gqlLabel.Key, 1719 ExpectedLabel: gqlLabel, 1720 ExpectedErr: nil, 1721 }, 1722 { 1723 Name: "Returns error when label retrieval failed", 1724 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1725 TransactionerFn: txtest.TransactionerThatSucceeds, 1726 ServiceFn: func() *automock.ApplicationService { 1727 svc := &automock.ApplicationService{} 1728 svc.On("GetLabel", contextParam, applicationID, labelKey).Return(nil, testErr).Once() 1729 return svc 1730 }, 1731 ConverterFn: func() *automock.ApplicationConverter { 1732 conv := &automock.ApplicationConverter{} 1733 return conv 1734 }, 1735 InputApplicationID: applicationID, 1736 InputKey: gqlLabel.Key, 1737 ExpectedLabel: nil, 1738 ExpectedErr: testErr, 1739 }, 1740 { 1741 Name: "Returns error when deleting application's label failed", 1742 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1743 TransactionerFn: txtest.TransactionerThatSucceeds, 1744 ServiceFn: func() *automock.ApplicationService { 1745 svc := &automock.ApplicationService{} 1746 svc.On("GetLabel", contextParam, applicationID, labelKey).Return(modelLabel, nil).Once() 1747 svc.On("DeleteLabel", contextParam, applicationID, labelKey).Return(testErr).Once() 1748 return svc 1749 }, 1750 ConverterFn: func() *automock.ApplicationConverter { 1751 conv := &automock.ApplicationConverter{} 1752 return conv 1753 }, 1754 InputApplicationID: applicationID, 1755 InputKey: gqlLabel.Key, 1756 ExpectedLabel: nil, 1757 ExpectedErr: testErr, 1758 }, 1759 } 1760 1761 for _, testCase := range testCases { 1762 t.Run(testCase.Name, func(t *testing.T) { 1763 svc := testCase.ServiceFn() 1764 converter := testCase.ConverterFn() 1765 persistTx := testCase.PersistenceFn() 1766 transactioner := testCase.TransactionerFn(persistTx) 1767 1768 resolver := application.NewResolver(transactioner, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 1769 resolver.SetConverter(converter) 1770 1771 // WHEN 1772 result, err := resolver.DeleteApplicationLabel(context.TODO(), testCase.InputApplicationID, testCase.InputKey) 1773 1774 // then 1775 assert.Equal(t, testCase.ExpectedLabel, result) 1776 assert.Equal(t, testCase.ExpectedErr, err) 1777 1778 svc.AssertExpectations(t) 1779 converter.AssertExpectations(t) 1780 transactioner.AssertExpectations(t) 1781 persistTx.AssertExpectations(t) 1782 }) 1783 } 1784 } 1785 1786 func TestResolver_Webhooks(t *testing.T) { 1787 // GIVEN 1788 applicationID := "fooid" 1789 modelWebhooks := []*model.Webhook{ 1790 fixModelWebhook(applicationID, "foo"), 1791 fixModelWebhook(applicationID, "bar"), 1792 } 1793 gqlWebhooks := []*graphql.Webhook{ 1794 fixGQLWebhook("foo"), 1795 fixGQLWebhook("bar"), 1796 } 1797 app := fixGQLApplication(applicationID, "foo", "bar") 1798 testErr := errors.New("Test error") 1799 1800 testCases := []struct { 1801 Name string 1802 PersistenceFn func() *persistenceautomock.PersistenceTx 1803 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 1804 ServiceFn func() *automock.WebhookService 1805 WebhookConverterFn func() *automock.WebhookConverter 1806 ExpectedResult []*graphql.Webhook 1807 ExpectedErr error 1808 }{ 1809 { 1810 Name: "Success", 1811 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1812 TransactionerFn: txtest.TransactionerThatSucceeds, 1813 ServiceFn: func() *automock.WebhookService { 1814 svc := &automock.WebhookService{} 1815 svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(modelWebhooks, nil).Once() 1816 return svc 1817 }, 1818 WebhookConverterFn: func() *automock.WebhookConverter { 1819 conv := &automock.WebhookConverter{} 1820 conv.On("MultipleToGraphQL", modelWebhooks).Return(gqlWebhooks, nil).Once() 1821 return conv 1822 }, 1823 ExpectedResult: gqlWebhooks, 1824 ExpectedErr: nil, 1825 }, 1826 { 1827 Name: "Returns error when webhook listing failed", 1828 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1829 TransactionerFn: txtest.TransactionerThatSucceeds, 1830 ServiceFn: func() *automock.WebhookService { 1831 svc := &automock.WebhookService{} 1832 svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(nil, testErr).Once() 1833 return svc 1834 }, 1835 WebhookConverterFn: func() *automock.WebhookConverter { 1836 return &automock.WebhookConverter{} 1837 }, 1838 ExpectedResult: nil, 1839 ExpectedErr: testErr, 1840 }, 1841 { 1842 Name: "Returns error when webhook conversion to graphql fails", 1843 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1844 TransactionerFn: txtest.TransactionerThatSucceeds, 1845 ServiceFn: func() *automock.WebhookService { 1846 svc := &automock.WebhookService{} 1847 svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(modelWebhooks, nil).Once() 1848 return svc 1849 }, 1850 WebhookConverterFn: func() *automock.WebhookConverter { 1851 conv := &automock.WebhookConverter{} 1852 conv.On("MultipleToGraphQL", modelWebhooks).Return(nil, testErr).Once() 1853 return conv 1854 }, 1855 ExpectedResult: nil, 1856 ExpectedErr: testErr, 1857 }, 1858 { 1859 Name: "Returns error on starting transaction", 1860 TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner { 1861 transact := &persistenceautomock.Transactioner{} 1862 transact.On("Begin").Return(nil, testErr).Once() 1863 return transact 1864 }, 1865 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1866 ServiceFn: func() *automock.WebhookService { 1867 return &automock.WebhookService{} 1868 }, 1869 WebhookConverterFn: func() *automock.WebhookConverter { 1870 return &automock.WebhookConverter{} 1871 }, 1872 ExpectedErr: testErr, 1873 }, 1874 { 1875 Name: "Returns error on committing transaction", 1876 PersistenceFn: func() *persistenceautomock.PersistenceTx { 1877 persistTx := &persistenceautomock.PersistenceTx{} 1878 persistTx.On("Commit").Return(testErr).Once() 1879 return persistTx 1880 }, 1881 TransactionerFn: txtest.TransactionerThatSucceeds, 1882 ServiceFn: func() *automock.WebhookService { 1883 svc := &automock.WebhookService{} 1884 svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(modelWebhooks, nil).Once() 1885 return svc 1886 }, 1887 WebhookConverterFn: func() *automock.WebhookConverter { 1888 conv := &automock.WebhookConverter{} 1889 conv.On("MultipleToGraphQL", modelWebhooks).Return(gqlWebhooks, nil).Once() 1890 return conv 1891 }, 1892 ExpectedErr: testErr, 1893 }, 1894 { 1895 Name: "Webhook service returns not found error", 1896 PersistenceFn: func() *persistenceautomock.PersistenceTx { 1897 persistTx := &persistenceautomock.PersistenceTx{} 1898 persistTx.On("Commit").Return(nil).Once() 1899 return persistTx 1900 }, 1901 TransactionerFn: txtest.TransactionerThatSucceeds, 1902 ServiceFn: func() *automock.WebhookService { 1903 svc := &automock.WebhookService{} 1904 svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(nil, apperrors.NewNotFoundError(resource.Webhook, "foo")).Once() 1905 return svc 1906 }, 1907 WebhookConverterFn: func() *automock.WebhookConverter { 1908 return &automock.WebhookConverter{} 1909 }, 1910 ExpectedResult: nil, 1911 ExpectedErr: nil, 1912 }, 1913 } 1914 1915 for _, testCase := range testCases { 1916 t.Run(testCase.Name, func(t *testing.T) { 1917 svc := testCase.ServiceFn() 1918 converter := testCase.WebhookConverterFn() 1919 1920 mockPersistence := testCase.PersistenceFn() 1921 mockTransactioner := testCase.TransactionerFn(mockPersistence) 1922 1923 resolver := application.NewResolver(mockTransactioner, nil, svc, nil, nil, nil, converter, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 1924 1925 // WHEN 1926 result, err := resolver.Webhooks(context.TODO(), app) 1927 1928 // then 1929 assert.Equal(t, testCase.ExpectedResult, result) 1930 assert.Equal(t, testCase.ExpectedErr, err) 1931 1932 svc.AssertExpectations(t) 1933 converter.AssertExpectations(t) 1934 mockPersistence.AssertExpectations(t) 1935 mockTransactioner.AssertExpectations(t) 1936 }) 1937 } 1938 } 1939 1940 func TestResolver_Labels(t *testing.T) { 1941 // GIVEN 1942 1943 id := "foo" 1944 tenant := "tenant" 1945 labelKey1 := "key1" 1946 labelValue1 := "val1" 1947 labelKey2 := "key2" 1948 labelValue2 := "val2" 1949 1950 gqlApp := fixGQLApplication(id, "name", "desc") 1951 1952 modelLabels := map[string]*model.Label{ 1953 "abc": { 1954 ID: "abc", 1955 Tenant: str.Ptr(tenant), 1956 Key: labelKey1, 1957 Value: labelValue1, 1958 ObjectID: id, 1959 ObjectType: model.ApplicationLabelableObject, 1960 }, 1961 "def": { 1962 ID: "def", 1963 Tenant: str.Ptr(tenant), 1964 Key: labelKey2, 1965 Value: labelValue2, 1966 ObjectID: id, 1967 ObjectType: model.ApplicationLabelableObject, 1968 }, 1969 } 1970 1971 gqlLabels := graphql.Labels{ 1972 labelKey1: labelValue1, 1973 labelKey2: labelValue2, 1974 } 1975 1976 gqlLabels1 := graphql.Labels{ 1977 labelKey1: labelValue1, 1978 } 1979 1980 testErr := errors.New("Test error") 1981 1982 testCases := []struct { 1983 Name string 1984 PersistenceFn func() *persistenceautomock.PersistenceTx 1985 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 1986 ServiceFn func() *automock.ApplicationService 1987 InputApp *graphql.Application 1988 InputKey *string 1989 ExpectedResult graphql.Labels 1990 ExpectedErr error 1991 }{ 1992 { 1993 Name: "Success", 1994 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1995 TransactionerFn: txtest.TransactionerThatSucceeds, 1996 ServiceFn: func() *automock.ApplicationService { 1997 svc := &automock.ApplicationService{} 1998 svc.On("ListLabels", contextParam, id).Return(modelLabels, nil).Once() 1999 return svc 2000 }, 2001 InputKey: nil, 2002 ExpectedResult: gqlLabels, 2003 ExpectedErr: nil, 2004 }, 2005 { 2006 Name: "Success when labels are filtered", 2007 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 2008 TransactionerFn: txtest.TransactionerThatSucceeds, 2009 ServiceFn: func() *automock.ApplicationService { 2010 svc := &automock.ApplicationService{} 2011 svc.On("ListLabels", contextParam, id).Return(modelLabels, nil).Once() 2012 return svc 2013 }, 2014 InputKey: &labelKey1, 2015 ExpectedResult: gqlLabels1, 2016 ExpectedErr: nil, 2017 }, 2018 { 2019 Name: "Returns error when label listing failed", 2020 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 2021 TransactionerFn: txtest.TransactionerThatSucceeds, 2022 ServiceFn: func() *automock.ApplicationService { 2023 svc := &automock.ApplicationService{} 2024 svc.On("ListLabels", contextParam, id).Return(nil, testErr).Once() 2025 return svc 2026 }, 2027 InputKey: &labelKey1, 2028 ExpectedResult: nil, 2029 ExpectedErr: testErr, 2030 }, 2031 } 2032 2033 for _, testCase := range testCases { 2034 t.Run(testCase.Name, func(t *testing.T) { 2035 svc := testCase.ServiceFn() 2036 persistTx := testCase.PersistenceFn() 2037 transact := testCase.TransactionerFn(persistTx) 2038 2039 resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 2040 2041 // WHEN 2042 result, err := resolver.Labels(context.TODO(), gqlApp, testCase.InputKey) 2043 2044 // then 2045 assert.Equal(t, testCase.ExpectedResult, result) 2046 assert.Equal(t, testCase.ExpectedErr, err) 2047 2048 svc.AssertExpectations(t) 2049 transact.AssertExpectations(t) 2050 persistTx.AssertExpectations(t) 2051 }) 2052 } 2053 } 2054 2055 func TestResolver_Auths(t *testing.T) { 2056 // GIVEN 2057 id := "foo" 2058 auth := model.Auth{ 2059 Credential: model.CredentialData{}, 2060 OneTimeToken: &model.OneTimeToken{ 2061 Token: "sometoken", 2062 Type: tokens.ApplicationToken, 2063 CreatedAt: time.Now(), 2064 Used: false, 2065 }, 2066 } 2067 gqlAuth := graphql.OneTimeTokenForApplication{ 2068 TokenWithURL: graphql.TokenWithURL{ 2069 Token: auth.OneTimeToken.Token, 2070 ConnectorURL: auth.OneTimeToken.ConnectorURL, 2071 }, 2072 LegacyConnectorURL: legacyConnectorURL, 2073 } 2074 testError := errors.New("error") 2075 gqlApp := fixGQLApplication(id, "name", "desc") 2076 txGen := txtest.NewTransactionContextGenerator(testError) 2077 2078 sysAuthModels := []pkgmodel.SystemAuth{{ID: "id1", AppID: &id, Value: &auth}, {ID: "id2", AppID: &id, Value: &auth}} 2079 sysAuthModelCert := []pkgmodel.SystemAuth{{ID: "id1", AppID: &id, Value: nil}} 2080 sysAuthGQL := []*graphql.AppSystemAuth{{ID: "id1", Auth: &graphql.Auth{ 2081 OneTimeToken: &gqlAuth, 2082 }}, {ID: "id2", Auth: &graphql.Auth{ 2083 OneTimeToken: &gqlAuth, 2084 }}} 2085 sysAuthGQLCert := []*graphql.AppSystemAuth{{ID: "id1", Auth: nil}} 2086 sysAuthExpected := []*graphql.AppSystemAuth{{ID: "id1", Auth: &graphql.Auth{OneTimeToken: &gqlAuth}}, {ID: "id2", Auth: &graphql.Auth{OneTimeToken: &gqlAuth}}} 2087 testCases := []struct { 2088 Name string 2089 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 2090 ServiceFn func() *automock.SystemAuthService 2091 SysAuthConvFn func() *automock.SystemAuthConverter 2092 InputApp *graphql.Application 2093 ExpectedResult []*graphql.AppSystemAuth 2094 ExpectedErr error 2095 }{ 2096 { 2097 Name: "Success", 2098 TransactionerFn: txGen.ThatSucceeds, 2099 ServiceFn: func() *automock.SystemAuthService { 2100 svc := &automock.SystemAuthService{} 2101 svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return(sysAuthModels, nil).Once() 2102 return svc 2103 }, 2104 SysAuthConvFn: func() *automock.SystemAuthConverter { 2105 sysAuthConv := &automock.SystemAuthConverter{} 2106 sysAuthConv.On("ToGraphQL", &sysAuthModels[0]).Return(sysAuthGQL[0], nil).Once() 2107 sysAuthConv.On("ToGraphQL", &sysAuthModels[1]).Return(sysAuthGQL[1], nil).Once() 2108 return sysAuthConv 2109 }, 2110 InputApp: gqlApp, 2111 ExpectedResult: sysAuthExpected, 2112 ExpectedErr: nil, 2113 }, 2114 { 2115 Name: "Success when System Auth is certificate", 2116 TransactionerFn: txGen.ThatSucceeds, 2117 ServiceFn: func() *automock.SystemAuthService { 2118 svc := &automock.SystemAuthService{} 2119 svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return(sysAuthModelCert, nil).Once() 2120 return svc 2121 }, 2122 SysAuthConvFn: func() *automock.SystemAuthConverter { 2123 sysAuthConv := &automock.SystemAuthConverter{} 2124 sysAuthConv.On("ToGraphQL", &sysAuthModelCert[0]).Return(sysAuthGQLCert[0], nil).Once() 2125 return sysAuthConv 2126 }, 2127 InputApp: gqlApp, 2128 ExpectedResult: sysAuthGQLCert, 2129 ExpectedErr: nil, 2130 }, 2131 { 2132 Name: "Returns error when commit transaction failed", 2133 TransactionerFn: txGen.ThatFailsOnCommit, 2134 ServiceFn: func() *automock.SystemAuthService { 2135 svc := &automock.SystemAuthService{} 2136 svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return(sysAuthModels, nil).Once() 2137 svc.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType") 2138 return svc 2139 }, 2140 SysAuthConvFn: func() *automock.SystemAuthConverter { 2141 sysAuthConv := &automock.SystemAuthConverter{} 2142 sysAuthConv.AssertNotCalled(t, "ToGraphQL") 2143 return sysAuthConv 2144 }, 2145 InputApp: gqlApp, 2146 ExpectedResult: nil, 2147 ExpectedErr: testError, 2148 }, 2149 { 2150 Name: "Returns error when list for SystemAuths failed", 2151 TransactionerFn: txGen.ThatDoesntExpectCommit, 2152 ServiceFn: func() *automock.SystemAuthService { 2153 svc := &automock.SystemAuthService{} 2154 svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return([]pkgmodel.SystemAuth{}, testError).Once() 2155 svc.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType") 2156 return svc 2157 }, 2158 SysAuthConvFn: func() *automock.SystemAuthConverter { 2159 sysAuthConv := &automock.SystemAuthConverter{} 2160 sysAuthConv.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType") 2161 return sysAuthConv 2162 }, 2163 InputApp: gqlApp, 2164 ExpectedResult: nil, 2165 ExpectedErr: testError, 2166 }, 2167 { 2168 Name: "Returns error when conversion to graphql fails", 2169 TransactionerFn: txGen.ThatSucceeds, 2170 ServiceFn: func() *automock.SystemAuthService { 2171 svc := &automock.SystemAuthService{} 2172 svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return(sysAuthModels, nil).Once() 2173 svc.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType") 2174 return svc 2175 }, 2176 SysAuthConvFn: func() *automock.SystemAuthConverter { 2177 sysAuthConv := &automock.SystemAuthConverter{} 2178 sysAuthConv.On("ToGraphQL", &sysAuthModels[0]).Return(nil, testError).Once() 2179 return sysAuthConv 2180 }, 2181 InputApp: gqlApp, 2182 ExpectedResult: nil, 2183 ExpectedErr: testError, 2184 }, 2185 { 2186 Name: "Returns error when starting transaction failed", 2187 TransactionerFn: txGen.ThatFailsOnBegin, 2188 ServiceFn: func() *automock.SystemAuthService { 2189 svc := &automock.SystemAuthService{} 2190 svc.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType") 2191 return svc 2192 }, 2193 SysAuthConvFn: func() *automock.SystemAuthConverter { 2194 sysAuthConv := &automock.SystemAuthConverter{} 2195 return sysAuthConv 2196 }, 2197 InputApp: gqlApp, 2198 ExpectedResult: nil, 2199 ExpectedErr: testError, 2200 }, 2201 } 2202 2203 for _, testCase := range testCases { 2204 t.Run(testCase.Name, func(t *testing.T) { 2205 svc := testCase.ServiceFn() 2206 persist, transact := testCase.TransactionerFn() 2207 conv := testCase.SysAuthConvFn() 2208 2209 resolver := application.NewResolver(transact, nil, nil, nil, svc, nil, nil, conv, nil, nil, nil, nil, nil, nil, nil, "", "") 2210 2211 // WHEN 2212 result, err := resolver.Auths(context.TODO(), testCase.InputApp) 2213 2214 // then 2215 assert.Equal(t, testCase.ExpectedResult, result) 2216 assert.Equal(t, testCase.ExpectedErr, err) 2217 2218 svc.AssertExpectations(t) 2219 conv.AssertExpectations(t) 2220 transact.AssertExpectations(t) 2221 persist.AssertExpectations(t) 2222 }) 2223 } 2224 2225 t.Run("Returns error when application is nil", func(t *testing.T) { 2226 resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 2227 // WHEN 2228 _, err := resolver.Auths(context.TODO(), nil) 2229 // THEN 2230 require.Error(t, err) 2231 assert.EqualError(t, err, "Internal Server Error: Application cannot be empty") 2232 }) 2233 } 2234 2235 func TestResolver_EventingConfiguration(t *testing.T) { 2236 // GIVEN 2237 tnt := "tnt" 2238 externalTnt := "ex-tnt" 2239 ctx := context.TODO() 2240 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 2241 2242 applicationID := uuid.New() 2243 gqlApp := fixGQLApplication(applicationID.String(), "bar", "baz") 2244 app := fixModelApplication(applicationID.String(), tnt, "bar", "baz") 2245 2246 converterMock := func() *automock.ApplicationConverter { 2247 converter := &automock.ApplicationConverter{} 2248 converter.On("GraphQLToModel", gqlApp, tnt).Return(app).Once() 2249 return converter 2250 } 2251 2252 testErr := errors.New("this is a test error") 2253 txGen := txtest.NewTransactionContextGenerator(testErr) 2254 2255 defaultEveningURL := "https://eventing.domain.local" 2256 modelAppEventingCfg := fixModelApplicationEventingConfiguration(t, defaultEveningURL) 2257 gqlAppEventingCfg := fixGQLApplicationEventingConfiguration(defaultEveningURL) 2258 2259 testCases := []struct { 2260 Name string 2261 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 2262 EventingSvcFn func() *automock.EventingService 2263 ConverterFn func() *automock.ApplicationConverter 2264 ExpectedOutput *graphql.ApplicationEventingConfiguration 2265 ExpectedError error 2266 }{ 2267 { 2268 Name: "Success", 2269 TransactionerFn: txGen.ThatSucceeds, 2270 EventingSvcFn: func() *automock.EventingService { 2271 eventingSvc := &automock.EventingService{} 2272 eventingSvc.On("GetForApplication", txtest.CtxWithDBMatcher(), *app).Return(modelAppEventingCfg, nil).Once() 2273 2274 return eventingSvc 2275 }, 2276 ConverterFn: converterMock, 2277 ExpectedOutput: gqlAppEventingCfg, 2278 ExpectedError: nil, 2279 }, { 2280 Name: "Error when getting the configuration for runtime failed", 2281 TransactionerFn: txGen.ThatDoesntExpectCommit, 2282 EventingSvcFn: func() *automock.EventingService { 2283 eventingSvc := &automock.EventingService{} 2284 eventingSvc.On("GetForApplication", txtest.CtxWithDBMatcher(), *app).Return(nil, testErr).Once() 2285 return eventingSvc 2286 }, 2287 ConverterFn: converterMock, 2288 ExpectedOutput: nil, 2289 ExpectedError: testErr, 2290 }, { 2291 Name: "Error when beginning transaction", 2292 TransactionerFn: txGen.ThatFailsOnBegin, 2293 EventingSvcFn: func() *automock.EventingService { 2294 eventingSvc := &automock.EventingService{} 2295 return eventingSvc 2296 }, 2297 ConverterFn: converterMock, 2298 ExpectedOutput: nil, 2299 ExpectedError: testErr, 2300 }, { 2301 Name: "Error when committing transaction", 2302 TransactionerFn: txGen.ThatFailsOnCommit, 2303 EventingSvcFn: func() *automock.EventingService { 2304 eventingSvc := &automock.EventingService{} 2305 eventingSvc.On("GetForApplication", txtest.CtxWithDBMatcher(), *app).Return(modelAppEventingCfg, nil).Once() 2306 return eventingSvc 2307 }, 2308 ConverterFn: converterMock, 2309 ExpectedOutput: nil, 2310 ExpectedError: testErr, 2311 }, 2312 } 2313 2314 for _, testCase := range testCases { 2315 t.Run(testCase.Name, func(t *testing.T) { 2316 persist, transact := testCase.TransactionerFn() 2317 eventingSvc := testCase.EventingSvcFn() 2318 converter := testCase.ConverterFn() 2319 2320 resolver := application.NewResolver(transact, nil, nil, nil, nil, converter, nil, nil, eventingSvc, nil, nil, nil, nil, nil, nil, "", "") 2321 2322 // WHEN 2323 result, err := resolver.EventingConfiguration(ctx, gqlApp) 2324 2325 // THEN 2326 if testCase.ExpectedError != nil { 2327 require.Error(t, err) 2328 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 2329 } else { 2330 assert.NoError(t, err) 2331 } 2332 assert.Equal(t, testCase.ExpectedOutput, result) 2333 2334 mock.AssertExpectationsForObjects(t, eventingSvc, transact, persist, converter) 2335 }) 2336 } 2337 2338 t.Run("Error when tenant not in context", func(t *testing.T) { 2339 // GIVEN 2340 resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 2341 2342 // WHEN 2343 _, err := resolver.EventingConfiguration(context.TODO(), &graphql.Application{}) 2344 2345 // THEN 2346 require.Error(t, err) 2347 assert.EqualError(t, err, "cannot read tenant from context") 2348 }) 2349 2350 t.Run("Error when parent object is nil", func(t *testing.T) { 2351 // GIVEN 2352 resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 2353 2354 // WHEN 2355 result, err := resolver.EventingConfiguration(context.TODO(), nil) 2356 2357 // THEN 2358 require.Error(t, err) 2359 assert.Contains(t, err.Error(), "Application cannot be empty") 2360 assert.Nil(t, result) 2361 }) 2362 } 2363 2364 func TestResolver_Bundles(t *testing.T) { 2365 // GIVEN 2366 testErr := errors.New("test error") 2367 2368 firstAppID := "appID" 2369 secondAppID := "appID2" 2370 appIDs := []string{firstAppID, secondAppID} 2371 2372 bundleFirstApp := fixModelBundle("foo", firstAppID, "Foo", "Lorem Ipsum") 2373 bundleSecondApp := fixModelBundle("foo", secondAppID, "Foo", "Lorem Ipsum") 2374 2375 bundlesFirstApp := []*model.Bundle{bundleFirstApp} 2376 bundlesSecondApp := []*model.Bundle{bundleSecondApp} 2377 2378 gqlBundleFirstApp := fixGQLBundle("foo", "Foo", "Lorem Ipsum") 2379 gqlBundleSecondApp := fixGQLBundle("foo", "Foo", "Lorem Ipsum") 2380 2381 gqlBundlesFirstApp := []*graphql.Bundle{gqlBundleFirstApp} 2382 gqlBundlesSecondApp := []*graphql.Bundle{gqlBundleSecondApp} 2383 2384 bundlePageFirstApp := fixBundlePage(bundlesFirstApp) 2385 bundlePageSecondApp := fixBundlePage(bundlesSecondApp) 2386 bundlePages := []*model.BundlePage{bundlePageFirstApp, bundlePageSecondApp} 2387 2388 gqlBundlePageFirstApp := fixGQLBundlePage(gqlBundlesFirstApp) 2389 gqlBundlePageSecondApp := fixGQLBundlePage(gqlBundlesSecondApp) 2390 gqlBundlePages := []*graphql.BundlePage{gqlBundlePageFirstApp, gqlBundlePageSecondApp} 2391 2392 txGen := txtest.NewTransactionContextGenerator(testErr) 2393 2394 first := 2 2395 gqlAfter := graphql.PageCursor("test") 2396 after := "test" 2397 2398 testCases := []struct { 2399 Name string 2400 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 2401 ServiceFn func() *automock.BundleService 2402 ConverterFn func() *automock.BundleConverter 2403 ExpectedResult []*graphql.BundlePage 2404 ExpectedErr []error 2405 }{ 2406 { 2407 Name: "Success", 2408 TransactionerFn: txGen.ThatSucceeds, 2409 ServiceFn: func() *automock.BundleService { 2410 svc := &automock.BundleService{} 2411 svc.On("ListByApplicationIDs", txtest.CtxWithDBMatcher(), appIDs, first, after).Return(bundlePages, nil).Once() 2412 return svc 2413 }, 2414 ConverterFn: func() *automock.BundleConverter { 2415 conv := &automock.BundleConverter{} 2416 conv.On("MultipleToGraphQL", bundlesFirstApp).Return(gqlBundlesFirstApp, nil).Once() 2417 conv.On("MultipleToGraphQL", bundlesSecondApp).Return(gqlBundlesSecondApp, nil).Once() 2418 return conv 2419 }, 2420 ExpectedResult: gqlBundlePages, 2421 ExpectedErr: nil, 2422 }, 2423 { 2424 Name: "Returns error when transaction begin failed", 2425 TransactionerFn: txGen.ThatFailsOnBegin, 2426 ServiceFn: func() *automock.BundleService { 2427 svc := &automock.BundleService{} 2428 return svc 2429 }, 2430 ConverterFn: func() *automock.BundleConverter { 2431 conv := &automock.BundleConverter{} 2432 return conv 2433 }, 2434 ExpectedResult: nil, 2435 ExpectedErr: []error{testErr}, 2436 }, 2437 { 2438 Name: "Returns error when Bundles listing failed", 2439 TransactionerFn: txGen.ThatDoesntExpectCommit, 2440 ServiceFn: func() *automock.BundleService { 2441 svc := &automock.BundleService{} 2442 svc.On("ListByApplicationIDs", txtest.CtxWithDBMatcher(), appIDs, first, after).Return(nil, testErr).Once() 2443 return svc 2444 }, 2445 ConverterFn: func() *automock.BundleConverter { 2446 conv := &automock.BundleConverter{} 2447 return conv 2448 }, 2449 ExpectedResult: nil, 2450 ExpectedErr: []error{testErr}, 2451 }, 2452 { 2453 Name: "Returns error when converting to GraphQL failed", 2454 TransactionerFn: txGen.ThatDoesntExpectCommit, 2455 ServiceFn: func() *automock.BundleService { 2456 svc := &automock.BundleService{} 2457 svc.On("ListByApplicationIDs", txtest.CtxWithDBMatcher(), appIDs, first, after).Return(bundlePages, nil).Once() 2458 return svc 2459 }, 2460 ConverterFn: func() *automock.BundleConverter { 2461 conv := &automock.BundleConverter{} 2462 conv.On("MultipleToGraphQL", bundlesFirstApp).Return(nil, testErr).Once() 2463 return conv 2464 }, 2465 ExpectedResult: nil, 2466 ExpectedErr: []error{testErr}, 2467 }, 2468 { 2469 Name: "Returns error when transaction commit failed", 2470 TransactionerFn: txGen.ThatFailsOnCommit, 2471 ServiceFn: func() *automock.BundleService { 2472 svc := &automock.BundleService{} 2473 svc.On("ListByApplicationIDs", txtest.CtxWithDBMatcher(), appIDs, first, after).Return(bundlePages, nil).Once() 2474 return svc 2475 }, 2476 ConverterFn: func() *automock.BundleConverter { 2477 conv := &automock.BundleConverter{} 2478 conv.On("MultipleToGraphQL", bundlesFirstApp).Return(gqlBundlesFirstApp, nil).Once() 2479 conv.On("MultipleToGraphQL", bundlesSecondApp).Return(gqlBundlesSecondApp, nil).Once() 2480 return conv 2481 }, 2482 ExpectedResult: nil, 2483 ExpectedErr: []error{testErr}, 2484 }, 2485 } 2486 2487 for _, testCase := range testCases { 2488 t.Run(testCase.Name, func(t *testing.T) { 2489 // GIVEN 2490 persist, transact := testCase.TransactionerFn() 2491 svc := testCase.ServiceFn() 2492 converter := testCase.ConverterFn() 2493 2494 resolver := application.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, svc, converter, nil, nil, nil, nil, "", "") 2495 firstAppParams := dataloader.ParamBundle{ID: firstAppID, Ctx: context.TODO(), First: &first, After: &gqlAfter} 2496 secondAppParams := dataloader.ParamBundle{ID: secondAppID, Ctx: context.TODO(), First: &first, After: &gqlAfter} 2497 keys := []dataloader.ParamBundle{firstAppParams, secondAppParams} 2498 2499 // WHEN 2500 result, err := resolver.BundlesDataLoader(keys) 2501 2502 // then 2503 assert.Equal(t, testCase.ExpectedResult, result) 2504 assert.Equal(t, testCase.ExpectedErr, err) 2505 2506 persist.AssertExpectations(t) 2507 transact.AssertExpectations(t) 2508 svc.AssertExpectations(t) 2509 converter.AssertExpectations(t) 2510 }) 2511 } 2512 2513 t.Run("Returns error when there are no Applications", func(t *testing.T) { 2514 resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 2515 // WHEN 2516 _, err := resolver.BundlesDataLoader([]dataloader.ParamBundle{}) 2517 // THEN 2518 require.Error(t, err[0]) 2519 assert.EqualError(t, err[0], apperrors.NewInternalError("No Applications found").Error()) 2520 }) 2521 2522 t.Run("Returns error when start cursor is nil", func(t *testing.T) { 2523 firstAppParams := dataloader.ParamBundle{ID: firstAppID, Ctx: context.TODO(), First: nil, After: &gqlAfter} 2524 keys := []dataloader.ParamBundle{firstAppParams} 2525 2526 resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 2527 // WHEN 2528 _, err := resolver.BundlesDataLoader(keys) 2529 // THEN 2530 require.Error(t, err[0]) 2531 assert.EqualError(t, err[0], apperrors.NewInvalidDataError("missing required parameter 'first'").Error()) 2532 }) 2533 } 2534 2535 func TestResolver_Bundle(t *testing.T) { 2536 // GIVEN 2537 id := "foo" 2538 appID := "bar" 2539 modelBundle := fixModelBundle(id, appID, "name", "bar") 2540 gqlBundle := fixGQLBundle(id, "name", "bar") 2541 app := fixGQLApplication("foo", "foo", "foo") 2542 testErr := errors.New("Test error") 2543 txGen := txtest.NewTransactionContextGenerator(testErr) 2544 2545 testCases := []struct { 2546 Name string 2547 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 2548 ServiceFn func() *automock.BundleService 2549 ConverterFn func() *automock.BundleConverter 2550 InputID string 2551 Application *graphql.Application 2552 ExpectedBundle *graphql.Bundle 2553 ExpectedErr error 2554 }{ 2555 { 2556 Name: "Success", 2557 TransactionerFn: txGen.ThatSucceeds, 2558 ServiceFn: func() *automock.BundleService { 2559 svc := &automock.BundleService{} 2560 svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelBundle, nil).Once() 2561 2562 return svc 2563 }, 2564 ConverterFn: func() *automock.BundleConverter { 2565 conv := &automock.BundleConverter{} 2566 conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once() 2567 return conv 2568 }, 2569 InputID: "foo", 2570 Application: app, 2571 ExpectedBundle: gqlBundle, 2572 ExpectedErr: nil, 2573 }, 2574 { 2575 Name: "Returns error when application retrieval failed", 2576 TransactionerFn: txGen.ThatDoesntExpectCommit, 2577 ServiceFn: func() *automock.BundleService { 2578 svc := &automock.BundleService{} 2579 svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, testErr).Once() 2580 2581 return svc 2582 }, 2583 ConverterFn: func() *automock.BundleConverter { 2584 conv := &automock.BundleConverter{} 2585 return conv 2586 }, 2587 InputID: "foo", 2588 Application: app, 2589 ExpectedBundle: nil, 2590 ExpectedErr: testErr, 2591 }, 2592 { 2593 Name: "Returns error when conversion to graphql fails", 2594 TransactionerFn: txGen.ThatDoesntExpectCommit, 2595 ServiceFn: func() *automock.BundleService { 2596 svc := &automock.BundleService{} 2597 svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelBundle, nil).Once() 2598 return svc 2599 }, 2600 ConverterFn: func() *automock.BundleConverter { 2601 conv := &automock.BundleConverter{} 2602 conv.On("ToGraphQL", modelBundle).Return(nil, testErr).Once() 2603 return conv 2604 }, 2605 InputID: "foo", 2606 Application: app, 2607 ExpectedBundle: nil, 2608 ExpectedErr: testErr, 2609 }, 2610 { 2611 Name: "Returns nil when bundle for application not found", 2612 TransactionerFn: txGen.ThatSucceeds, 2613 ServiceFn: func() *automock.BundleService { 2614 svc := &automock.BundleService{} 2615 svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, apperrors.NewNotFoundError(resource.Application, "")).Once() 2616 2617 return svc 2618 }, 2619 ConverterFn: func() *automock.BundleConverter { 2620 conv := &automock.BundleConverter{} 2621 return conv 2622 }, 2623 InputID: "foo", 2624 Application: app, 2625 ExpectedBundle: nil, 2626 ExpectedErr: nil, 2627 }, 2628 { 2629 Name: "Returns error when commit begin error", 2630 TransactionerFn: txGen.ThatFailsOnBegin, 2631 ServiceFn: func() *automock.BundleService { 2632 svc := &automock.BundleService{} 2633 2634 return svc 2635 }, 2636 ConverterFn: func() *automock.BundleConverter { 2637 conv := &automock.BundleConverter{} 2638 return conv 2639 }, 2640 InputID: "foo", 2641 Application: app, 2642 ExpectedBundle: nil, 2643 ExpectedErr: testErr, 2644 }, 2645 { 2646 Name: "Returns error when commit failed", 2647 TransactionerFn: txGen.ThatFailsOnCommit, 2648 ServiceFn: func() *automock.BundleService { 2649 svc := &automock.BundleService{} 2650 svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelBundle, nil).Once() 2651 return svc 2652 }, 2653 ConverterFn: func() *automock.BundleConverter { 2654 conv := &automock.BundleConverter{} 2655 conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once() 2656 return conv 2657 }, 2658 InputID: "foo", 2659 Application: app, 2660 ExpectedBundle: nil, 2661 ExpectedErr: testErr, 2662 }, 2663 } 2664 2665 for _, testCase := range testCases { 2666 t.Run(testCase.Name, func(t *testing.T) { 2667 persist, transact := testCase.TransactionerFn() 2668 svc := testCase.ServiceFn() 2669 converter := testCase.ConverterFn() 2670 2671 resolver := application.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, svc, converter, nil, nil, nil, nil, "", "") 2672 2673 // WHEN 2674 result, err := resolver.Bundle(context.TODO(), testCase.Application, testCase.InputID) 2675 2676 // then 2677 assert.Equal(t, testCase.ExpectedBundle, result) 2678 assert.Equal(t, testCase.ExpectedErr, err) 2679 2680 svc.AssertExpectations(t) 2681 persist.AssertExpectations(t) 2682 transact.AssertExpectations(t) 2683 converter.AssertExpectations(t) 2684 }) 2685 } 2686 2687 t.Run("Returns error when application is nil", func(t *testing.T) { 2688 resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "") 2689 // WHEN 2690 _, err := resolver.Bundle(context.TODO(), nil, "") 2691 // THEN 2692 require.Error(t, err) 2693 assert.EqualError(t, err, apperrors.NewInternalError("Application cannot be empty").Error()) 2694 }) 2695 } 2696 2697 func fixOAuths() []pkgmodel.SystemAuth { 2698 return []pkgmodel.SystemAuth{ 2699 { 2700 ID: "foo", 2701 TenantID: str.Ptr("foo"), 2702 Value: &model.Auth{ 2703 Credential: model.CredentialData{ 2704 Basic: nil, 2705 Oauth: &model.OAuthCredentialData{ 2706 ClientID: "foo", 2707 ClientSecret: "foo", 2708 URL: "foo", 2709 }, 2710 }, 2711 }, 2712 }, 2713 { 2714 ID: "bar", 2715 TenantID: str.Ptr("bar"), 2716 Value: nil, 2717 }, 2718 { 2719 ID: "test", 2720 TenantID: str.Ptr("test"), 2721 Value: &model.Auth{ 2722 Credential: model.CredentialData{ 2723 Basic: &model.BasicCredentialData{ 2724 Username: "test", 2725 Password: "test", 2726 }, 2727 Oauth: nil, 2728 }, 2729 }, 2730 }, 2731 } 2732 } 2733 2734 func TestResolver_ApplicationTemplate(t *testing.T) { 2735 // GIVEN 2736 2737 id := "foo" 2738 appTemplateID := "12345678-ae7e-4d1a-8027-520a96d5319d" 2739 appTemplateName := "app-template" 2740 2741 gqlApp := fixGQLApplication(id, "name", "desc") 2742 gqlAppWithAppTemplate := fixGQLApplicationWithAppTemplate(id, "name", "desc", appTemplateID) 2743 modelAppTemplate := fixModelApplicationTemplate(appTemplateID, appTemplateName) 2744 gqlAppTemplate := fixGQLApplicationTemplate(appTemplateID, appTemplateName) 2745 2746 testErr := errors.New("Test error") 2747 2748 testCases := []struct { 2749 Name string 2750 PersistenceFn func() *persistenceautomock.PersistenceTx 2751 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 2752 ServiceFn func() *automock.ApplicationTemplateService 2753 ConverterFn func() *automock.ApplicationTemplateConverter 2754 Application *graphql.Application 2755 ExpectedResult *graphql.ApplicationTemplate 2756 ExpectedErr error 2757 }{ 2758 { 2759 Name: "Success", 2760 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 2761 TransactionerFn: txtest.TransactionerThatSucceeds, 2762 ServiceFn: func() *automock.ApplicationTemplateService { 2763 svc := &automock.ApplicationTemplateService{} 2764 svc.On("Get", contextParam, appTemplateID).Return(modelAppTemplate, nil).Once() 2765 return svc 2766 }, 2767 ConverterFn: func() *automock.ApplicationTemplateConverter { 2768 conv := &automock.ApplicationTemplateConverter{} 2769 conv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once() 2770 return conv 2771 }, 2772 Application: gqlAppWithAppTemplate, 2773 ExpectedResult: gqlAppTemplate, 2774 ExpectedErr: nil, 2775 }, 2776 { 2777 Name: "Success when application does not contain app template", 2778 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 2779 TransactionerFn: txtest.NoopTransactioner, 2780 ServiceFn: func() *automock.ApplicationTemplateService { 2781 svc := &automock.ApplicationTemplateService{} 2782 svc.AssertNotCalled(t, "Get", contextParam, appTemplateID) 2783 return svc 2784 }, 2785 ConverterFn: func() *automock.ApplicationTemplateConverter { 2786 conv := &automock.ApplicationTemplateConverter{} 2787 conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate) 2788 return conv 2789 }, 2790 Application: gqlApp, 2791 ExpectedResult: nil, 2792 ExpectedErr: nil, 2793 }, 2794 { 2795 Name: "Returns error when application is empty", 2796 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 2797 TransactionerFn: txtest.NoopTransactioner, 2798 ServiceFn: func() *automock.ApplicationTemplateService { 2799 svc := &automock.ApplicationTemplateService{} 2800 svc.AssertNotCalled(t, "Get", contextParam, appTemplateID) 2801 return svc 2802 }, 2803 ConverterFn: func() *automock.ApplicationTemplateConverter { 2804 conv := &automock.ApplicationTemplateConverter{} 2805 conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate) 2806 return conv 2807 }, 2808 Application: nil, 2809 ExpectedResult: nil, 2810 ExpectedErr: apperrors.NewInternalError("Application cannot be empty"), 2811 }, 2812 { 2813 Name: "Returns error when transaction begin fails", 2814 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 2815 TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner { 2816 transact := &persistenceautomock.Transactioner{} 2817 transact.On("Begin").Return(persistTx, testErr).Once() 2818 return transact 2819 }, 2820 ServiceFn: func() *automock.ApplicationTemplateService { 2821 svc := &automock.ApplicationTemplateService{} 2822 svc.AssertNotCalled(t, "Get", contextParam, appTemplateID) 2823 return svc 2824 }, 2825 ConverterFn: func() *automock.ApplicationTemplateConverter { 2826 conv := &automock.ApplicationTemplateConverter{} 2827 conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate) 2828 return conv 2829 }, 2830 Application: gqlAppWithAppTemplate, 2831 ExpectedResult: nil, 2832 ExpectedErr: testErr, 2833 }, 2834 { 2835 Name: "Returns error when transaction commit fails", 2836 PersistenceFn: func() *persistenceautomock.PersistenceTx { 2837 persistTx := &persistenceautomock.PersistenceTx{} 2838 persistTx.On("Commit").Return(testErr).Once() 2839 return persistTx 2840 }, 2841 TransactionerFn: txtest.TransactionerThatSucceeds, 2842 ServiceFn: func() *automock.ApplicationTemplateService { 2843 svc := &automock.ApplicationTemplateService{} 2844 svc.On("Get", contextParam, appTemplateID).Return(modelAppTemplate, nil).Once() 2845 return svc 2846 }, 2847 ConverterFn: func() *automock.ApplicationTemplateConverter { 2848 conv := &automock.ApplicationTemplateConverter{} 2849 conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate) 2850 return conv 2851 }, 2852 Application: gqlAppWithAppTemplate, 2853 ExpectedResult: nil, 2854 ExpectedErr: testErr, 2855 }, 2856 { 2857 Name: "Returns error when app template is not found", 2858 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 2859 TransactionerFn: txtest.TransactionerThatDoesARollback, 2860 ServiceFn: func() *automock.ApplicationTemplateService { 2861 svc := &automock.ApplicationTemplateService{} 2862 svc.On("Get", contextParam, appTemplateID).Return(nil, testErr).Once() 2863 return svc 2864 }, 2865 ConverterFn: func() *automock.ApplicationTemplateConverter { 2866 conv := &automock.ApplicationTemplateConverter{} 2867 conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate) 2868 return conv 2869 }, 2870 Application: gqlAppWithAppTemplate, 2871 ExpectedResult: nil, 2872 ExpectedErr: errors.Wrapf(testErr, "no app template found with id %s", appTemplateID), 2873 }, 2874 } 2875 2876 for _, testCase := range testCases { 2877 t.Run(testCase.Name, func(t *testing.T) { 2878 svc := testCase.ServiceFn() 2879 converter := testCase.ConverterFn() 2880 persistTx := testCase.PersistenceFn() 2881 transact := testCase.TransactionerFn(persistTx) 2882 2883 resolver := application.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, svc, converter, nil, nil, "", "") 2884 // WHEN 2885 result, err := resolver.ApplicationTemplate(context.TODO(), testCase.Application) 2886 2887 // then 2888 assert.Equal(t, testCase.ExpectedResult, result) 2889 if testCase.ExpectedErr != nil { 2890 assert.EqualError(t, testCase.ExpectedErr, err.Error()) 2891 } else { 2892 assert.NoError(t, err) 2893 } 2894 2895 svc.AssertExpectations(t) 2896 converter.AssertExpectations(t) 2897 transact.AssertExpectations(t) 2898 persistTx.AssertExpectations(t) 2899 }) 2900 } 2901 } 2902 2903 func TestResolver_TenantBusinessType(t *testing.T) { 2904 // GIVEN 2905 2906 id := "foo" 2907 //appTemplateName := "app-template" 2908 2909 gqlApp := fixGQLApplication(id, "name", "desc") 2910 gqlAppWithTbt := fixGQLApplicationWithTenantBusinessType(id, "name", "desc") 2911 gqlTbt := fixGQLTenantBusinessType(id, "test-code", "test-name") 2912 modelTbt := fixModelTenantBusinessType(tbtID, "test-code", "test-name") 2913 //gqlAppTemplate := fixGQLApplicationTemplate(appTemplateID, appTemplateName) 2914 2915 testErr := errors.New("Test error") 2916 2917 testCases := []struct { 2918 Name string 2919 PersistenceFn func() *persistenceautomock.PersistenceTx 2920 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 2921 ServiceFn func() *automock.TenantBusinessTypeService 2922 ConverterFn func() *automock.TenantBusinessTypeConverter 2923 Application *graphql.Application 2924 ExpectedResult *graphql.TenantBusinessType 2925 ExpectedErr error 2926 }{ 2927 { 2928 Name: "Success", 2929 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 2930 TransactionerFn: txtest.TransactionerThatSucceeds, 2931 ServiceFn: func() *automock.TenantBusinessTypeService { 2932 svc := &automock.TenantBusinessTypeService{} 2933 svc.On("GetByID", contextParam, tbtID).Return(modelTbt, nil).Once() 2934 return svc 2935 }, 2936 ConverterFn: func() *automock.TenantBusinessTypeConverter { 2937 conv := &automock.TenantBusinessTypeConverter{} 2938 conv.On("ToGraphQL", modelTbt).Return(gqlTbt, nil).Once() 2939 return conv 2940 }, 2941 Application: gqlAppWithTbt, 2942 ExpectedResult: gqlTbt, 2943 ExpectedErr: nil, 2944 }, 2945 { 2946 Name: "Success when application does not contain tenant business type", 2947 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 2948 TransactionerFn: txtest.NoopTransactioner, 2949 ServiceFn: func() *automock.TenantBusinessTypeService { 2950 svc := &automock.TenantBusinessTypeService{} 2951 svc.AssertNotCalled(t, "GetByID", contextParam, tbtID) 2952 return svc 2953 }, 2954 ConverterFn: func() *automock.TenantBusinessTypeConverter { 2955 conv := &automock.TenantBusinessTypeConverter{} 2956 conv.AssertNotCalled(t, "ToGraphQL", modelTbt) 2957 return conv 2958 }, 2959 Application: gqlApp, 2960 ExpectedResult: nil, 2961 ExpectedErr: nil, 2962 }, 2963 { 2964 Name: "Returns error when application is empty", 2965 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 2966 TransactionerFn: txtest.NoopTransactioner, 2967 ServiceFn: func() *automock.TenantBusinessTypeService { 2968 svc := &automock.TenantBusinessTypeService{} 2969 svc.AssertNotCalled(t, "GetByID", contextParam, tbtID) 2970 return svc 2971 }, 2972 ConverterFn: func() *automock.TenantBusinessTypeConverter { 2973 conv := &automock.TenantBusinessTypeConverter{} 2974 conv.AssertNotCalled(t, "ToGraphQL", modelTbt) 2975 return conv 2976 }, 2977 Application: nil, 2978 ExpectedResult: nil, 2979 ExpectedErr: apperrors.NewInternalError("Application cannot be empty"), 2980 }, 2981 { 2982 Name: "Returns error when transaction begin fails", 2983 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 2984 TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner { 2985 transact := &persistenceautomock.Transactioner{} 2986 transact.On("Begin").Return(persistTx, testErr).Once() 2987 return transact 2988 }, 2989 ServiceFn: func() *automock.TenantBusinessTypeService { 2990 svc := &automock.TenantBusinessTypeService{} 2991 svc.AssertNotCalled(t, "GetByID", contextParam, tbtID) 2992 return svc 2993 }, 2994 ConverterFn: func() *automock.TenantBusinessTypeConverter { 2995 conv := &automock.TenantBusinessTypeConverter{} 2996 conv.AssertNotCalled(t, "ToGraphQL", modelTbt) 2997 return conv 2998 }, 2999 Application: gqlAppWithTbt, 3000 ExpectedResult: nil, 3001 ExpectedErr: testErr, 3002 }, 3003 { 3004 Name: "Returns error when transaction commit fails", 3005 PersistenceFn: func() *persistenceautomock.PersistenceTx { 3006 persistTx := &persistenceautomock.PersistenceTx{} 3007 persistTx.On("Commit").Return(testErr).Once() 3008 return persistTx 3009 }, 3010 TransactionerFn: txtest.TransactionerThatSucceeds, 3011 ServiceFn: func() *automock.TenantBusinessTypeService { 3012 svc := &automock.TenantBusinessTypeService{} 3013 svc.On("GetByID", contextParam, tbtID).Return(modelTbt, nil).Once() 3014 return svc 3015 }, 3016 ConverterFn: func() *automock.TenantBusinessTypeConverter { 3017 conv := &automock.TenantBusinessTypeConverter{} 3018 conv.AssertNotCalled(t, "ToGraphQL", modelTbt) 3019 return conv 3020 }, 3021 Application: gqlAppWithTbt, 3022 ExpectedResult: nil, 3023 ExpectedErr: testErr, 3024 }, 3025 { 3026 Name: "Returns error when tenant business type is not found", 3027 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 3028 TransactionerFn: txtest.TransactionerThatDoesARollback, 3029 ServiceFn: func() *automock.TenantBusinessTypeService { 3030 svc := &automock.TenantBusinessTypeService{} 3031 svc.On("GetByID", contextParam, tbtID).Return(nil, testErr).Once() 3032 return svc 3033 }, 3034 ConverterFn: func() *automock.TenantBusinessTypeConverter { 3035 conv := &automock.TenantBusinessTypeConverter{} 3036 conv.AssertNotCalled(t, "ToGraphQL", modelTbt) 3037 return conv 3038 }, 3039 Application: gqlAppWithTbt, 3040 ExpectedResult: nil, 3041 ExpectedErr: errors.Wrapf(testErr, "no tenant business type found with id %s", tbtID), 3042 }, 3043 } 3044 3045 for _, testCase := range testCases { 3046 t.Run(testCase.Name, func(t *testing.T) { 3047 svc := testCase.ServiceFn() 3048 converter := testCase.ConverterFn() 3049 persistTx := testCase.PersistenceFn() 3050 transact := testCase.TransactionerFn(persistTx) 3051 3052 resolver := application.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, svc, converter, "", "") 3053 // WHEN 3054 result, err := resolver.TenantBusinessType(context.TODO(), testCase.Application) 3055 3056 // then 3057 assert.Equal(t, testCase.ExpectedResult, result) 3058 if testCase.ExpectedErr != nil { 3059 assert.EqualError(t, testCase.ExpectedErr, err.Error()) 3060 } else { 3061 assert.NoError(t, err) 3062 } 3063 3064 svc.AssertExpectations(t) 3065 converter.AssertExpectations(t) 3066 transact.AssertExpectations(t) 3067 persistTx.AssertExpectations(t) 3068 }) 3069 } 3070 }