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