github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/bundle/resolver_test.go (about) 1 package bundle_test 2 3 import ( 4 "context" 5 "encoding/json" 6 "strings" 7 "testing" 8 9 dataloader "github.com/kyma-incubator/compass/components/director/internal/dataloaders" 10 11 "github.com/kyma-incubator/compass/components/director/pkg/str" 12 13 "github.com/kyma-incubator/compass/components/director/internal/domain/bundle" 14 "github.com/kyma-incubator/compass/components/director/internal/domain/bundle/automock" 15 "github.com/kyma-incubator/compass/components/director/internal/model" 16 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 17 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 18 persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock" 19 "github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest" 20 "github.com/kyma-incubator/compass/components/director/pkg/resource" 21 "github.com/pkg/errors" 22 "github.com/stretchr/testify/assert" 23 "github.com/stretchr/testify/require" 24 ) 25 26 func TestResolver_API(t *testing.T) { 27 { 28 // GIVEN 29 id := "bar" 30 bndlID := "1" 31 var nilBundleID *string 32 modelAPI := fixModelAPIDefinition(id, "name", "bar", "test") 33 modelSpec := &model.Spec{ 34 ID: id, 35 ObjectType: model.APISpecReference, 36 ObjectID: id, 37 } 38 modelBundleRef := &model.BundleReference{ 39 BundleID: &bndlID, 40 ObjectType: model.BundleAPIReference, 41 ObjectID: &id, 42 APIDefaultTargetURL: str.Ptr(""), 43 } 44 gqlAPI := fixGQLAPIDefinition(id, bndlID, "name", "bar", "test") 45 app := fixGQLBundle("foo", "foo", "foo") 46 testErr := errors.New("Test error") 47 txGen := txtest.NewTransactionContextGenerator(testErr) 48 49 testCases := []struct { 50 Name string 51 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 52 ServiceFn func() *automock.APIService 53 SpecServiceFn func() *automock.SpecService 54 BundleReferenceServiceFn func() *automock.BundleReferenceService 55 ConverterFn func() *automock.APIConverter 56 InputID string 57 Bundle *graphql.Bundle 58 ExpectedAPI *graphql.APIDefinition 59 ExpectedErr error 60 }{ 61 { 62 Name: "Success", 63 TransactionerFn: txGen.ThatSucceeds, 64 ServiceFn: func() *automock.APIService { 65 svc := &automock.APIService{} 66 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelAPI, nil).Once() 67 68 return svc 69 }, 70 SpecServiceFn: func() *automock.SpecService { 71 svc := &automock.SpecService{} 72 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPI.ID).Return(modelSpec, nil).Once() 73 return svc 74 }, 75 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 76 svc := &automock.BundleReferenceService{} 77 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPI.ID, nilBundleID).Return(modelBundleRef, nil).Once() 78 return svc 79 }, 80 ConverterFn: func() *automock.APIConverter { 81 conv := &automock.APIConverter{} 82 conv.On("ToGraphQL", modelAPI, modelSpec, modelBundleRef).Return(gqlAPI, nil).Once() 83 return conv 84 }, 85 InputID: "foo", 86 Bundle: app, 87 ExpectedAPI: gqlAPI, 88 ExpectedErr: nil, 89 }, 90 { 91 Name: "Returns error when bundle retrieval failed", 92 TransactionerFn: txGen.ThatDoesntExpectCommit, 93 ServiceFn: func() *automock.APIService { 94 svc := &automock.APIService{} 95 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, testErr).Once() 96 97 return svc 98 }, 99 SpecServiceFn: func() *automock.SpecService { 100 return &automock.SpecService{} 101 }, 102 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 103 return &automock.BundleReferenceService{} 104 }, 105 ConverterFn: func() *automock.APIConverter { 106 return &automock.APIConverter{} 107 }, 108 InputID: "foo", 109 Bundle: app, 110 ExpectedAPI: nil, 111 ExpectedErr: testErr, 112 }, 113 { 114 Name: "Returns null when api for bundle not found", 115 TransactionerFn: txGen.ThatSucceeds, 116 ServiceFn: func() *automock.APIService { 117 svc := &automock.APIService{} 118 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, apperrors.NewNotFoundError(resource.Bundle, "")).Once() 119 return svc 120 }, 121 SpecServiceFn: func() *automock.SpecService { 122 return &automock.SpecService{} 123 }, 124 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 125 return &automock.BundleReferenceService{} 126 }, 127 ConverterFn: func() *automock.APIConverter { 128 return &automock.APIConverter{} 129 }, 130 InputID: "foo", 131 Bundle: app, 132 ExpectedAPI: nil, 133 ExpectedErr: nil, 134 }, 135 { 136 Name: "Returns error when Spec retrieval failed", 137 TransactionerFn: txGen.ThatDoesntExpectCommit, 138 ServiceFn: func() *automock.APIService { 139 svc := &automock.APIService{} 140 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelAPI, nil).Once() 141 142 return svc 143 }, 144 SpecServiceFn: func() *automock.SpecService { 145 svc := &automock.SpecService{} 146 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPI.ID).Return(nil, testErr).Once() 147 return svc 148 }, 149 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 150 return &automock.BundleReferenceService{} 151 }, 152 ConverterFn: func() *automock.APIConverter { 153 return &automock.APIConverter{} 154 }, 155 InputID: "foo", 156 Bundle: app, 157 ExpectedAPI: nil, 158 ExpectedErr: testErr, 159 }, 160 { 161 Name: "Returns error when BundleReference retrieval failed", 162 TransactionerFn: txGen.ThatDoesntExpectCommit, 163 ServiceFn: func() *automock.APIService { 164 svc := &automock.APIService{} 165 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelAPI, nil).Once() 166 167 return svc 168 }, 169 SpecServiceFn: func() *automock.SpecService { 170 svc := &automock.SpecService{} 171 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPI.ID).Return(modelSpec, nil).Once() 172 return svc 173 }, 174 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 175 svc := &automock.BundleReferenceService{} 176 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPI.ID, nilBundleID).Return(nil, testErr).Once() 177 return svc 178 }, 179 ConverterFn: func() *automock.APIConverter { 180 return &automock.APIConverter{} 181 }, 182 InputID: "foo", 183 Bundle: app, 184 ExpectedAPI: nil, 185 ExpectedErr: testErr, 186 }, 187 { 188 Name: "Returns error when converting to GraphQL failed", 189 TransactionerFn: txGen.ThatDoesntExpectCommit, 190 ServiceFn: func() *automock.APIService { 191 svc := &automock.APIService{} 192 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelAPI, nil).Once() 193 194 return svc 195 }, 196 SpecServiceFn: func() *automock.SpecService { 197 svc := &automock.SpecService{} 198 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPI.ID).Return(modelSpec, nil).Once() 199 return svc 200 }, 201 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 202 svc := &automock.BundleReferenceService{} 203 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPI.ID, nilBundleID).Return(modelBundleRef, nil).Once() 204 return svc 205 }, 206 ConverterFn: func() *automock.APIConverter { 207 conv := &automock.APIConverter{} 208 conv.On("ToGraphQL", modelAPI, modelSpec, modelBundleRef).Return(nil, testErr).Once() 209 return conv 210 }, 211 InputID: "foo", 212 Bundle: app, 213 ExpectedAPI: nil, 214 ExpectedErr: testErr, 215 }, 216 { 217 Name: "Returns error when commit begin error", 218 TransactionerFn: txGen.ThatFailsOnBegin, 219 ServiceFn: func() *automock.APIService { 220 return &automock.APIService{} 221 }, 222 SpecServiceFn: func() *automock.SpecService { 223 return &automock.SpecService{} 224 }, 225 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 226 return &automock.BundleReferenceService{} 227 }, 228 ConverterFn: func() *automock.APIConverter { 229 return &automock.APIConverter{} 230 }, 231 InputID: "foo", 232 Bundle: app, 233 ExpectedAPI: nil, 234 ExpectedErr: testErr, 235 }, 236 { 237 Name: "Returns error when commit failed", 238 TransactionerFn: txGen.ThatFailsOnCommit, 239 ServiceFn: func() *automock.APIService { 240 svc := &automock.APIService{} 241 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelAPI, nil).Once() 242 243 return svc 244 }, 245 SpecServiceFn: func() *automock.SpecService { 246 svc := &automock.SpecService{} 247 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPI.ID).Return(modelSpec, nil).Once() 248 return svc 249 }, 250 BundleReferenceServiceFn: func() *automock.BundleReferenceService { 251 svc := &automock.BundleReferenceService{} 252 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPI.ID, nilBundleID).Return(modelBundleRef, nil).Once() 253 return svc 254 }, 255 ConverterFn: func() *automock.APIConverter { 256 conv := &automock.APIConverter{} 257 conv.On("ToGraphQL", modelAPI, modelSpec, modelBundleRef).Return(gqlAPI, nil).Once() 258 return conv 259 }, 260 InputID: "foo", 261 Bundle: app, 262 ExpectedAPI: nil, 263 ExpectedErr: testErr, 264 }, 265 } 266 267 for _, testCase := range testCases { 268 t.Run(testCase.Name, func(t *testing.T) { 269 persist, transact := testCase.TransactionerFn() 270 svc := testCase.ServiceFn() 271 converter := testCase.ConverterFn() 272 specSvc := testCase.SpecServiceFn() 273 bndlRefSvc := testCase.BundleReferenceServiceFn() 274 275 resolver := bundle.NewResolver(transact, nil, nil, bndlRefSvc, svc, nil, nil, nil, nil, converter, nil, nil, specSvc, nil) 276 277 // WHEN 278 result, err := resolver.APIDefinition(context.TODO(), testCase.Bundle, testCase.InputID) 279 280 // then 281 assert.Equal(t, testCase.ExpectedAPI, result) 282 if testCase.ExpectedErr != nil { 283 require.Error(t, err) 284 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 285 } else { 286 require.Nil(t, err) 287 } 288 289 svc.AssertExpectations(t) 290 persist.AssertExpectations(t) 291 transact.AssertExpectations(t) 292 converter.AssertExpectations(t) 293 specSvc.AssertExpectations(t) 294 bndlRefSvc.AssertExpectations(t) 295 }) 296 } 297 } 298 } 299 300 func TestResolver_APIs(t *testing.T) { 301 // GIVEN 302 testErr := errors.New("test error") 303 group := "group" 304 desc := "desc" 305 name := "test name" 306 307 firstBundleID := "bundleID" 308 secondBundleID := "bundleID2" 309 bundleIDs := []string{firstBundleID, secondBundleID} 310 firstAPIID := "apiID" 311 secondAPIID := "apiID2" 312 apiIDs := []string{firstAPIID, secondAPIID} 313 firstSpecID := "specID" 314 secondSpecID := "specID2" 315 316 // model APIDefs 317 apiDefFirstBundle := fixModelAPIDefinition(firstAPIID, "Foo", "Lorem Ipsum", group) 318 apiDefSecondBundle := fixModelAPIDefinition(secondAPIID, "Bar", "Lorem Ipsum", group) 319 320 apiDefsFirstBundle := []*model.APIDefinition{apiDefFirstBundle} 321 apiDefsSecondBundle := []*model.APIDefinition{apiDefSecondBundle} 322 323 apiDefPageFirstBundle := fixAPIDefinitionPage(apiDefsFirstBundle) 324 apiDefPageSecondBundle := fixAPIDefinitionPage(apiDefsSecondBundle) 325 apiDefPages := []*model.APIDefinitionPage{apiDefPageFirstBundle, apiDefPageSecondBundle} 326 327 // GQL APIDefs 328 gqlAPIDefFirstBundle := fixGQLAPIDefinition(firstAPIID, firstBundleID, name, desc, group) 329 gqlAPIDefSecondBundle := fixGQLAPIDefinition(secondAPIID, secondBundleID, name, desc, group) 330 331 gqlAPIDefsFirstBundle := []*graphql.APIDefinition{gqlAPIDefFirstBundle} 332 gqlAPIDefsSecondBundle := []*graphql.APIDefinition{gqlAPIDefSecondBundle} 333 334 gqlAPIDefPageFirstBundle := fixGQLAPIDefinitionPage(gqlAPIDefsFirstBundle) 335 gqlAPIDefPageSecondBundle := fixGQLAPIDefinitionPage(gqlAPIDefsSecondBundle) 336 gqlAPIDefPages := []*graphql.APIDefinitionPage{gqlAPIDefPageFirstBundle, gqlAPIDefPageSecondBundle} 337 338 // API BundleReferences 339 numberOfAPIsInFirstBundle := 1 340 numberOfAPIsInSecondBundle := 1 341 apiDefFirstBundleReference := fixModelAPIBundleReference(firstBundleID, firstAPIID) 342 apiDefSecondBundleReference := fixModelAPIBundleReference(secondBundleID, secondAPIID) 343 bundleRefsFirstAPI := []*model.BundleReference{apiDefFirstBundleReference} 344 bundleRefsSecondAPI := []*model.BundleReference{apiDefSecondBundleReference} 345 bundleRefs := []*model.BundleReference{apiDefFirstBundleReference, apiDefSecondBundleReference} 346 totalCounts := map[string]int{firstBundleID: numberOfAPIsInFirstBundle, secondBundleID: numberOfAPIsInSecondBundle} 347 348 // API Specs 349 apiDefFirstSpec := &model.Spec{ID: firstSpecID, ObjectType: model.APISpecReference, ObjectID: firstAPIID} 350 apiDefSecondSpec := &model.Spec{ID: secondSpecID, ObjectType: model.APISpecReference, ObjectID: secondAPIID} 351 specsFirstAPI := []*model.Spec{apiDefFirstSpec} 352 specsSecondAPI := []*model.Spec{apiDefSecondSpec} 353 specs := []*model.Spec{apiDefFirstSpec, apiDefSecondSpec} 354 355 txGen := txtest.NewTransactionContextGenerator(testErr) 356 357 first := 2 358 gqlAfter := graphql.PageCursor("test") 359 after := "test" 360 361 testCases := []struct { 362 Name string 363 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 364 ServiceFn func() *automock.APIService 365 ConverterFn func() *automock.APIConverter 366 SpecServiceFn func() *automock.SpecService 367 BundleReferenceFn func() *automock.BundleReferenceService 368 ExpectedResult []*graphql.APIDefinitionPage 369 ExpectedErr []error 370 }{ 371 { 372 Name: "Success", 373 TransactionerFn: txGen.ThatSucceeds, 374 ServiceFn: func() *automock.APIService { 375 svc := &automock.APIService{} 376 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(apiDefPages, nil).Once() 377 return svc 378 }, 379 SpecServiceFn: func() *automock.SpecService { 380 svc := &automock.SpecService{} 381 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.APISpecReference, apiIDs).Return(specs, nil).Once() 382 return svc 383 }, 384 BundleReferenceFn: func() *automock.BundleReferenceService { 385 svc := &automock.BundleReferenceService{} 386 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), model.BundleAPIReference, bundleIDs, first, after).Return(bundleRefs, totalCounts, nil).Once() 387 return svc 388 }, 389 ConverterFn: func() *automock.APIConverter { 390 conv := &automock.APIConverter{} 391 conv.On("MultipleToGraphQL", apiDefsFirstBundle, specsFirstAPI, bundleRefsFirstAPI).Return(gqlAPIDefsFirstBundle, nil).Once() 392 conv.On("MultipleToGraphQL", apiDefsSecondBundle, specsSecondAPI, bundleRefsSecondAPI).Return(gqlAPIDefsSecondBundle, nil).Once() 393 return conv 394 }, 395 ExpectedResult: gqlAPIDefPages, 396 ExpectedErr: nil, 397 }, 398 { 399 Name: "Returns error when transaction begin failed", 400 TransactionerFn: txGen.ThatFailsOnBegin, 401 ServiceFn: func() *automock.APIService { 402 return &automock.APIService{} 403 }, 404 SpecServiceFn: func() *automock.SpecService { 405 return &automock.SpecService{} 406 }, 407 BundleReferenceFn: func() *automock.BundleReferenceService { 408 return &automock.BundleReferenceService{} 409 }, 410 ConverterFn: func() *automock.APIConverter { 411 return &automock.APIConverter{} 412 }, 413 ExpectedResult: nil, 414 ExpectedErr: []error{testErr}, 415 }, 416 { 417 Name: "Returns error when APIs listing failed", 418 TransactionerFn: txGen.ThatDoesntExpectCommit, 419 ServiceFn: func() *automock.APIService { 420 svc := &automock.APIService{} 421 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(nil, testErr).Once() 422 return svc 423 }, 424 SpecServiceFn: func() *automock.SpecService { 425 return &automock.SpecService{} 426 }, 427 BundleReferenceFn: func() *automock.BundleReferenceService { 428 return &automock.BundleReferenceService{} 429 }, 430 ConverterFn: func() *automock.APIConverter { 431 return &automock.APIConverter{} 432 }, 433 ExpectedResult: nil, 434 ExpectedErr: []error{testErr}, 435 }, 436 { 437 Name: "Returns error when Specs retrieval failed", 438 TransactionerFn: txGen.ThatDoesntExpectCommit, 439 ServiceFn: func() *automock.APIService { 440 svc := &automock.APIService{} 441 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(apiDefPages, nil).Once() 442 return svc 443 }, 444 SpecServiceFn: func() *automock.SpecService { 445 svc := &automock.SpecService{} 446 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.APISpecReference, apiIDs).Return(nil, testErr).Once() 447 return svc 448 }, 449 BundleReferenceFn: func() *automock.BundleReferenceService { 450 return &automock.BundleReferenceService{} 451 }, 452 ConverterFn: func() *automock.APIConverter { 453 return &automock.APIConverter{} 454 }, 455 ExpectedResult: nil, 456 ExpectedErr: []error{testErr}, 457 }, 458 { 459 Name: "Returns error when BundleReferences retrieval failed", 460 TransactionerFn: txGen.ThatDoesntExpectCommit, 461 ServiceFn: func() *automock.APIService { 462 svc := &automock.APIService{} 463 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(apiDefPages, nil).Once() 464 return svc 465 }, 466 SpecServiceFn: func() *automock.SpecService { 467 svc := &automock.SpecService{} 468 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.APISpecReference, apiIDs).Return(specs, nil).Once() 469 return svc 470 }, 471 BundleReferenceFn: func() *automock.BundleReferenceService { 472 svc := &automock.BundleReferenceService{} 473 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), model.BundleAPIReference, bundleIDs, first, after).Return(nil, nil, testErr).Once() 474 return svc 475 }, 476 ConverterFn: func() *automock.APIConverter { 477 return &automock.APIConverter{} 478 }, 479 ExpectedResult: nil, 480 ExpectedErr: []error{testErr}, 481 }, 482 { 483 Name: "Returns error when there is no BundleReference for API", 484 TransactionerFn: txGen.ThatDoesntExpectCommit, 485 ServiceFn: func() *automock.APIService { 486 svc := &automock.APIService{} 487 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(apiDefPages, nil).Once() 488 return svc 489 }, 490 SpecServiceFn: func() *automock.SpecService { 491 svc := &automock.SpecService{} 492 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.APISpecReference, apiIDs).Return(specs, nil).Once() 493 return svc 494 }, 495 BundleReferenceFn: func() *automock.BundleReferenceService { 496 svc := &automock.BundleReferenceService{} 497 invalidBundleRefs := []*model.BundleReference{apiDefSecondBundleReference} 498 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), model.BundleAPIReference, bundleIDs, first, after).Return(invalidBundleRefs, totalCounts, nil).Once() 499 return svc 500 }, 501 ConverterFn: func() *automock.APIConverter { 502 conv := &automock.APIConverter{} 503 return conv 504 }, 505 ExpectedResult: nil, 506 ExpectedErr: []error{errors.New("could not find BundleReference for API with id")}, 507 }, 508 { 509 Name: "Returns error when converting to GraphQL failed", 510 TransactionerFn: txGen.ThatDoesntExpectCommit, 511 ServiceFn: func() *automock.APIService { 512 svc := &automock.APIService{} 513 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(apiDefPages, nil).Once() 514 return svc 515 }, 516 SpecServiceFn: func() *automock.SpecService { 517 svc := &automock.SpecService{} 518 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.APISpecReference, apiIDs).Return(specs, nil).Once() 519 return svc 520 }, 521 BundleReferenceFn: func() *automock.BundleReferenceService { 522 svc := &automock.BundleReferenceService{} 523 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), model.BundleAPIReference, bundleIDs, first, after).Return(bundleRefs, totalCounts, nil).Once() 524 return svc 525 }, 526 ConverterFn: func() *automock.APIConverter { 527 conv := &automock.APIConverter{} 528 conv.On("MultipleToGraphQL", apiDefsFirstBundle, specsFirstAPI, bundleRefsFirstAPI).Return(nil, testErr).Once() 529 return conv 530 }, 531 ExpectedResult: nil, 532 ExpectedErr: []error{testErr}, 533 }, 534 { 535 Name: "Returns error when transaction commit failed", 536 TransactionerFn: txGen.ThatFailsOnCommit, 537 ServiceFn: func() *automock.APIService { 538 svc := &automock.APIService{} 539 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(apiDefPages, nil).Once() 540 return svc 541 }, 542 SpecServiceFn: func() *automock.SpecService { 543 svc := &automock.SpecService{} 544 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.APISpecReference, apiIDs).Return(specs, nil).Once() 545 return svc 546 }, 547 BundleReferenceFn: func() *automock.BundleReferenceService { 548 svc := &automock.BundleReferenceService{} 549 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), model.BundleAPIReference, bundleIDs, first, after).Return(bundleRefs, totalCounts, nil).Once() 550 return svc 551 }, 552 ConverterFn: func() *automock.APIConverter { 553 conv := &automock.APIConverter{} 554 conv.On("MultipleToGraphQL", apiDefsFirstBundle, specsFirstAPI, bundleRefsFirstAPI).Return(gqlAPIDefsFirstBundle, nil).Once() 555 conv.On("MultipleToGraphQL", apiDefsSecondBundle, specsSecondAPI, bundleRefsSecondAPI).Return(gqlAPIDefsSecondBundle, nil).Once() 556 return conv 557 }, 558 ExpectedResult: nil, 559 ExpectedErr: []error{testErr}, 560 }, 561 } 562 563 for _, testCase := range testCases { 564 t.Run(testCase.Name, func(t *testing.T) { 565 // GIVEN 566 persist, transact := testCase.TransactionerFn() 567 svc := testCase.ServiceFn() 568 converter := testCase.ConverterFn() 569 specService := testCase.SpecServiceFn() 570 bundleRefService := testCase.BundleReferenceFn() 571 572 firstBundleParams := dataloader.ParamAPIDef{ID: firstBundleID, Ctx: context.TODO(), First: &first, After: &gqlAfter} 573 secondBundleParams := dataloader.ParamAPIDef{ID: secondBundleID, Ctx: context.TODO(), First: &first, After: &gqlAfter} 574 keys := []dataloader.ParamAPIDef{firstBundleParams, secondBundleParams} 575 resolver := bundle.NewResolver(transact, nil, nil, bundleRefService, svc, nil, nil, nil, nil, converter, nil, nil, specService, nil) 576 // WHEN 577 result, err := resolver.APIDefinitionsDataLoader(keys) 578 579 // then 580 assert.Equal(t, testCase.ExpectedResult, result) 581 if testCase.ExpectedErr != nil { 582 require.Error(t, err[0]) 583 assert.Contains(t, err[0].Error(), testCase.ExpectedErr[0].Error()) 584 } else { 585 require.Nil(t, err) 586 } 587 588 persist.AssertExpectations(t) 589 transact.AssertExpectations(t) 590 svc.AssertExpectations(t) 591 converter.AssertExpectations(t) 592 specService.AssertExpectations(t) 593 bundleRefService.AssertExpectations(t) 594 }) 595 } 596 597 t.Run("Returns error when there are no Bundles", func(t *testing.T) { 598 resolver := bundle.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) 599 // WHEN 600 _, err := resolver.APIDefinitionsDataLoader([]dataloader.ParamAPIDef{}) 601 // THEN 602 require.Error(t, err[0]) 603 assert.EqualError(t, err[0], apperrors.NewInternalError("No Bundles found").Error()) 604 }) 605 606 t.Run("Returns error when start cursor is nil", func(t *testing.T) { 607 params := dataloader.ParamAPIDef{ID: firstBundleID, Ctx: context.TODO(), First: nil, After: &gqlAfter} 608 keys := []dataloader.ParamAPIDef{params} 609 610 resolver := bundle.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) 611 // WHEN 612 _, err := resolver.APIDefinitionsDataLoader(keys) 613 // THEN 614 require.Error(t, err[0]) 615 assert.EqualError(t, err[0], apperrors.NewInvalidDataError("missing required parameter 'first'").Error()) 616 }) 617 } 618 619 func TestResolver_Event(t *testing.T) { 620 { 621 // GIVEN 622 id := "bar" 623 bndlID := "1" 624 var nilBundleID *string 625 modelEvent := fixModelEventAPIDefinition(id, "name", "bar", "test") 626 modelSpec := &model.Spec{ 627 ID: id, 628 ObjectType: model.EventSpecReference, 629 ObjectID: id, 630 } 631 modelBundleRef := &model.BundleReference{ 632 BundleID: &bndlID, 633 ObjectType: model.BundleEventReference, 634 ObjectID: &id, 635 } 636 gqlEvent := fixGQLEventDefinition(id, bndlID, "name", "bar", "test") 637 app := fixGQLBundle("foo", "foo", "foo") 638 testErr := errors.New("Test error") 639 txGen := txtest.NewTransactionContextGenerator(testErr) 640 641 testCases := []struct { 642 Name string 643 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 644 ServiceFn func() *automock.EventService 645 SpecServiceFn func() *automock.SpecService 646 BundleRefServiceFn func() *automock.BundleReferenceService 647 ConverterFn func() *automock.EventConverter 648 InputID string 649 Bundle *graphql.Bundle 650 ExpectedEvent *graphql.EventDefinition 651 ExpectedErr error 652 }{ 653 { 654 Name: "Success", 655 TransactionerFn: txGen.ThatSucceeds, 656 ServiceFn: func() *automock.EventService { 657 svc := &automock.EventService{} 658 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelEvent, nil).Once() 659 660 return svc 661 }, 662 SpecServiceFn: func() *automock.SpecService { 663 svc := &automock.SpecService{} 664 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.EventSpecReference, modelEvent.ID).Return(modelSpec, nil).Once() 665 return svc 666 }, 667 BundleRefServiceFn: func() *automock.BundleReferenceService { 668 svc := &automock.BundleReferenceService{} 669 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleEventReference, &modelEvent.ID, nilBundleID).Return(modelBundleRef, nil).Once() 670 return svc 671 }, 672 ConverterFn: func() *automock.EventConverter { 673 conv := &automock.EventConverter{} 674 conv.On("ToGraphQL", modelEvent, modelSpec, modelBundleRef).Return(gqlEvent, nil).Once() 675 return conv 676 }, 677 InputID: "foo", 678 Bundle: app, 679 ExpectedEvent: gqlEvent, 680 ExpectedErr: nil, 681 }, 682 { 683 Name: "Returns error when bundle retrieval failed", 684 TransactionerFn: txGen.ThatDoesntExpectCommit, 685 ServiceFn: func() *automock.EventService { 686 svc := &automock.EventService{} 687 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, testErr).Once() 688 689 return svc 690 }, 691 SpecServiceFn: func() *automock.SpecService { 692 return &automock.SpecService{} 693 }, 694 BundleRefServiceFn: func() *automock.BundleReferenceService { 695 return &automock.BundleReferenceService{} 696 }, 697 ConverterFn: func() *automock.EventConverter { 698 return &automock.EventConverter{} 699 }, 700 InputID: "foo", 701 Bundle: app, 702 ExpectedEvent: nil, 703 ExpectedErr: testErr, 704 }, 705 { 706 Name: "Returns null when api for bundle not found", 707 TransactionerFn: txGen.ThatSucceeds, 708 ServiceFn: func() *automock.EventService { 709 svc := &automock.EventService{} 710 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, apperrors.NewNotFoundError(resource.Bundle, "")).Once() 711 return svc 712 }, 713 SpecServiceFn: func() *automock.SpecService { 714 return &automock.SpecService{} 715 }, 716 BundleRefServiceFn: func() *automock.BundleReferenceService { 717 return &automock.BundleReferenceService{} 718 }, 719 ConverterFn: func() *automock.EventConverter { 720 return &automock.EventConverter{} 721 }, 722 InputID: "foo", 723 Bundle: app, 724 ExpectedEvent: nil, 725 ExpectedErr: nil, 726 }, 727 { 728 Name: "Returns error when Spec retrieval failed", 729 TransactionerFn: txGen.ThatDoesntExpectCommit, 730 ServiceFn: func() *automock.EventService { 731 svc := &automock.EventService{} 732 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelEvent, nil).Once() 733 734 return svc 735 }, 736 SpecServiceFn: func() *automock.SpecService { 737 svc := &automock.SpecService{} 738 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.EventSpecReference, modelEvent.ID).Return(nil, testErr).Once() 739 return svc 740 }, 741 BundleRefServiceFn: func() *automock.BundleReferenceService { 742 return &automock.BundleReferenceService{} 743 }, 744 ConverterFn: func() *automock.EventConverter { 745 return &automock.EventConverter{} 746 }, 747 InputID: "foo", 748 Bundle: app, 749 ExpectedEvent: nil, 750 ExpectedErr: testErr, 751 }, 752 { 753 Name: "Returns error when BundleReference retrieval failed", 754 TransactionerFn: txGen.ThatDoesntExpectCommit, 755 ServiceFn: func() *automock.EventService { 756 svc := &automock.EventService{} 757 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelEvent, nil).Once() 758 759 return svc 760 }, 761 SpecServiceFn: func() *automock.SpecService { 762 svc := &automock.SpecService{} 763 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.EventSpecReference, modelEvent.ID).Return(modelSpec, nil).Once() 764 return svc 765 }, 766 BundleRefServiceFn: func() *automock.BundleReferenceService { 767 svc := &automock.BundleReferenceService{} 768 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleEventReference, &modelEvent.ID, nilBundleID).Return(nil, testErr).Once() 769 return svc 770 }, 771 ConverterFn: func() *automock.EventConverter { 772 return &automock.EventConverter{} 773 }, 774 InputID: "foo", 775 Bundle: app, 776 ExpectedEvent: nil, 777 ExpectedErr: testErr, 778 }, 779 { 780 Name: "Returns error when converting to GraphQL failed", 781 TransactionerFn: txGen.ThatDoesntExpectCommit, 782 ServiceFn: func() *automock.EventService { 783 svc := &automock.EventService{} 784 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelEvent, nil).Once() 785 786 return svc 787 }, 788 SpecServiceFn: func() *automock.SpecService { 789 svc := &automock.SpecService{} 790 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.EventSpecReference, modelEvent.ID).Return(modelSpec, nil).Once() 791 return svc 792 }, 793 BundleRefServiceFn: func() *automock.BundleReferenceService { 794 svc := &automock.BundleReferenceService{} 795 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleEventReference, &modelEvent.ID, nilBundleID).Return(modelBundleRef, nil).Once() 796 return svc 797 }, 798 ConverterFn: func() *automock.EventConverter { 799 conv := &automock.EventConverter{} 800 conv.On("ToGraphQL", modelEvent, modelSpec, modelBundleRef).Return(nil, testErr).Once() 801 return conv 802 }, 803 InputID: "foo", 804 Bundle: app, 805 ExpectedEvent: nil, 806 ExpectedErr: testErr, 807 }, 808 { 809 Name: "Returns error when commit begin error", 810 TransactionerFn: txGen.ThatFailsOnBegin, 811 ServiceFn: func() *automock.EventService { 812 return &automock.EventService{} 813 }, 814 SpecServiceFn: func() *automock.SpecService { 815 return &automock.SpecService{} 816 }, 817 BundleRefServiceFn: func() *automock.BundleReferenceService { 818 return &automock.BundleReferenceService{} 819 }, 820 ConverterFn: func() *automock.EventConverter { 821 return &automock.EventConverter{} 822 }, 823 InputID: "foo", 824 Bundle: app, 825 ExpectedEvent: nil, 826 ExpectedErr: testErr, 827 }, 828 { 829 Name: "Returns error when commit failed", 830 TransactionerFn: txGen.ThatFailsOnCommit, 831 ServiceFn: func() *automock.EventService { 832 svc := &automock.EventService{} 833 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelEvent, nil).Once() 834 835 return svc 836 }, 837 SpecServiceFn: func() *automock.SpecService { 838 svc := &automock.SpecService{} 839 svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.EventSpecReference, modelEvent.ID).Return(modelSpec, nil).Once() 840 return svc 841 }, 842 BundleRefServiceFn: func() *automock.BundleReferenceService { 843 svc := &automock.BundleReferenceService{} 844 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleEventReference, &modelEvent.ID, nilBundleID).Return(modelBundleRef, nil).Once() 845 return svc 846 }, 847 ConverterFn: func() *automock.EventConverter { 848 conv := &automock.EventConverter{} 849 conv.On("ToGraphQL", modelEvent, modelSpec, modelBundleRef).Return(gqlEvent, nil).Once() 850 return conv 851 }, 852 InputID: "foo", 853 Bundle: app, 854 ExpectedEvent: nil, 855 ExpectedErr: testErr, 856 }, 857 } 858 859 for _, testCase := range testCases { 860 t.Run(testCase.Name, func(t *testing.T) { 861 persist, transact := testCase.TransactionerFn() 862 svc := testCase.ServiceFn() 863 converter := testCase.ConverterFn() 864 specSvc := testCase.SpecServiceFn() 865 bndlRefService := testCase.BundleRefServiceFn() 866 867 resolver := bundle.NewResolver(transact, nil, nil, bndlRefService, nil, svc, nil, nil, nil, nil, converter, nil, specSvc, nil) 868 869 // WHEN 870 result, err := resolver.EventDefinition(context.TODO(), testCase.Bundle, testCase.InputID) 871 872 // then 873 assert.Equal(t, testCase.ExpectedEvent, result) 874 if testCase.ExpectedErr != nil { 875 require.Error(t, err) 876 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 877 } else { 878 require.Nil(t, err) 879 } 880 881 svc.AssertExpectations(t) 882 persist.AssertExpectations(t) 883 transact.AssertExpectations(t) 884 converter.AssertExpectations(t) 885 specSvc.AssertExpectations(t) 886 bndlRefService.AssertExpectations(t) 887 }) 888 } 889 } 890 } 891 892 func TestResolver_Events(t *testing.T) { 893 // GIVEN 894 testErr := errors.New("test error") 895 group := "group" 896 desc := "desc" 897 name := "test name" 898 899 firstBundleID := "bundleID" 900 secondBundleID := "bundleID2" 901 bundleIDs := []string{firstBundleID, secondBundleID} 902 firstEventID := "eventID" 903 secondEventID := "eventID2" 904 eventIDs := []string{firstEventID, secondEventID} 905 firstSpecID := "specID" 906 secondSpecID := "specID2" 907 908 // model Events 909 eventFirstBundle := fixModelEventAPIDefinition(firstEventID, "Foo", "Lorem Ipsum", group) 910 eventSecondBundle := fixModelEventAPIDefinition(secondEventID, "Bar", "Lorem Ipsum", group) 911 912 eventsFirstBundle := []*model.EventDefinition{eventFirstBundle} 913 eventsSecondBundle := []*model.EventDefinition{eventSecondBundle} 914 915 eventPageFirstBundle := fixEventAPIDefinitionPage(eventsFirstBundle) 916 eventPageSecondBundle := fixEventAPIDefinitionPage(eventsSecondBundle) 917 eventPages := []*model.EventDefinitionPage{eventPageFirstBundle, eventPageSecondBundle} 918 919 // GQL Events 920 gqlEventFirstBundle := fixGQLEventDefinition(firstEventID, firstBundleID, name, desc, group) 921 gqlEventSecondBundle := fixGQLEventDefinition(secondEventID, secondBundleID, name, desc, group) 922 923 gqlEventsFirstBundle := []*graphql.EventDefinition{gqlEventFirstBundle} 924 gqlEventsSecondBundle := []*graphql.EventDefinition{gqlEventSecondBundle} 925 926 gqlEventPageFirstBundle := fixGQLEventDefinitionPage(gqlEventsFirstBundle) 927 gqlEventPageSecondBundle := fixGQLEventDefinitionPage(gqlEventsSecondBundle) 928 gqlEventPages := []*graphql.EventDefinitionPage{gqlEventPageFirstBundle, gqlEventPageSecondBundle} 929 930 // Event BundleReferences 931 numberOfEventsInFirstBundle := 1 932 numberOfEventsInSecondBundle := 1 933 eventFirstBundleReference := fixModelEventBundleReference(firstBundleID, firstEventID) 934 eventSecondBundleReference := fixModelEventBundleReference(secondBundleID, secondEventID) 935 bundleRefsFirstEvent := []*model.BundleReference{eventFirstBundleReference} 936 bundleRefsSecondEvent := []*model.BundleReference{eventSecondBundleReference} 937 bundleRefs := []*model.BundleReference{eventFirstBundleReference, eventSecondBundleReference} 938 totalCounts := map[string]int{firstBundleID: numberOfEventsInFirstBundle, secondBundleID: numberOfEventsInSecondBundle} 939 940 // Event Specs 941 eventFirstSpec := &model.Spec{ID: firstSpecID, ObjectType: model.EventSpecReference, ObjectID: firstEventID} 942 eventSecondSpec := &model.Spec{ID: secondSpecID, ObjectType: model.EventSpecReference, ObjectID: secondEventID} 943 specsFirstEvent := []*model.Spec{eventFirstSpec} 944 specsSecondEvent := []*model.Spec{eventSecondSpec} 945 specs := []*model.Spec{eventFirstSpec, eventSecondSpec} 946 947 txGen := txtest.NewTransactionContextGenerator(testErr) 948 949 first := 2 950 gqlAfter := graphql.PageCursor("test") 951 after := "test" 952 953 testCases := []struct { 954 Name string 955 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 956 ServiceFn func() *automock.EventService 957 ConverterFn func() *automock.EventConverter 958 SpecServiceFn func() *automock.SpecService 959 BundleReferenceFn func() *automock.BundleReferenceService 960 ExpectedResult []*graphql.EventDefinitionPage 961 ExpectedErr []error 962 }{ 963 { 964 Name: "Success", 965 TransactionerFn: txGen.ThatSucceeds, 966 ServiceFn: func() *automock.EventService { 967 svc := &automock.EventService{} 968 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(eventPages, nil).Once() 969 return svc 970 }, 971 SpecServiceFn: func() *automock.SpecService { 972 svc := &automock.SpecService{} 973 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.EventSpecReference, eventIDs).Return(specs, nil).Once() 974 return svc 975 }, 976 BundleReferenceFn: func() *automock.BundleReferenceService { 977 svc := &automock.BundleReferenceService{} 978 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), model.BundleEventReference, bundleIDs, first, after).Return(bundleRefs, totalCounts, nil).Once() 979 return svc 980 }, 981 ConverterFn: func() *automock.EventConverter { 982 conv := &automock.EventConverter{} 983 conv.On("MultipleToGraphQL", eventsFirstBundle, specsFirstEvent, bundleRefsFirstEvent).Return(gqlEventsFirstBundle, nil).Once() 984 conv.On("MultipleToGraphQL", eventsSecondBundle, specsSecondEvent, bundleRefsSecondEvent).Return(gqlEventsSecondBundle, nil).Once() 985 return conv 986 }, 987 ExpectedResult: gqlEventPages, 988 ExpectedErr: nil, 989 }, 990 { 991 Name: "Returns error when transaction begin failed", 992 TransactionerFn: txGen.ThatFailsOnBegin, 993 ServiceFn: func() *automock.EventService { 994 return &automock.EventService{} 995 }, 996 SpecServiceFn: func() *automock.SpecService { 997 return &automock.SpecService{} 998 }, 999 BundleReferenceFn: func() *automock.BundleReferenceService { 1000 return &automock.BundleReferenceService{} 1001 }, 1002 ConverterFn: func() *automock.EventConverter { 1003 return &automock.EventConverter{} 1004 }, 1005 ExpectedResult: nil, 1006 ExpectedErr: []error{testErr}, 1007 }, 1008 { 1009 Name: "Returns error when Events listing failed", 1010 TransactionerFn: txGen.ThatDoesntExpectCommit, 1011 ServiceFn: func() *automock.EventService { 1012 svc := &automock.EventService{} 1013 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(nil, testErr).Once() 1014 return svc 1015 }, 1016 SpecServiceFn: func() *automock.SpecService { 1017 return &automock.SpecService{} 1018 }, 1019 BundleReferenceFn: func() *automock.BundleReferenceService { 1020 return &automock.BundleReferenceService{} 1021 }, 1022 ConverterFn: func() *automock.EventConverter { 1023 return &automock.EventConverter{} 1024 }, 1025 ExpectedResult: nil, 1026 ExpectedErr: []error{testErr}, 1027 }, 1028 { 1029 Name: "Returns error when Specs retrieval failed", 1030 TransactionerFn: txGen.ThatDoesntExpectCommit, 1031 ServiceFn: func() *automock.EventService { 1032 svc := &automock.EventService{} 1033 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(eventPages, nil).Once() 1034 return svc 1035 }, 1036 SpecServiceFn: func() *automock.SpecService { 1037 svc := &automock.SpecService{} 1038 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.EventSpecReference, eventIDs).Return(nil, testErr).Once() 1039 return svc 1040 }, 1041 BundleReferenceFn: func() *automock.BundleReferenceService { 1042 return &automock.BundleReferenceService{} 1043 }, 1044 ConverterFn: func() *automock.EventConverter { 1045 return &automock.EventConverter{} 1046 }, 1047 ExpectedResult: nil, 1048 ExpectedErr: []error{testErr}, 1049 }, 1050 { 1051 Name: "Returns error when BundleReferences retrieval failed", 1052 TransactionerFn: txGen.ThatDoesntExpectCommit, 1053 ServiceFn: func() *automock.EventService { 1054 svc := &automock.EventService{} 1055 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(eventPages, nil).Once() 1056 return svc 1057 }, 1058 SpecServiceFn: func() *automock.SpecService { 1059 svc := &automock.SpecService{} 1060 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.EventSpecReference, eventIDs).Return(specs, nil).Once() 1061 return svc 1062 }, 1063 BundleReferenceFn: func() *automock.BundleReferenceService { 1064 svc := &automock.BundleReferenceService{} 1065 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), model.BundleEventReference, bundleIDs, first, after).Return(nil, nil, testErr).Once() 1066 return svc 1067 }, 1068 ConverterFn: func() *automock.EventConverter { 1069 return &automock.EventConverter{} 1070 }, 1071 ExpectedResult: nil, 1072 ExpectedErr: []error{testErr}, 1073 }, 1074 { 1075 Name: "Returns error when converting to GraphQL failed", 1076 TransactionerFn: txGen.ThatDoesntExpectCommit, 1077 ServiceFn: func() *automock.EventService { 1078 svc := &automock.EventService{} 1079 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(eventPages, nil).Once() 1080 return svc 1081 }, 1082 SpecServiceFn: func() *automock.SpecService { 1083 svc := &automock.SpecService{} 1084 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.EventSpecReference, eventIDs).Return(specs, nil).Once() 1085 return svc 1086 }, 1087 BundleReferenceFn: func() *automock.BundleReferenceService { 1088 svc := &automock.BundleReferenceService{} 1089 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), model.BundleEventReference, bundleIDs, first, after).Return(bundleRefs, totalCounts, nil).Once() 1090 return svc 1091 }, 1092 ConverterFn: func() *automock.EventConverter { 1093 conv := &automock.EventConverter{} 1094 conv.On("MultipleToGraphQL", eventsFirstBundle, specsFirstEvent, bundleRefsFirstEvent).Return(nil, testErr).Once() 1095 return conv 1096 }, 1097 ExpectedResult: nil, 1098 ExpectedErr: []error{testErr}, 1099 }, 1100 { 1101 Name: "Returns error when transaction commit failed", 1102 TransactionerFn: txGen.ThatFailsOnCommit, 1103 ServiceFn: func() *automock.EventService { 1104 svc := &automock.EventService{} 1105 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), bundleIDs, first, after).Return(eventPages, nil).Once() 1106 return svc 1107 }, 1108 SpecServiceFn: func() *automock.SpecService { 1109 svc := &automock.SpecService{} 1110 svc.On("ListByReferenceObjectIDs", txtest.CtxWithDBMatcher(), model.EventSpecReference, eventIDs).Return(specs, nil).Once() 1111 return svc 1112 }, 1113 BundleReferenceFn: func() *automock.BundleReferenceService { 1114 svc := &automock.BundleReferenceService{} 1115 svc.On("ListByBundleIDs", txtest.CtxWithDBMatcher(), model.BundleEventReference, bundleIDs, first, after).Return(bundleRefs, totalCounts, nil).Once() 1116 return svc 1117 }, 1118 ConverterFn: func() *automock.EventConverter { 1119 conv := &automock.EventConverter{} 1120 conv.On("MultipleToGraphQL", eventsFirstBundle, specsFirstEvent, bundleRefsFirstEvent).Return(gqlEventsFirstBundle, nil).Once() 1121 conv.On("MultipleToGraphQL", eventsSecondBundle, specsSecondEvent, bundleRefsSecondEvent).Return(gqlEventsSecondBundle, nil).Once() 1122 return conv 1123 }, 1124 ExpectedResult: nil, 1125 ExpectedErr: []error{testErr}, 1126 }, 1127 } 1128 1129 for _, testCase := range testCases { 1130 t.Run(testCase.Name, func(t *testing.T) { 1131 // GIVEN 1132 persist, transact := testCase.TransactionerFn() 1133 svc := testCase.ServiceFn() 1134 converter := testCase.ConverterFn() 1135 specService := testCase.SpecServiceFn() 1136 bundleRefService := testCase.BundleReferenceFn() 1137 1138 firstBundleParams := dataloader.ParamEventDef{ID: firstBundleID, Ctx: context.TODO(), First: &first, After: &gqlAfter} 1139 secondBundleParams := dataloader.ParamEventDef{ID: secondBundleID, Ctx: context.TODO(), First: &first, After: &gqlAfter} 1140 keys := []dataloader.ParamEventDef{firstBundleParams, secondBundleParams} 1141 resolver := bundle.NewResolver(transact, nil, nil, bundleRefService, nil, svc, nil, nil, nil, nil, converter, nil, specService, nil) 1142 // WHEN 1143 result, err := resolver.EventDefinitionsDataLoader(keys) 1144 1145 // then 1146 assert.Equal(t, testCase.ExpectedResult, result) 1147 if testCase.ExpectedErr != nil { 1148 require.Error(t, err[0]) 1149 assert.Contains(t, err[0].Error(), testCase.ExpectedErr[0].Error()) 1150 } else { 1151 require.Nil(t, err) 1152 } 1153 1154 persist.AssertExpectations(t) 1155 transact.AssertExpectations(t) 1156 svc.AssertExpectations(t) 1157 converter.AssertExpectations(t) 1158 specService.AssertExpectations(t) 1159 bundleRefService.AssertExpectations(t) 1160 }) 1161 } 1162 1163 t.Run("Returns error when there are no Bundles", func(t *testing.T) { 1164 resolver := bundle.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) 1165 // WHEN 1166 _, err := resolver.EventDefinitionsDataLoader([]dataloader.ParamEventDef{}) 1167 // THEN 1168 require.Error(t, err[0]) 1169 assert.EqualError(t, err[0], apperrors.NewInternalError("No Bundles found").Error()) 1170 }) 1171 1172 t.Run("Returns error when start cursor is nil", func(t *testing.T) { 1173 params := dataloader.ParamEventDef{ID: firstBundleID, Ctx: context.TODO(), First: nil, After: &gqlAfter} 1174 keys := []dataloader.ParamEventDef{params} 1175 1176 resolver := bundle.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) 1177 // WHEN 1178 _, err := resolver.EventDefinitionsDataLoader(keys) 1179 // THEN 1180 require.Error(t, err[0]) 1181 assert.EqualError(t, err[0], apperrors.NewInvalidDataError("missing required parameter 'first'").Error()) 1182 }) 1183 } 1184 1185 func TestResolver_Document(t *testing.T) { 1186 // GIVEN 1187 id := "bar" 1188 1189 modelDoc := fixModelDocument("foo", id) 1190 gqlDoc := fixGQLDocument(id) 1191 bndl := fixGQLBundle("foo", "foo", "foo") 1192 testErr := errors.New("Test error") 1193 txGen := txtest.NewTransactionContextGenerator(testErr) 1194 1195 testCases := []struct { 1196 Name string 1197 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 1198 ServiceFn func() *automock.DocumentService 1199 ConverterFn func() *automock.DocumentConverter 1200 InputID string 1201 Bundle *graphql.Bundle 1202 ExpectedDoc *graphql.Document 1203 ExpectedErr error 1204 }{ 1205 { 1206 Name: "Success", 1207 TransactionerFn: txGen.ThatSucceeds, 1208 ServiceFn: func() *automock.DocumentService { 1209 svc := &automock.DocumentService{} 1210 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelDoc, nil).Once() 1211 1212 return svc 1213 }, 1214 ConverterFn: func() *automock.DocumentConverter { 1215 conv := &automock.DocumentConverter{} 1216 conv.On("ToGraphQL", modelDoc).Return(gqlDoc).Once() 1217 return conv 1218 }, 1219 InputID: "foo", 1220 Bundle: bndl, 1221 ExpectedDoc: gqlDoc, 1222 ExpectedErr: nil, 1223 }, 1224 { 1225 Name: "Returns error when application retrieval failed", 1226 TransactionerFn: txGen.ThatDoesntExpectCommit, 1227 ServiceFn: func() *automock.DocumentService { 1228 svc := &automock.DocumentService{} 1229 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, testErr).Once() 1230 1231 return svc 1232 }, 1233 ConverterFn: func() *automock.DocumentConverter { 1234 conv := &automock.DocumentConverter{} 1235 return conv 1236 }, 1237 InputID: "foo", 1238 Bundle: bndl, 1239 ExpectedDoc: nil, 1240 ExpectedErr: testErr, 1241 }, 1242 { 1243 Name: "Returns null when document for bundle not found", 1244 TransactionerFn: txGen.ThatSucceeds, 1245 ServiceFn: func() *automock.DocumentService { 1246 svc := &automock.DocumentService{} 1247 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, apperrors.NewNotFoundError(resource.Bundle, "")).Once() 1248 1249 return svc 1250 }, 1251 ConverterFn: func() *automock.DocumentConverter { 1252 conv := &automock.DocumentConverter{} 1253 return conv 1254 }, 1255 InputID: "foo", 1256 Bundle: bndl, 1257 ExpectedDoc: nil, 1258 ExpectedErr: nil, 1259 }, 1260 { 1261 Name: "Returns error when commit begin error", 1262 TransactionerFn: txGen.ThatFailsOnBegin, 1263 ServiceFn: func() *automock.DocumentService { 1264 svc := &automock.DocumentService{} 1265 1266 return svc 1267 }, 1268 ConverterFn: func() *automock.DocumentConverter { 1269 conv := &automock.DocumentConverter{} 1270 return conv 1271 }, 1272 InputID: "foo", 1273 Bundle: bndl, 1274 ExpectedDoc: nil, 1275 ExpectedErr: testErr, 1276 }, 1277 { 1278 Name: "Returns error when commit failed", 1279 TransactionerFn: txGen.ThatFailsOnCommit, 1280 ServiceFn: func() *automock.DocumentService { 1281 svc := &automock.DocumentService{} 1282 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelDoc, nil).Once() 1283 return svc 1284 }, 1285 ConverterFn: func() *automock.DocumentConverter { 1286 conv := &automock.DocumentConverter{} 1287 return conv 1288 }, 1289 InputID: "foo", 1290 Bundle: bndl, 1291 ExpectedDoc: nil, 1292 ExpectedErr: testErr, 1293 }, 1294 } 1295 1296 for _, testCase := range testCases { 1297 t.Run(testCase.Name, func(t *testing.T) { 1298 persist, transact := testCase.TransactionerFn() 1299 svc := testCase.ServiceFn() 1300 converter := testCase.ConverterFn() 1301 1302 resolver := bundle.NewResolver(transact, nil, nil, nil, nil, nil, svc, nil, nil, nil, nil, converter, nil, nil) 1303 1304 // WHEN 1305 result, err := resolver.Document(context.TODO(), testCase.Bundle, testCase.InputID) 1306 1307 // then 1308 assert.Equal(t, testCase.ExpectedDoc, result) 1309 assert.Equal(t, testCase.ExpectedErr, err) 1310 1311 svc.AssertExpectations(t) 1312 persist.AssertExpectations(t) 1313 transact.AssertExpectations(t) 1314 converter.AssertExpectations(t) 1315 }) 1316 } 1317 } 1318 1319 func TestResolver_Documents(t *testing.T) { 1320 // GIVEN 1321 contextParam := txtest.CtxWithDBMatcher() 1322 1323 firstBundleID := "bundleID" 1324 secondBundleID := "bundleID2" 1325 bundleIDs := []string{firstBundleID, secondBundleID} 1326 firstDocID := "docID" 1327 secondDocID := "docID2" 1328 1329 // model Docs 1330 docFirstBundle := fixModelDocument(firstBundleID, firstDocID) 1331 docSecondBundle := fixModelDocument(secondBundleID, secondDocID) 1332 1333 docsFirstBundle := []*model.Document{docFirstBundle} 1334 docsSecondBundle := []*model.Document{docSecondBundle} 1335 1336 docPageFirstBundle := fixModelDocumentPage(docsFirstBundle) 1337 docPageSecondBundle := fixModelDocumentPage(docsSecondBundle) 1338 docPages := []*model.DocumentPage{docPageFirstBundle, docPageSecondBundle} 1339 1340 // GQL Docs 1341 gqlDocFirstBundle := fixGQLDocument(firstDocID) 1342 gqlDocSecondBundle := fixGQLDocument(secondDocID) 1343 1344 gqlDocsFirstBundle := []*graphql.Document{gqlDocFirstBundle} 1345 gqlDocsSecondBundle := []*graphql.Document{gqlDocSecondBundle} 1346 1347 gqlDocPageFirstBundle := fixGQLDocumentPage(gqlDocsFirstBundle) 1348 gqlDocPageSecondBundle := fixGQLDocumentPage(gqlDocsSecondBundle) 1349 gqlDocPages := []*graphql.DocumentPage{gqlDocPageFirstBundle, gqlDocPageSecondBundle} 1350 1351 first := 2 1352 gqlAfter := graphql.PageCursor("test") 1353 after := "test" 1354 testErr := errors.New("Test error") 1355 1356 testCases := []struct { 1357 Name string 1358 ServiceFn func() *automock.DocumentService 1359 ConverterFn func() *automock.DocumentConverter 1360 PersistenceFn func() *persistenceautomock.PersistenceTx 1361 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 1362 ExpectedResult []*graphql.DocumentPage 1363 ExpectedErr []error 1364 }{ 1365 { 1366 Name: "Success", 1367 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 1368 TransactionerFn: txtest.TransactionerThatSucceeds, 1369 ServiceFn: func() *automock.DocumentService { 1370 svc := &automock.DocumentService{} 1371 svc.On("ListByBundleIDs", contextParam, bundleIDs, first, after).Return(docPages, nil).Once() 1372 return svc 1373 }, 1374 ConverterFn: func() *automock.DocumentConverter { 1375 conv := &automock.DocumentConverter{} 1376 conv.On("MultipleToGraphQL", docsFirstBundle).Return(gqlDocsFirstBundle).Once() 1377 conv.On("MultipleToGraphQL", docsSecondBundle).Return(gqlDocsSecondBundle).Once() 1378 return conv 1379 }, 1380 ExpectedResult: gqlDocPages, 1381 ExpectedErr: nil, 1382 }, 1383 { 1384 Name: "Returns error when document listing failed", 1385 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 1386 TransactionerFn: txtest.TransactionerThatSucceeds, 1387 ServiceFn: func() *automock.DocumentService { 1388 svc := &automock.DocumentService{} 1389 svc.On("ListByBundleIDs", contextParam, bundleIDs, first, after).Return(nil, testErr).Once() 1390 return svc 1391 }, 1392 ConverterFn: func() *automock.DocumentConverter { 1393 conv := &automock.DocumentConverter{} 1394 return conv 1395 }, 1396 ExpectedResult: nil, 1397 ExpectedErr: []error{testErr}, 1398 }, 1399 } 1400 1401 for _, testCase := range testCases { 1402 t.Run(testCase.Name, func(t *testing.T) { 1403 svc := testCase.ServiceFn() 1404 converter := testCase.ConverterFn() 1405 persistTx := testCase.PersistenceFn() 1406 transact := testCase.TransactionerFn(persistTx) 1407 1408 firstBundleParams := dataloader.ParamDocument{ID: firstBundleID, Ctx: context.TODO(), First: &first, After: &gqlAfter} 1409 secondBundleParams := dataloader.ParamDocument{ID: secondBundleID, Ctx: context.TODO(), First: &first, After: &gqlAfter} 1410 keys := []dataloader.ParamDocument{firstBundleParams, secondBundleParams} 1411 resolver := bundle.NewResolver(transact, nil, nil, nil, nil, nil, svc, nil, nil, nil, nil, converter, nil, nil) 1412 1413 // WHEN 1414 result, err := resolver.DocumentsDataLoader(keys) 1415 1416 // then 1417 assert.Equal(t, testCase.ExpectedResult, result) 1418 assert.Equal(t, testCase.ExpectedErr, err) 1419 1420 svc.AssertExpectations(t) 1421 converter.AssertExpectations(t) 1422 persistTx.AssertExpectations(t) 1423 transact.AssertExpectations(t) 1424 }) 1425 } 1426 1427 t.Run("Returns error when there are no Bundles", func(t *testing.T) { 1428 resolver := bundle.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) 1429 // WHEN 1430 _, err := resolver.DocumentsDataLoader([]dataloader.ParamDocument{}) 1431 // THEN 1432 require.Error(t, err[0]) 1433 assert.EqualError(t, err[0], apperrors.NewInternalError("No Bundles found").Error()) 1434 }) 1435 1436 t.Run("Returns error when start cursor is nil", func(t *testing.T) { 1437 params := dataloader.ParamDocument{ID: firstBundleID, Ctx: context.TODO(), First: nil, After: &gqlAfter} 1438 keys := []dataloader.ParamDocument{params} 1439 1440 resolver := bundle.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) 1441 // WHEN 1442 _, err := resolver.DocumentsDataLoader(keys) 1443 // THEN 1444 require.Error(t, err[0]) 1445 assert.EqualError(t, err[0], apperrors.NewInvalidDataError("missing required parameter 'first'").Error()) 1446 }) 1447 } 1448 1449 func TestResolver_AddBundle(t *testing.T) { 1450 // GIVEN 1451 testErr := errors.New("Test error") 1452 1453 id := "foo" 1454 desc := "bar" 1455 name := "baz" 1456 1457 modelBundle := fixBundleModel(name, desc) 1458 gqlBundle := fixGQLBundle(id, name, desc) 1459 gqlBundleInput := fixGQLBundleCreateInput(name, desc) 1460 modelBundleInput := fixModelBundleCreateInput(name, desc) 1461 1462 txGen := txtest.NewTransactionContextGenerator(testErr) 1463 1464 testCases := []struct { 1465 Name string 1466 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 1467 BundleSvcFn func() *automock.BundleService 1468 AppSvcFn func() *automock.ApplicationService 1469 ConverterFn func() *automock.BundleConverter 1470 ExpectedBundle *graphql.Bundle 1471 ExpectedErr error 1472 }{ 1473 { 1474 Name: "Success", 1475 TransactionerFn: txGen.ThatSucceeds, 1476 BundleSvcFn: func() *automock.BundleService { 1477 svc := &automock.BundleService{} 1478 svc.On("Create", txtest.CtxWithDBMatcher(), resource.Application, appID, modelBundleInput).Return(id, nil).Once() 1479 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1480 return svc 1481 }, 1482 AppSvcFn: func() *automock.ApplicationService { 1483 svc := &automock.ApplicationService{} 1484 svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, extractTargetURLFromJSONArray(modelBundleInput.APIDefinitions[0].TargetURLs)).Return(nil).Once() 1485 return svc 1486 }, 1487 ConverterFn: func() *automock.BundleConverter { 1488 conv := &automock.BundleConverter{} 1489 conv.On("CreateInputFromGraphQL", gqlBundleInput).Return(modelBundleInput, nil).Once() 1490 conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once() 1491 return conv 1492 }, 1493 ExpectedBundle: gqlBundle, 1494 ExpectedErr: nil, 1495 }, 1496 { 1497 Name: "Returns error when starting transaction", 1498 TransactionerFn: txGen.ThatFailsOnBegin, 1499 BundleSvcFn: func() *automock.BundleService { 1500 svc := &automock.BundleService{} 1501 return svc 1502 }, 1503 AppSvcFn: func() *automock.ApplicationService { 1504 return &automock.ApplicationService{} 1505 }, 1506 ConverterFn: func() *automock.BundleConverter { 1507 conv := &automock.BundleConverter{} 1508 return conv 1509 }, 1510 ExpectedBundle: nil, 1511 ExpectedErr: testErr, 1512 }, 1513 { 1514 Name: "Returns error when adding Bundle failed", 1515 TransactionerFn: txGen.ThatDoesntExpectCommit, 1516 BundleSvcFn: func() *automock.BundleService { 1517 svc := &automock.BundleService{} 1518 svc.On("Create", txtest.CtxWithDBMatcher(), resource.Application, appID, modelBundleInput).Return("", testErr).Once() 1519 return svc 1520 }, 1521 AppSvcFn: func() *automock.ApplicationService { 1522 return &automock.ApplicationService{} 1523 }, 1524 ConverterFn: func() *automock.BundleConverter { 1525 conv := &automock.BundleConverter{} 1526 conv.On("CreateInputFromGraphQL", gqlBundleInput).Return(modelBundleInput, nil).Once() 1527 return conv 1528 }, 1529 ExpectedBundle: nil, 1530 ExpectedErr: testErr, 1531 }, 1532 { 1533 Name: "Returns error when Bundle retrieval failed", 1534 TransactionerFn: txGen.ThatDoesntExpectCommit, 1535 BundleSvcFn: func() *automock.BundleService { 1536 svc := &automock.BundleService{} 1537 svc.On("Create", txtest.CtxWithDBMatcher(), resource.Application, appID, modelBundleInput).Return(id, nil).Once() 1538 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(nil, testErr).Once() 1539 return svc 1540 }, 1541 AppSvcFn: func() *automock.ApplicationService { 1542 return &automock.ApplicationService{} 1543 }, 1544 ConverterFn: func() *automock.BundleConverter { 1545 conv := &automock.BundleConverter{} 1546 conv.On("CreateInputFromGraphQL", gqlBundleInput).Return(modelBundleInput, nil).Once() 1547 return conv 1548 }, 1549 ExpectedBundle: nil, 1550 ExpectedErr: testErr, 1551 }, 1552 { 1553 Name: "Returns error when updating base url failed", 1554 TransactionerFn: txGen.ThatDoesntExpectCommit, 1555 BundleSvcFn: func() *automock.BundleService { 1556 svc := &automock.BundleService{} 1557 svc.On("Create", txtest.CtxWithDBMatcher(), resource.Application, appID, modelBundleInput).Return(id, nil).Once() 1558 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1559 return svc 1560 }, 1561 AppSvcFn: func() *automock.ApplicationService { 1562 svc := &automock.ApplicationService{} 1563 svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, extractTargetURLFromJSONArray(modelBundleInput.APIDefinitions[0].TargetURLs)).Return(testErr).Once() 1564 return svc 1565 }, 1566 ConverterFn: func() *automock.BundleConverter { 1567 conv := &automock.BundleConverter{} 1568 conv.On("CreateInputFromGraphQL", gqlBundleInput).Return(modelBundleInput, nil).Once() 1569 return conv 1570 }, 1571 ExpectedBundle: nil, 1572 ExpectedErr: testErr, 1573 }, 1574 { 1575 Name: "Returns error when commit transaction failed", 1576 TransactionerFn: txGen.ThatFailsOnCommit, 1577 BundleSvcFn: func() *automock.BundleService { 1578 svc := &automock.BundleService{} 1579 svc.On("Create", txtest.CtxWithDBMatcher(), resource.Application, appID, modelBundleInput).Return(id, nil).Once() 1580 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1581 return svc 1582 }, 1583 AppSvcFn: func() *automock.ApplicationService { 1584 svc := &automock.ApplicationService{} 1585 svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, extractTargetURLFromJSONArray(modelBundleInput.APIDefinitions[0].TargetURLs)).Return(nil).Once() 1586 return svc 1587 }, 1588 ConverterFn: func() *automock.BundleConverter { 1589 conv := &automock.BundleConverter{} 1590 conv.On("CreateInputFromGraphQL", gqlBundleInput).Return(modelBundleInput, nil).Once() 1591 conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once() 1592 return conv 1593 }, 1594 ExpectedBundle: nil, 1595 ExpectedErr: testErr, 1596 }, 1597 { 1598 Name: "Returns error when converting to GraphQL failed", 1599 TransactionerFn: txGen.ThatDoesntExpectCommit, 1600 BundleSvcFn: func() *automock.BundleService { 1601 svc := &automock.BundleService{} 1602 svc.On("Create", txtest.CtxWithDBMatcher(), resource.Application, appID, modelBundleInput).Return(id, nil).Once() 1603 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1604 return svc 1605 }, 1606 AppSvcFn: func() *automock.ApplicationService { 1607 svc := &automock.ApplicationService{} 1608 svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, extractTargetURLFromJSONArray(modelBundleInput.APIDefinitions[0].TargetURLs)).Return(nil).Once() 1609 return svc 1610 }, 1611 ConverterFn: func() *automock.BundleConverter { 1612 conv := &automock.BundleConverter{} 1613 conv.On("CreateInputFromGraphQL", gqlBundleInput).Return(modelBundleInput, nil).Once() 1614 conv.On("ToGraphQL", modelBundle).Return(nil, testErr).Once() 1615 return conv 1616 }, 1617 ExpectedBundle: nil, 1618 ExpectedErr: testErr, 1619 }, 1620 } 1621 1622 for _, testCase := range testCases { 1623 t.Run(testCase.Name, func(t *testing.T) { 1624 // GIVEN 1625 persist, transact := testCase.TransactionerFn() 1626 bundleSvc := testCase.BundleSvcFn() 1627 appSvc := testCase.AppSvcFn() 1628 converter := testCase.ConverterFn() 1629 1630 resolver := bundle.NewResolver(transact, bundleSvc, nil, nil, nil, nil, nil, converter, nil, nil, nil, nil, nil, appSvc) 1631 1632 // WHEN 1633 result, err := resolver.AddBundle(context.TODO(), appID, gqlBundleInput) 1634 1635 // then 1636 assert.Equal(t, testCase.ExpectedBundle, result) 1637 if testCase.ExpectedErr != nil { 1638 require.Error(t, err) 1639 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 1640 } else { 1641 require.Nil(t, err) 1642 } 1643 1644 persist.AssertExpectations(t) 1645 transact.AssertExpectations(t) 1646 bundleSvc.AssertExpectations(t) 1647 appSvc.AssertExpectations(t) 1648 converter.AssertExpectations(t) 1649 }) 1650 } 1651 } 1652 1653 func TestResolver_UpdateBundle(t *testing.T) { 1654 // GIVEN 1655 testErr := errors.New("Test error") 1656 1657 id := "id" 1658 name := "foo" 1659 desc := "bar" 1660 gqlBundleUpdateInput := fixGQLBundleUpdateInput(name, desc) 1661 modelBundleUpdateInput := fixModelBundleUpdateInput(name, desc) 1662 gqlBundle := fixGQLBundle(id, name, desc) 1663 modelBundle := fixBundleModel(name, desc) 1664 1665 txGen := txtest.NewTransactionContextGenerator(testErr) 1666 1667 testCases := []struct { 1668 Name string 1669 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 1670 ServiceFn func() *automock.BundleService 1671 ConverterFn func() *automock.BundleConverter 1672 InputBundle graphql.BundleUpdateInput 1673 ExpectedBundle *graphql.Bundle 1674 ExpectedErr error 1675 }{ 1676 { 1677 Name: "Success", 1678 TransactionerFn: txGen.ThatSucceeds, 1679 ServiceFn: func() *automock.BundleService { 1680 svc := &automock.BundleService{} 1681 svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, modelBundleUpdateInput).Return(nil).Once() 1682 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1683 return svc 1684 }, 1685 ConverterFn: func() *automock.BundleConverter { 1686 conv := &automock.BundleConverter{} 1687 conv.On("UpdateInputFromGraphQL", gqlBundleUpdateInput).Return(&modelBundleUpdateInput, nil).Once() 1688 conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once() 1689 return conv 1690 }, 1691 InputBundle: gqlBundleUpdateInput, 1692 ExpectedBundle: gqlBundle, 1693 ExpectedErr: nil, 1694 }, 1695 { 1696 Name: "Returns error when starting transaction failed", 1697 TransactionerFn: txGen.ThatFailsOnBegin, 1698 ServiceFn: func() *automock.BundleService { 1699 svc := &automock.BundleService{} 1700 return svc 1701 }, 1702 ConverterFn: func() *automock.BundleConverter { 1703 conv := &automock.BundleConverter{} 1704 return conv 1705 }, 1706 InputBundle: gqlBundleUpdateInput, 1707 ExpectedBundle: nil, 1708 ExpectedErr: testErr, 1709 }, 1710 { 1711 Name: "Returns error when converting from GraphQL failed", 1712 TransactionerFn: txGen.ThatDoesntExpectCommit, 1713 ServiceFn: func() *automock.BundleService { 1714 svc := &automock.BundleService{} 1715 return svc 1716 }, 1717 ConverterFn: func() *automock.BundleConverter { 1718 conv := &automock.BundleConverter{} 1719 conv.On("UpdateInputFromGraphQL", gqlBundleUpdateInput).Return(&model.BundleUpdateInput{}, testErr).Once() 1720 return conv 1721 }, 1722 ExpectedBundle: nil, 1723 ExpectedErr: testErr, 1724 }, 1725 { 1726 Name: "Returns error when Bundle update failed", 1727 TransactionerFn: txGen.ThatDoesntExpectCommit, 1728 ServiceFn: func() *automock.BundleService { 1729 svc := &automock.BundleService{} 1730 svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, modelBundleUpdateInput).Return(testErr).Once() 1731 return svc 1732 }, 1733 ConverterFn: func() *automock.BundleConverter { 1734 conv := &automock.BundleConverter{} 1735 conv.On("UpdateInputFromGraphQL", gqlBundleUpdateInput).Return(&modelBundleUpdateInput, nil).Once() 1736 return conv 1737 }, 1738 InputBundle: gqlBundleUpdateInput, 1739 ExpectedBundle: nil, 1740 ExpectedErr: testErr, 1741 }, 1742 { 1743 Name: "Returns error when Bundle retrieval failed", 1744 TransactionerFn: txGen.ThatDoesntExpectCommit, 1745 ServiceFn: func() *automock.BundleService { 1746 svc := &automock.BundleService{} 1747 svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, modelBundleUpdateInput).Return(nil).Once() 1748 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(nil, testErr).Once() 1749 return svc 1750 }, 1751 ConverterFn: func() *automock.BundleConverter { 1752 conv := &automock.BundleConverter{} 1753 conv.On("UpdateInputFromGraphQL", gqlBundleUpdateInput).Return(&modelBundleUpdateInput, nil).Once() 1754 return conv 1755 }, 1756 InputBundle: gqlBundleUpdateInput, 1757 ExpectedBundle: nil, 1758 ExpectedErr: testErr, 1759 }, 1760 { 1761 Name: "Returns error when commit transaction failed", 1762 TransactionerFn: txGen.ThatFailsOnCommit, 1763 ServiceFn: func() *automock.BundleService { 1764 svc := &automock.BundleService{} 1765 svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, modelBundleUpdateInput).Return(nil).Once() 1766 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1767 return svc 1768 }, 1769 ConverterFn: func() *automock.BundleConverter { 1770 conv := &automock.BundleConverter{} 1771 conv.On("UpdateInputFromGraphQL", gqlBundleUpdateInput).Return(&modelBundleUpdateInput, nil).Once() 1772 conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once() 1773 return conv 1774 }, 1775 InputBundle: gqlBundleUpdateInput, 1776 ExpectedBundle: nil, 1777 ExpectedErr: testErr, 1778 }, 1779 { 1780 Name: "Returns error when converting to GraphQL failed", 1781 TransactionerFn: txGen.ThatDoesntExpectCommit, 1782 ServiceFn: func() *automock.BundleService { 1783 svc := &automock.BundleService{} 1784 svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, modelBundleUpdateInput).Return(nil).Once() 1785 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1786 return svc 1787 }, 1788 ConverterFn: func() *automock.BundleConverter { 1789 conv := &automock.BundleConverter{} 1790 conv.On("UpdateInputFromGraphQL", gqlBundleUpdateInput).Return(&modelBundleUpdateInput, nil).Once() 1791 conv.On("ToGraphQL", modelBundle).Return(nil, testErr).Once() 1792 return conv 1793 }, 1794 ExpectedBundle: nil, 1795 ExpectedErr: testErr, 1796 }, 1797 } 1798 1799 for _, testCase := range testCases { 1800 t.Run(testCase.Name, func(t *testing.T) { 1801 // GIVEN 1802 persist, transact := testCase.TransactionerFn() 1803 svc := testCase.ServiceFn() 1804 converter := testCase.ConverterFn() 1805 1806 resolver := bundle.NewResolver(transact, svc, nil, nil, nil, nil, nil, converter, nil, nil, nil, nil, nil, nil) 1807 1808 // WHEN 1809 result, err := resolver.UpdateBundle(context.TODO(), id, gqlBundleUpdateInput) 1810 1811 // then 1812 assert.Equal(t, testCase.ExpectedBundle, result) 1813 if testCase.ExpectedErr != nil { 1814 require.Error(t, err) 1815 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 1816 } else { 1817 require.Nil(t, err) 1818 } 1819 1820 persist.AssertExpectations(t) 1821 transact.AssertExpectations(t) 1822 svc.AssertExpectations(t) 1823 converter.AssertExpectations(t) 1824 }) 1825 } 1826 } 1827 1828 func TestResolver_DeleteBundle(t *testing.T) { 1829 // GIVEN 1830 testErr := errors.New("Test error") 1831 1832 id := "id" 1833 name := "foo" 1834 desc := "desc" 1835 modelBundle := fixBundleModel(name, desc) 1836 gqlBundle := fixGQLBundle(id, name, desc) 1837 1838 txGen := txtest.NewTransactionContextGenerator(testErr) 1839 1840 testCases := []struct { 1841 Name string 1842 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 1843 ServiceFn func() *automock.BundleService 1844 APIDefFn func() *automock.APIService 1845 EventDefFn func() *automock.EventService 1846 ConverterFn func() *automock.BundleConverter 1847 ExpectedBundle *graphql.Bundle 1848 ExpectedErr error 1849 }{ 1850 { 1851 Name: "Success", 1852 TransactionerFn: txGen.ThatSucceeds, 1853 ServiceFn: func() *automock.BundleService { 1854 svc := &automock.BundleService{} 1855 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1856 svc.On("Delete", txtest.CtxWithDBMatcher(), resource.Application, id).Return(nil).Once() 1857 return svc 1858 }, 1859 APIDefFn: func() *automock.APIService { 1860 apiSvc := &automock.APIService{} 1861 apiSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(nil).Once() 1862 return apiSvc 1863 }, 1864 EventDefFn: func() *automock.EventService { 1865 eventSvc := &automock.EventService{} 1866 eventSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(nil).Once() 1867 return eventSvc 1868 }, 1869 ConverterFn: func() *automock.BundleConverter { 1870 conv := &automock.BundleConverter{} 1871 conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once() 1872 return conv 1873 }, 1874 ExpectedBundle: gqlBundle, 1875 ExpectedErr: nil, 1876 }, 1877 { 1878 Name: "Return error when starting transaction fails", 1879 TransactionerFn: txGen.ThatFailsOnBegin, 1880 ServiceFn: func() *automock.BundleService { 1881 svc := &automock.BundleService{} 1882 return svc 1883 }, 1884 APIDefFn: func() *automock.APIService { 1885 apiSvc := &automock.APIService{} 1886 return apiSvc 1887 }, 1888 EventDefFn: func() *automock.EventService { 1889 eventSvc := &automock.EventService{} 1890 return eventSvc 1891 }, 1892 ConverterFn: func() *automock.BundleConverter { 1893 conv := &automock.BundleConverter{} 1894 return conv 1895 }, 1896 ExpectedBundle: nil, 1897 ExpectedErr: testErr, 1898 }, 1899 { 1900 Name: "Returns error when Bundle retrieval failed", 1901 TransactionerFn: txGen.ThatDoesntExpectCommit, 1902 ServiceFn: func() *automock.BundleService { 1903 svc := &automock.BundleService{} 1904 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(nil, testErr).Once() 1905 return svc 1906 }, 1907 APIDefFn: func() *automock.APIService { 1908 apiSvc := &automock.APIService{} 1909 return apiSvc 1910 }, 1911 EventDefFn: func() *automock.EventService { 1912 eventSvc := &automock.EventService{} 1913 return eventSvc 1914 }, 1915 ConverterFn: func() *automock.BundleConverter { 1916 conv := &automock.BundleConverter{} 1917 return conv 1918 }, 1919 ExpectedBundle: nil, 1920 ExpectedErr: testErr, 1921 }, 1922 { 1923 Name: "Returns error when APIs deletion failed", 1924 TransactionerFn: txGen.ThatDoesntExpectCommit, 1925 ServiceFn: func() *automock.BundleService { 1926 svc := &automock.BundleService{} 1927 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1928 return svc 1929 }, 1930 APIDefFn: func() *automock.APIService { 1931 apiSvc := &automock.APIService{} 1932 apiSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(testErr).Once() 1933 return apiSvc 1934 }, 1935 EventDefFn: func() *automock.EventService { 1936 eventSvc := &automock.EventService{} 1937 return eventSvc 1938 }, 1939 ConverterFn: func() *automock.BundleConverter { 1940 conv := &automock.BundleConverter{} 1941 return conv 1942 }, 1943 ExpectedBundle: nil, 1944 ExpectedErr: testErr, 1945 }, 1946 { 1947 Name: "Returns error when Events deletion failed", 1948 TransactionerFn: txGen.ThatDoesntExpectCommit, 1949 ServiceFn: func() *automock.BundleService { 1950 svc := &automock.BundleService{} 1951 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1952 return svc 1953 }, 1954 APIDefFn: func() *automock.APIService { 1955 apiSvc := &automock.APIService{} 1956 apiSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(nil).Once() 1957 return apiSvc 1958 }, 1959 EventDefFn: func() *automock.EventService { 1960 eventSvc := &automock.EventService{} 1961 eventSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(testErr).Once() 1962 return eventSvc 1963 }, 1964 ConverterFn: func() *automock.BundleConverter { 1965 conv := &automock.BundleConverter{} 1966 return conv 1967 }, 1968 ExpectedBundle: nil, 1969 ExpectedErr: testErr, 1970 }, 1971 { 1972 Name: "Returns error when Bundle deletion failed", 1973 TransactionerFn: txGen.ThatDoesntExpectCommit, 1974 ServiceFn: func() *automock.BundleService { 1975 svc := &automock.BundleService{} 1976 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 1977 svc.On("Delete", txtest.CtxWithDBMatcher(), resource.Application, id).Return(testErr).Once() 1978 return svc 1979 }, 1980 APIDefFn: func() *automock.APIService { 1981 apiSvc := &automock.APIService{} 1982 apiSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(nil).Once() 1983 return apiSvc 1984 }, 1985 EventDefFn: func() *automock.EventService { 1986 eventSvc := &automock.EventService{} 1987 eventSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(nil).Once() 1988 return eventSvc 1989 }, 1990 ConverterFn: func() *automock.BundleConverter { 1991 conv := &automock.BundleConverter{} 1992 return conv 1993 }, 1994 ExpectedBundle: nil, 1995 ExpectedErr: testErr, 1996 }, 1997 { 1998 Name: "Return error when commit transaction fails", 1999 TransactionerFn: txGen.ThatFailsOnCommit, 2000 ServiceFn: func() *automock.BundleService { 2001 svc := &automock.BundleService{} 2002 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 2003 svc.On("Delete", txtest.CtxWithDBMatcher(), resource.Application, id).Return(nil).Once() 2004 return svc 2005 }, 2006 APIDefFn: func() *automock.APIService { 2007 apiSvc := &automock.APIService{} 2008 apiSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(nil).Once() 2009 return apiSvc 2010 }, 2011 EventDefFn: func() *automock.EventService { 2012 eventSvc := &automock.EventService{} 2013 eventSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(nil).Once() 2014 return eventSvc 2015 }, 2016 ConverterFn: func() *automock.BundleConverter { 2017 conv := &automock.BundleConverter{} 2018 conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once() 2019 return conv 2020 }, 2021 ExpectedBundle: nil, 2022 ExpectedErr: testErr, 2023 }, 2024 { 2025 Name: "Success", 2026 TransactionerFn: txGen.ThatDoesntExpectCommit, 2027 ServiceFn: func() *automock.BundleService { 2028 svc := &automock.BundleService{} 2029 svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(modelBundle, nil).Once() 2030 svc.On("Delete", txtest.CtxWithDBMatcher(), resource.Application, id).Return(nil).Once() 2031 return svc 2032 }, 2033 APIDefFn: func() *automock.APIService { 2034 apiSvc := &automock.APIService{} 2035 apiSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(nil).Once() 2036 return apiSvc 2037 }, 2038 EventDefFn: func() *automock.EventService { 2039 eventSvc := &automock.EventService{} 2040 eventSvc.On("DeleteAllByBundleID", txtest.CtxWithDBMatcher(), id).Return(nil).Once() 2041 return eventSvc 2042 }, 2043 ConverterFn: func() *automock.BundleConverter { 2044 conv := &automock.BundleConverter{} 2045 conv.On("ToGraphQL", modelBundle).Return(nil, testErr).Once() 2046 return conv 2047 }, 2048 ExpectedBundle: nil, 2049 ExpectedErr: testErr, 2050 }, 2051 } 2052 2053 for _, testCase := range testCases { 2054 t.Run(testCase.Name, func(t *testing.T) { 2055 // GIVEN 2056 persist, transact := testCase.TransactionerFn() 2057 svc := testCase.ServiceFn() 2058 apiSvc := testCase.APIDefFn() 2059 eventSvc := testCase.EventDefFn() 2060 converter := testCase.ConverterFn() 2061 2062 resolver := bundle.NewResolver(transact, svc, nil, nil, apiSvc, eventSvc, nil, converter, nil, nil, nil, nil, nil, nil) 2063 2064 // WHEN 2065 result, err := resolver.DeleteBundle(context.TODO(), id) 2066 2067 // then 2068 assert.Equal(t, testCase.ExpectedBundle, result) 2069 if testCase.ExpectedErr != nil { 2070 require.Error(t, err) 2071 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 2072 } else { 2073 require.Nil(t, err) 2074 } 2075 2076 svc.AssertExpectations(t) 2077 converter.AssertExpectations(t) 2078 transact.AssertExpectations(t) 2079 persist.AssertExpectations(t) 2080 }) 2081 } 2082 } 2083 2084 func TestResolver_InstanceAuth(t *testing.T) { 2085 // GIVEN 2086 id := "foo" 2087 modelBundleInstanceAuth := fixModelBundleInstanceAuth(id) 2088 gqlBundleInstanceAuth := fixGQLBundleInstanceAuth(id) 2089 bndl := fixGQLBundle("foo", "foo", "foo") 2090 testErr := errors.New("Test error") 2091 txGen := txtest.NewTransactionContextGenerator(testErr) 2092 2093 testCases := []struct { 2094 Name string 2095 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 2096 ServiceFn func() *automock.BundleInstanceAuthService 2097 ConverterFn func() *automock.BundleInstanceAuthConverter 2098 InputID string 2099 Bundle *graphql.Bundle 2100 ExpectedBundleInstanceAuth *graphql.BundleInstanceAuth 2101 ExpectedErr error 2102 }{ 2103 { 2104 Name: "Success", 2105 TransactionerFn: txGen.ThatSucceeds, 2106 ServiceFn: func() *automock.BundleInstanceAuthService { 2107 svc := &automock.BundleInstanceAuthService{} 2108 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelBundleInstanceAuth, nil).Once() 2109 2110 return svc 2111 }, 2112 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2113 conv := &automock.BundleInstanceAuthConverter{} 2114 conv.On("ToGraphQL", modelBundleInstanceAuth).Return(gqlBundleInstanceAuth, nil).Once() 2115 return conv 2116 }, 2117 InputID: "foo", 2118 Bundle: bndl, 2119 ExpectedBundleInstanceAuth: gqlBundleInstanceAuth, 2120 ExpectedErr: nil, 2121 }, 2122 { 2123 Name: "Returns error when Bundle retrieval failed", 2124 TransactionerFn: txGen.ThatDoesntExpectCommit, 2125 ServiceFn: func() *automock.BundleInstanceAuthService { 2126 svc := &automock.BundleInstanceAuthService{} 2127 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, testErr).Once() 2128 2129 return svc 2130 }, 2131 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2132 conv := &automock.BundleInstanceAuthConverter{} 2133 return conv 2134 }, 2135 InputID: "foo", 2136 Bundle: bndl, 2137 ExpectedBundleInstanceAuth: nil, 2138 ExpectedErr: testErr, 2139 }, 2140 { 2141 Name: "Returns error when conversion to graphql fails", 2142 TransactionerFn: txGen.ThatDoesntExpectCommit, 2143 ServiceFn: func() *automock.BundleInstanceAuthService { 2144 svc := &automock.BundleInstanceAuthService{} 2145 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelBundleInstanceAuth, nil).Once() 2146 2147 return svc 2148 }, 2149 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2150 conv := &automock.BundleInstanceAuthConverter{} 2151 conv.On("ToGraphQL", modelBundleInstanceAuth).Return(nil, testErr).Once() 2152 return conv 2153 }, 2154 InputID: "foo", 2155 Bundle: bndl, 2156 ExpectedBundleInstanceAuth: nil, 2157 ExpectedErr: testErr, 2158 }, 2159 { 2160 Name: "Returns nil when bundle instance auth for bundle not found", 2161 TransactionerFn: txGen.ThatSucceeds, 2162 ServiceFn: func() *automock.BundleInstanceAuthService { 2163 svc := &automock.BundleInstanceAuthService{} 2164 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, apperrors.NewNotFoundError(resource.Bundle, "")).Once() 2165 2166 return svc 2167 }, 2168 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2169 conv := &automock.BundleInstanceAuthConverter{} 2170 return conv 2171 }, 2172 InputID: "foo", 2173 Bundle: bndl, 2174 ExpectedBundleInstanceAuth: nil, 2175 ExpectedErr: nil, 2176 }, 2177 { 2178 Name: "Returns error when commit begin error", 2179 TransactionerFn: txGen.ThatFailsOnBegin, 2180 ServiceFn: func() *automock.BundleInstanceAuthService { 2181 svc := &automock.BundleInstanceAuthService{} 2182 2183 return svc 2184 }, 2185 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2186 conv := &automock.BundleInstanceAuthConverter{} 2187 return conv 2188 }, 2189 InputID: "foo", 2190 Bundle: bndl, 2191 ExpectedBundleInstanceAuth: nil, 2192 ExpectedErr: testErr, 2193 }, 2194 { 2195 Name: "Returns error when commit failed", 2196 TransactionerFn: txGen.ThatFailsOnCommit, 2197 ServiceFn: func() *automock.BundleInstanceAuthService { 2198 svc := &automock.BundleInstanceAuthService{} 2199 svc.On("GetForBundle", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelBundleInstanceAuth, nil).Once() 2200 return svc 2201 }, 2202 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2203 conv := &automock.BundleInstanceAuthConverter{} 2204 conv.On("ToGraphQL", modelBundleInstanceAuth).Return(gqlBundleInstanceAuth, nil).Once() 2205 return conv 2206 }, 2207 InputID: "foo", 2208 Bundle: bndl, 2209 ExpectedBundleInstanceAuth: nil, 2210 ExpectedErr: testErr, 2211 }, 2212 } 2213 2214 for _, testCase := range testCases { 2215 t.Run(testCase.Name, func(t *testing.T) { 2216 persist, transact := testCase.TransactionerFn() 2217 svc := testCase.ServiceFn() 2218 converter := testCase.ConverterFn() 2219 2220 resolver := bundle.NewResolver(transact, nil, svc, nil, nil, nil, nil, nil, converter, nil, nil, nil, nil, nil) 2221 2222 // WHEN 2223 result, err := resolver.InstanceAuth(context.TODO(), testCase.Bundle, testCase.InputID) 2224 2225 // then 2226 assert.Equal(t, testCase.ExpectedBundleInstanceAuth, result) 2227 assert.Equal(t, testCase.ExpectedErr, err) 2228 2229 svc.AssertExpectations(t) 2230 persist.AssertExpectations(t) 2231 transact.AssertExpectations(t) 2232 converter.AssertExpectations(t) 2233 }) 2234 } 2235 2236 t.Run("Returns error when Bundle is nil", func(t *testing.T) { 2237 resolver := bundle.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) 2238 // WHEN 2239 _, err := resolver.InstanceAuth(context.TODO(), nil, "") 2240 // THEN 2241 require.Error(t, err) 2242 assert.EqualError(t, err, apperrors.NewInternalError("Bundle cannot be empty").Error()) 2243 }) 2244 } 2245 2246 func TestResolver_InstanceAuths(t *testing.T) { 2247 // GIVEN 2248 testErr := errors.New("test error") 2249 2250 bndl := fixGQLBundle(bundleID, "foo", "bar") 2251 modelBundleInstanceAuths := []*model.BundleInstanceAuth{ 2252 fixModelBundleInstanceAuth("foo"), 2253 fixModelBundleInstanceAuth("bar"), 2254 } 2255 2256 gqlBundleInstanceAuths := []*graphql.BundleInstanceAuth{ 2257 fixGQLBundleInstanceAuth("foo"), 2258 fixGQLBundleInstanceAuth("bar"), 2259 } 2260 2261 txGen := txtest.NewTransactionContextGenerator(testErr) 2262 2263 testCases := []struct { 2264 Name string 2265 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 2266 ServiceFn func() *automock.BundleInstanceAuthService 2267 ConverterFn func() *automock.BundleInstanceAuthConverter 2268 ExpectedResult []*graphql.BundleInstanceAuth 2269 ExpectedErr error 2270 }{ 2271 { 2272 Name: "Success", 2273 TransactionerFn: txGen.ThatSucceeds, 2274 ServiceFn: func() *automock.BundleInstanceAuthService { 2275 svc := &automock.BundleInstanceAuthService{} 2276 svc.On("List", txtest.CtxWithDBMatcher(), bundleID).Return(modelBundleInstanceAuths, nil).Once() 2277 return svc 2278 }, 2279 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2280 conv := &automock.BundleInstanceAuthConverter{} 2281 conv.On("MultipleToGraphQL", modelBundleInstanceAuths).Return(gqlBundleInstanceAuths, nil).Once() 2282 return conv 2283 }, 2284 ExpectedResult: gqlBundleInstanceAuths, 2285 ExpectedErr: nil, 2286 }, 2287 { 2288 Name: "Returns error when transaction begin failed", 2289 TransactionerFn: txGen.ThatFailsOnBegin, 2290 ServiceFn: func() *automock.BundleInstanceAuthService { 2291 svc := &automock.BundleInstanceAuthService{} 2292 return svc 2293 }, 2294 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2295 conv := &automock.BundleInstanceAuthConverter{} 2296 return conv 2297 }, 2298 ExpectedResult: nil, 2299 ExpectedErr: testErr, 2300 }, 2301 { 2302 Name: "Returns error when Bundle Instance Auths listing failed", 2303 TransactionerFn: txGen.ThatDoesntExpectCommit, 2304 ServiceFn: func() *automock.BundleInstanceAuthService { 2305 svc := &automock.BundleInstanceAuthService{} 2306 svc.On("List", txtest.CtxWithDBMatcher(), bundleID).Return(nil, testErr).Once() 2307 return svc 2308 }, 2309 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2310 conv := &automock.BundleInstanceAuthConverter{} 2311 return conv 2312 }, 2313 ExpectedResult: nil, 2314 ExpectedErr: testErr, 2315 }, 2316 { 2317 Name: "Returns error when Bundle Instance Auths conversion to graphql failed", 2318 TransactionerFn: txGen.ThatDoesntExpectCommit, 2319 ServiceFn: func() *automock.BundleInstanceAuthService { 2320 svc := &automock.BundleInstanceAuthService{} 2321 svc.On("List", txtest.CtxWithDBMatcher(), bundleID).Return(modelBundleInstanceAuths, nil).Once() 2322 return svc 2323 }, 2324 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2325 conv := &automock.BundleInstanceAuthConverter{} 2326 conv.On("MultipleToGraphQL", modelBundleInstanceAuths).Return(nil, testErr).Once() 2327 return conv 2328 }, 2329 ExpectedResult: nil, 2330 ExpectedErr: testErr, 2331 }, 2332 { 2333 Name: "Returns error when transaction commit failed", 2334 TransactionerFn: txGen.ThatFailsOnCommit, 2335 ServiceFn: func() *automock.BundleInstanceAuthService { 2336 svc := &automock.BundleInstanceAuthService{} 2337 svc.On("List", txtest.CtxWithDBMatcher(), bundleID).Return(modelBundleInstanceAuths, nil).Once() 2338 return svc 2339 }, 2340 ConverterFn: func() *automock.BundleInstanceAuthConverter { 2341 conv := &automock.BundleInstanceAuthConverter{} 2342 conv.On("MultipleToGraphQL", modelBundleInstanceAuths).Return(gqlBundleInstanceAuths, nil).Once() 2343 return conv 2344 }, 2345 ExpectedResult: nil, 2346 ExpectedErr: testErr, 2347 }, 2348 } 2349 2350 for _, testCase := range testCases { 2351 t.Run(testCase.Name, func(t *testing.T) { 2352 // GIVEN 2353 persist, transact := testCase.TransactionerFn() 2354 svc := testCase.ServiceFn() 2355 converter := testCase.ConverterFn() 2356 2357 resolver := bundle.NewResolver(transact, nil, svc, nil, nil, nil, nil, nil, converter, nil, nil, nil, nil, nil) 2358 // WHEN 2359 result, err := resolver.InstanceAuths(context.TODO(), bndl) 2360 2361 // then 2362 assert.Equal(t, testCase.ExpectedResult, result) 2363 assert.Equal(t, testCase.ExpectedErr, err) 2364 2365 persist.AssertExpectations(t) 2366 transact.AssertExpectations(t) 2367 svc.AssertExpectations(t) 2368 converter.AssertExpectations(t) 2369 }) 2370 } 2371 2372 t.Run("Returns error when Bundle is nil", func(t *testing.T) { 2373 resolver := bundle.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) 2374 // WHEN 2375 _, err := resolver.InstanceAuths(context.TODO(), nil) 2376 // THEN 2377 require.Error(t, err) 2378 assert.EqualError(t, err, apperrors.NewInternalError("Bundle cannot be empty").Error()) 2379 }) 2380 } 2381 2382 func extractTargetURLFromJSONArray(jsonTargetURL json.RawMessage) string { 2383 strTargetURL := string(jsonTargetURL) 2384 strTargetURL = strings.TrimPrefix(strTargetURL, `["`) 2385 strTargetURL = strings.TrimSuffix(strTargetURL, `"]`) 2386 2387 return strTargetURL 2388 }