github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/formationtemplate/resolver_test.go (about) 1 package formationtemplate_test 2 3 import ( 4 "context" 5 "reflect" 6 "testing" 7 8 dataloader "github.com/kyma-incubator/compass/components/director/internal/dataloaders" 9 10 "github.com/kyma-incubator/compass/components/director/internal/model" 11 12 "github.com/kyma-incubator/compass/components/director/internal/domain/formationtemplate" 13 "github.com/kyma-incubator/compass/components/director/internal/domain/formationtemplate/automock" 14 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 15 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 16 persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock" 17 "github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest" 18 "github.com/kyma-incubator/compass/components/director/pkg/resource" 19 "github.com/pkg/errors" 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/mock" 22 "github.com/stretchr/testify/require" 23 ) 24 25 func TestResolver_FormationTemplate(t *testing.T) { 26 // GIVEN 27 ctx := context.TODO() 28 29 testErr := errors.New("test error") 30 31 txGen := txtest.NewTransactionContextGenerator(testErr) 32 33 testCases := []struct { 34 Name string 35 TxFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 36 FormationTemplateConverter func() *automock.FormationTemplateConverter 37 FormationTemplateService func() *automock.FormationTemplateService 38 ExpectedOutput *graphql.FormationTemplate 39 ExpectedError error 40 }{ 41 { 42 Name: "Success", 43 TxFn: txGen.ThatSucceeds, 44 FormationTemplateService: func() *automock.FormationTemplateService { 45 svc := &automock.FormationTemplateService{} 46 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&formationTemplateModel, nil) 47 48 return svc 49 }, 50 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 51 converter := &automock.FormationTemplateConverter{} 52 converter.On("ToGraphQL", &formationTemplateModel).Return(&graphQLFormationTemplate, nil) 53 54 return converter 55 }, 56 ExpectedOutput: &graphQLFormationTemplate, 57 ExpectedError: nil, 58 }, 59 { 60 Name: "Error when getting from service fails", 61 TxFn: txGen.ThatDoesntExpectCommit, 62 FormationTemplateService: func() *automock.FormationTemplateService { 63 svc := &automock.FormationTemplateService{} 64 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testErr) 65 66 return svc 67 }, 68 FormationTemplateConverter: UnusedFormationTemplateConverter, 69 ExpectedOutput: nil, 70 ExpectedError: testErr, 71 }, 72 { 73 Name: "Returns nil when formation template not found", 74 TxFn: txGen.ThatSucceeds, 75 FormationTemplateService: func() *automock.FormationTemplateService { 76 svc := &automock.FormationTemplateService{} 77 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, apperrors.NewNotFoundError(resource.FormationTemplate, testID)) 78 79 return svc 80 }, 81 FormationTemplateConverter: UnusedFormationTemplateConverter, 82 ExpectedOutput: nil, 83 ExpectedError: nil, 84 }, 85 { 86 Name: "Returns error when failing on the committing of a transaction", 87 TxFn: txGen.ThatFailsOnCommit, 88 FormationTemplateService: func() *automock.FormationTemplateService { 89 svc := &automock.FormationTemplateService{} 90 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&formationTemplateModel, nil) 91 92 return svc 93 }, 94 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 95 converter := &automock.FormationTemplateConverter{} 96 converter.On("ToGraphQL", &formationTemplateModel).Return(&graphQLFormationTemplate, nil) 97 98 return converter 99 }, 100 ExpectedOutput: nil, 101 ExpectedError: testErr, 102 }, 103 { 104 Name: "Error when converting ot graphql fails", 105 TxFn: txGen.ThatDoesntExpectCommit, 106 FormationTemplateService: func() *automock.FormationTemplateService { 107 svc := &automock.FormationTemplateService{} 108 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&formationTemplateModel, nil) 109 110 return svc 111 }, 112 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 113 converter := &automock.FormationTemplateConverter{} 114 converter.On("ToGraphQL", &formationTemplateModel).Return(nil, testErr) 115 116 return converter 117 }, 118 ExpectedOutput: nil, 119 ExpectedError: testErr, 120 }, 121 { 122 Name: "Returns error when failing on the beginning of a transaction", 123 TxFn: txGen.ThatFailsOnBegin, 124 FormationTemplateService: UnusedFormationTemplateService, 125 FormationTemplateConverter: UnusedFormationTemplateConverter, 126 ExpectedOutput: nil, 127 ExpectedError: testErr, 128 }, 129 } 130 131 for _, testCase := range testCases { 132 t.Run(testCase.Name, func(t *testing.T) { 133 persist, transact := testCase.TxFn() 134 formationTemplateSvc := testCase.FormationTemplateService() 135 formationTemplateConverter := testCase.FormationTemplateConverter() 136 137 resolver := formationtemplate.NewResolver(transact, formationTemplateConverter, formationTemplateSvc, nil, nil, nil) 138 139 // WHEN 140 result, err := resolver.FormationTemplate(ctx, testID) 141 142 // THEN 143 if testCase.ExpectedError != nil { 144 require.Error(t, err) 145 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 146 } else { 147 assert.NoError(t, err) 148 } 149 assert.Equal(t, testCase.ExpectedOutput, result) 150 151 mock.AssertExpectationsForObjects(t, persist, formationTemplateSvc, formationTemplateConverter) 152 }) 153 } 154 } 155 156 func TestResolver_FormationTemplates(t *testing.T) { 157 // GIVEN 158 ctx := context.TODO() 159 160 testErr := errors.New("test error") 161 162 txGen := txtest.NewTransactionContextGenerator(testErr) 163 164 first := 2 165 after := "test" 166 gqlAfter := graphql.PageCursor(after) 167 168 testCases := []struct { 169 Name string 170 First *int 171 TxFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 172 FormationTemplateConverter func() *automock.FormationTemplateConverter 173 FormationTemplateService func() *automock.FormationTemplateService 174 ExpectedOutput *graphql.FormationTemplatePage 175 ExpectedError error 176 }{ 177 { 178 Name: "Success", 179 TxFn: txGen.ThatSucceeds, 180 First: &first, 181 FormationTemplateService: func() *automock.FormationTemplateService { 182 svc := &automock.FormationTemplateService{} 183 svc.On("List", txtest.CtxWithDBMatcher(), first, after).Return(&formationTemplateModelPage, nil) 184 185 return svc 186 }, 187 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 188 converter := &automock.FormationTemplateConverter{} 189 converter.On("MultipleToGraphQL", formationTemplateModelPage.Data).Return(graphQLFormationTemplatePage.Data, nil) 190 191 return converter 192 }, 193 ExpectedOutput: &graphQLFormationTemplatePage, 194 ExpectedError: nil, 195 }, 196 { 197 Name: "Error when listing from service fails", 198 First: &first, 199 TxFn: txGen.ThatDoesntExpectCommit, 200 FormationTemplateService: func() *automock.FormationTemplateService { 201 svc := &automock.FormationTemplateService{} 202 svc.On("List", txtest.CtxWithDBMatcher(), first, after).Return(nil, testErr) 203 204 return svc 205 }, 206 FormationTemplateConverter: UnusedFormationTemplateConverter, 207 ExpectedOutput: nil, 208 ExpectedError: testErr, 209 }, 210 { 211 Name: "Error when converting to graphql fails", 212 First: &first, 213 TxFn: txGen.ThatDoesntExpectCommit, 214 FormationTemplateService: func() *automock.FormationTemplateService { 215 svc := &automock.FormationTemplateService{} 216 svc.On("List", txtest.CtxWithDBMatcher(), first, after).Return(&formationTemplateModelPage, nil) 217 218 return svc 219 }, 220 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 221 converter := &automock.FormationTemplateConverter{} 222 converter.On("MultipleToGraphQL", formationTemplateModelPage.Data).Return(nil, testErr) 223 224 return converter 225 }, 226 ExpectedOutput: nil, 227 ExpectedError: testErr, 228 }, 229 { 230 Name: "Returns error when failing on the committing of a transaction", 231 First: &first, 232 TxFn: txGen.ThatFailsOnCommit, 233 FormationTemplateService: func() *automock.FormationTemplateService { 234 svc := &automock.FormationTemplateService{} 235 svc.On("List", txtest.CtxWithDBMatcher(), first, after).Return(&formationTemplateModelPage, nil) 236 237 return svc 238 }, 239 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 240 converter := &automock.FormationTemplateConverter{} 241 converter.On("MultipleToGraphQL", formationTemplateModelPage.Data).Return(graphQLFormationTemplatePage.Data, nil) 242 243 return converter 244 }, 245 ExpectedOutput: nil, 246 ExpectedError: testErr, 247 }, 248 { 249 Name: "Returns error missing first parameter", 250 First: nil, 251 TxFn: txGen.ThatDoesntExpectCommit, 252 FormationTemplateService: UnusedFormationTemplateService, 253 FormationTemplateConverter: UnusedFormationTemplateConverter, 254 ExpectedOutput: nil, 255 ExpectedError: apperrors.NewInvalidDataError("missing required parameter 'first'"), 256 }, 257 { 258 Name: "Returns error when failing on the beginning of a transaction", 259 First: &first, 260 TxFn: txGen.ThatFailsOnBegin, 261 FormationTemplateService: UnusedFormationTemplateService, 262 FormationTemplateConverter: UnusedFormationTemplateConverter, 263 ExpectedOutput: nil, 264 ExpectedError: testErr, 265 }, 266 } 267 268 for _, testCase := range testCases { 269 t.Run(testCase.Name, func(t *testing.T) { 270 persist, transact := testCase.TxFn() 271 formationTemplateSvc := testCase.FormationTemplateService() 272 formationTemplateConverter := testCase.FormationTemplateConverter() 273 274 resolver := formationtemplate.NewResolver(transact, formationTemplateConverter, formationTemplateSvc, nil, nil, nil) 275 276 // WHEN 277 result, err := resolver.FormationTemplates(ctx, testCase.First, &gqlAfter) 278 279 // THEN 280 if testCase.ExpectedError != nil { 281 require.Error(t, err) 282 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 283 } else { 284 assert.NoError(t, err) 285 } 286 assert.Equal(t, testCase.ExpectedOutput, result) 287 288 mock.AssertExpectationsForObjects(t, persist, formationTemplateSvc, formationTemplateConverter) 289 }) 290 } 291 } 292 293 func TestResolver_UpdateFormationTemplate(t *testing.T) { 294 // GIVEN 295 ctx := context.TODO() 296 297 testErr := errors.New("test error") 298 299 // removing the webhooks below because they do not affect the flow in any way but their validation is difficult to set up properly 300 gqlInputWithoutWebhooks := formationTemplateGraphQLInput 301 gqlInputWithoutWebhooks.Webhooks = nil 302 303 modelInputWithoutWebhooks := formationTemplateModelInput 304 modelInputWithoutWebhooks.Webhooks = nil 305 306 modelWithoutWebhooks := formationTemplateModel 307 modelWithoutWebhooks.Webhooks = nil 308 309 graphQLFormationTemplateWithoutWebhooks := graphQLFormationTemplate 310 graphQLFormationTemplateWithoutWebhooks.Webhooks = nil 311 312 txGen := txtest.NewTransactionContextGenerator(testErr) 313 314 testCases := []struct { 315 Name string 316 Input graphql.FormationTemplateInput 317 TxFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 318 FormationTemplateConverter func() *automock.FormationTemplateConverter 319 FormationTemplateService func() *automock.FormationTemplateService 320 ExpectedOutput *graphql.FormationTemplate 321 ExpectedError error 322 }{ 323 { 324 Name: "Success", 325 TxFn: txGen.ThatSucceeds, 326 Input: gqlInputWithoutWebhooks, 327 FormationTemplateService: func() *automock.FormationTemplateService { 328 svc := &automock.FormationTemplateService{} 329 svc.On("Update", txtest.CtxWithDBMatcher(), testID, &modelInputWithoutWebhooks).Return(nil) 330 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&modelWithoutWebhooks, nil) 331 332 return svc 333 }, 334 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 335 converter := &automock.FormationTemplateConverter{} 336 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 337 converter.On("ToGraphQL", &modelWithoutWebhooks).Return(&graphQLFormationTemplateWithoutWebhooks, nil) 338 339 return converter 340 }, 341 ExpectedOutput: &graphQLFormationTemplateWithoutWebhooks, 342 ExpectedError: nil, 343 }, 344 { 345 Name: "Error when converting from graphql fails", 346 Input: gqlInputWithoutWebhooks, 347 TxFn: txGen.ThatDoesntExpectCommit, 348 FormationTemplateService: UnusedFormationTemplateService, 349 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 350 converter := &automock.FormationTemplateConverter{} 351 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(nil, testErr) 352 353 return converter 354 }, 355 ExpectedOutput: nil, 356 ExpectedError: testErr, 357 }, 358 { 359 Name: "Error when updating call in service fails", 360 Input: gqlInputWithoutWebhooks, 361 TxFn: txGen.ThatDoesntExpectCommit, 362 FormationTemplateService: func() *automock.FormationTemplateService { 363 svc := &automock.FormationTemplateService{} 364 svc.On("Update", txtest.CtxWithDBMatcher(), testID, &modelInputWithoutWebhooks).Return(testErr) 365 366 return svc 367 }, 368 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 369 converter := &automock.FormationTemplateConverter{} 370 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 371 372 return converter 373 }, 374 ExpectedOutput: nil, 375 ExpectedError: testErr, 376 }, 377 { 378 Name: "Error when get call in service fails", 379 Input: gqlInputWithoutWebhooks, 380 TxFn: txGen.ThatDoesntExpectCommit, 381 FormationTemplateService: func() *automock.FormationTemplateService { 382 svc := &automock.FormationTemplateService{} 383 svc.On("Update", txtest.CtxWithDBMatcher(), testID, &modelInputWithoutWebhooks).Return(nil) 384 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testErr) 385 386 return svc 387 }, 388 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 389 converter := &automock.FormationTemplateConverter{} 390 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 391 392 return converter 393 }, 394 ExpectedOutput: nil, 395 ExpectedError: testErr, 396 }, 397 { 398 Name: "Error when converting to graphql fails", 399 Input: gqlInputWithoutWebhooks, 400 TxFn: txGen.ThatDoesntExpectCommit, 401 FormationTemplateService: func() *automock.FormationTemplateService { 402 svc := &automock.FormationTemplateService{} 403 svc.On("Update", txtest.CtxWithDBMatcher(), testID, &modelInputWithoutWebhooks).Return(nil) 404 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&modelWithoutWebhooks, nil) 405 406 return svc 407 }, 408 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 409 converter := &automock.FormationTemplateConverter{} 410 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 411 converter.On("ToGraphQL", &modelWithoutWebhooks).Return(nil, testErr) 412 413 return converter 414 }, 415 ExpectedOutput: nil, 416 ExpectedError: testErr, 417 }, 418 { 419 Name: "Returns error when failing on the committing of a transaction", 420 TxFn: txGen.ThatFailsOnCommit, 421 Input: gqlInputWithoutWebhooks, 422 FormationTemplateService: func() *automock.FormationTemplateService { 423 svc := &automock.FormationTemplateService{} 424 svc.On("Update", txtest.CtxWithDBMatcher(), testID, &modelInputWithoutWebhooks).Return(nil) 425 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&modelWithoutWebhooks, nil) 426 427 return svc 428 }, 429 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 430 converter := &automock.FormationTemplateConverter{} 431 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 432 converter.On("ToGraphQL", &modelWithoutWebhooks).Return(&graphQLFormationTemplateWithoutWebhooks, nil) 433 434 return converter 435 }, 436 ExpectedOutput: nil, 437 ExpectedError: testErr, 438 }, 439 { 440 Name: "Returns error when input validation fails", 441 Input: graphql.FormationTemplateInput{}, 442 TxFn: txGen.ThatDoesntExpectCommit, 443 FormationTemplateService: UnusedFormationTemplateService, 444 FormationTemplateConverter: UnusedFormationTemplateConverter, 445 ExpectedOutput: nil, 446 ExpectedError: errors.New("cannot be blank"), 447 }, 448 { 449 Name: "Returns error when failing on the beginning of a transaction", 450 Input: formationTemplateGraphQLInput, 451 TxFn: txGen.ThatFailsOnBegin, 452 FormationTemplateService: UnusedFormationTemplateService, 453 FormationTemplateConverter: UnusedFormationTemplateConverter, 454 ExpectedOutput: nil, 455 ExpectedError: testErr, 456 }, 457 } 458 459 for _, testCase := range testCases { 460 t.Run(testCase.Name, func(t *testing.T) { 461 persist, transact := testCase.TxFn() 462 formationTemplateSvc := testCase.FormationTemplateService() 463 formationTemplateConverter := testCase.FormationTemplateConverter() 464 465 resolver := formationtemplate.NewResolver(transact, formationTemplateConverter, formationTemplateSvc, nil, nil, nil) 466 467 // WHEN 468 result, err := resolver.UpdateFormationTemplate(ctx, testID, testCase.Input) 469 470 // THEN 471 if testCase.ExpectedError != nil { 472 require.Error(t, err) 473 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 474 } else { 475 assert.NoError(t, err) 476 } 477 assert.Equal(t, testCase.ExpectedOutput, result) 478 479 mock.AssertExpectationsForObjects(t, persist, formationTemplateSvc, formationTemplateConverter) 480 }) 481 } 482 } 483 484 func TestResolver_DeleteFormationTemplate(t *testing.T) { 485 // GIVEN 486 ctx := context.TODO() 487 488 testErr := errors.New("test error") 489 490 txGen := txtest.NewTransactionContextGenerator(testErr) 491 492 testCases := []struct { 493 Name string 494 TxFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 495 FormationTemplateConverter func() *automock.FormationTemplateConverter 496 FormationTemplateService func() *automock.FormationTemplateService 497 ExpectedOutput *graphql.FormationTemplate 498 ExpectedError error 499 }{ 500 { 501 Name: "Success", 502 TxFn: txGen.ThatSucceeds, 503 FormationTemplateService: func() *automock.FormationTemplateService { 504 svc := &automock.FormationTemplateService{} 505 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&formationTemplateModel, nil) 506 svc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(nil) 507 508 return svc 509 }, 510 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 511 converter := &automock.FormationTemplateConverter{} 512 converter.On("ToGraphQL", &formationTemplateModel).Return(&graphQLFormationTemplate, nil) 513 514 return converter 515 }, 516 ExpectedOutput: &graphQLFormationTemplate, 517 ExpectedError: nil, 518 }, 519 { 520 Name: "Error when get call in service fails", 521 TxFn: txGen.ThatDoesntExpectCommit, 522 FormationTemplateService: func() *automock.FormationTemplateService { 523 svc := &automock.FormationTemplateService{} 524 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testErr) 525 526 return svc 527 }, 528 FormationTemplateConverter: UnusedFormationTemplateConverter, 529 ExpectedOutput: nil, 530 ExpectedError: testErr, 531 }, 532 { 533 Name: "Error when delete call in service fails", 534 TxFn: txGen.ThatDoesntExpectCommit, 535 FormationTemplateService: func() *automock.FormationTemplateService { 536 svc := &automock.FormationTemplateService{} 537 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&formationTemplateModel, nil) 538 svc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(testErr) 539 540 return svc 541 }, 542 FormationTemplateConverter: UnusedFormationTemplateConverter, 543 ExpectedOutput: nil, 544 ExpectedError: testErr, 545 }, 546 { 547 Name: "Error when converting to graphql fails", 548 TxFn: txGen.ThatDoesntExpectCommit, 549 FormationTemplateService: func() *automock.FormationTemplateService { 550 svc := &automock.FormationTemplateService{} 551 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&formationTemplateModel, nil) 552 svc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(nil) 553 554 return svc 555 }, 556 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 557 converter := &automock.FormationTemplateConverter{} 558 converter.On("ToGraphQL", &formationTemplateModel).Return(nil, testErr) 559 560 return converter 561 }, 562 ExpectedOutput: nil, 563 ExpectedError: testErr, 564 }, 565 { 566 Name: "Returns error when failing on the committing of a transaction", 567 TxFn: txGen.ThatFailsOnCommit, 568 FormationTemplateService: func() *automock.FormationTemplateService { 569 svc := &automock.FormationTemplateService{} 570 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&formationTemplateModel, nil) 571 svc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(nil) 572 573 return svc 574 }, 575 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 576 converter := &automock.FormationTemplateConverter{} 577 converter.On("ToGraphQL", &formationTemplateModel).Return(&graphQLFormationTemplate, nil) 578 579 return converter 580 }, 581 ExpectedOutput: nil, 582 ExpectedError: testErr, 583 }, 584 { 585 Name: "Returns error when failing on the beginning of a transaction", 586 TxFn: txGen.ThatFailsOnBegin, 587 FormationTemplateService: UnusedFormationTemplateService, 588 FormationTemplateConverter: UnusedFormationTemplateConverter, 589 ExpectedOutput: nil, 590 ExpectedError: testErr, 591 }, 592 } 593 594 for _, testCase := range testCases { 595 t.Run(testCase.Name, func(t *testing.T) { 596 persist, transact := testCase.TxFn() 597 formationTemplateSvc := testCase.FormationTemplateService() 598 formationTemplateConverter := testCase.FormationTemplateConverter() 599 600 resolver := formationtemplate.NewResolver(transact, formationTemplateConverter, formationTemplateSvc, nil, nil, nil) 601 602 // WHEN 603 result, err := resolver.DeleteFormationTemplate(ctx, testID) 604 605 // THEN 606 if testCase.ExpectedError != nil { 607 require.Error(t, err) 608 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 609 } else { 610 assert.NoError(t, err) 611 } 612 assert.Equal(t, testCase.ExpectedOutput, result) 613 614 mock.AssertExpectationsForObjects(t, persist, formationTemplateSvc, formationTemplateConverter) 615 }) 616 } 617 } 618 619 func TestResolver_CreateFormationTemplate(t *testing.T) { 620 // GIVEN 621 ctx := context.TODO() 622 623 testErr := errors.New("test error") 624 625 // removing the webhooks below because they do not affect the flow in any way but their validation is difficult to set up properly 626 gqlInputWithoutWebhooks := formationTemplateGraphQLInput 627 gqlInputWithoutWebhooks.Webhooks = nil 628 629 modelInputWithoutWebhooks := formationTemplateModelInput 630 modelInputWithoutWebhooks.Webhooks = nil 631 632 modelWithoutWebhooks := formationTemplateModel 633 modelWithoutWebhooks.Webhooks = nil 634 635 graphQLFormationTemplateWithoutWebhooks := graphQLFormationTemplate 636 graphQLFormationTemplateWithoutWebhooks.Webhooks = nil 637 638 txGen := txtest.NewTransactionContextGenerator(testErr) 639 640 testCases := []struct { 641 Name string 642 Input graphql.FormationTemplateInput 643 TxFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 644 FormationTemplateConverter func() *automock.FormationTemplateConverter 645 FormationTemplateService func() *automock.FormationTemplateService 646 ExpectedOutput *graphql.FormationTemplate 647 ExpectedError error 648 }{ 649 { 650 Name: "Success", 651 TxFn: txGen.ThatSucceeds, 652 Input: gqlInputWithoutWebhooks, 653 FormationTemplateService: func() *automock.FormationTemplateService { 654 svc := &automock.FormationTemplateService{} 655 svc.On("Create", txtest.CtxWithDBMatcher(), &modelInputWithoutWebhooks).Return(testID, nil) 656 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&modelWithoutWebhooks, nil) 657 658 return svc 659 }, 660 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 661 converter := &automock.FormationTemplateConverter{} 662 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 663 converter.On("ToGraphQL", &modelWithoutWebhooks).Return(&graphQLFormationTemplateWithoutWebhooks, nil) 664 665 return converter 666 }, 667 ExpectedOutput: &graphQLFormationTemplateWithoutWebhooks, 668 ExpectedError: nil, 669 }, 670 { 671 Name: "Error when converting from graphql fails", 672 Input: gqlInputWithoutWebhooks, 673 TxFn: txGen.ThatDoesntExpectCommit, 674 FormationTemplateService: UnusedFormationTemplateService, 675 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 676 converter := &automock.FormationTemplateConverter{} 677 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(nil, testErr) 678 679 return converter 680 }, 681 ExpectedOutput: nil, 682 ExpectedError: testErr, 683 }, 684 { 685 Name: "Error when creating call to service fails", 686 Input: gqlInputWithoutWebhooks, 687 TxFn: txGen.ThatDoesntExpectCommit, 688 FormationTemplateService: func() *automock.FormationTemplateService { 689 svc := &automock.FormationTemplateService{} 690 svc.On("Create", txtest.CtxWithDBMatcher(), &modelInputWithoutWebhooks).Return("", testErr) 691 692 return svc 693 }, 694 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 695 converter := &automock.FormationTemplateConverter{} 696 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 697 698 return converter 699 }, 700 ExpectedOutput: nil, 701 ExpectedError: testErr, 702 }, 703 { 704 Name: "Error when get call to service fails", 705 Input: gqlInputWithoutWebhooks, 706 TxFn: txGen.ThatDoesntExpectCommit, 707 FormationTemplateService: func() *automock.FormationTemplateService { 708 svc := &automock.FormationTemplateService{} 709 svc.On("Create", txtest.CtxWithDBMatcher(), &modelInputWithoutWebhooks).Return(testID, nil) 710 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testErr) 711 712 return svc 713 }, 714 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 715 converter := &automock.FormationTemplateConverter{} 716 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 717 718 return converter 719 }, 720 ExpectedOutput: nil, 721 ExpectedError: testErr, 722 }, 723 { 724 Name: "Error when converting to graphql fails", 725 Input: gqlInputWithoutWebhooks, 726 TxFn: txGen.ThatDoesntExpectCommit, 727 FormationTemplateService: func() *automock.FormationTemplateService { 728 svc := &automock.FormationTemplateService{} 729 svc.On("Create", txtest.CtxWithDBMatcher(), &modelInputWithoutWebhooks).Return(testID, nil) 730 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&modelWithoutWebhooks, nil) 731 732 return svc 733 }, 734 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 735 converter := &automock.FormationTemplateConverter{} 736 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 737 converter.On("ToGraphQL", &modelWithoutWebhooks).Return(nil, testErr) 738 739 return converter 740 }, 741 ExpectedOutput: nil, 742 ExpectedError: testErr, 743 }, 744 { 745 Name: "Returns error when failing on the committing of a transaction", 746 TxFn: txGen.ThatFailsOnCommit, 747 Input: gqlInputWithoutWebhooks, 748 FormationTemplateService: func() *automock.FormationTemplateService { 749 svc := &automock.FormationTemplateService{} 750 svc.On("Create", txtest.CtxWithDBMatcher(), &modelInputWithoutWebhooks).Return(testID, nil) 751 svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&modelWithoutWebhooks, nil) 752 753 return svc 754 }, 755 FormationTemplateConverter: func() *automock.FormationTemplateConverter { 756 converter := &automock.FormationTemplateConverter{} 757 converter.On("FromInputGraphQL", &gqlInputWithoutWebhooks).Return(&modelInputWithoutWebhooks, nil) 758 converter.On("ToGraphQL", &modelWithoutWebhooks).Return(&graphQLFormationTemplateWithoutWebhooks, nil) 759 760 return converter 761 }, 762 ExpectedOutput: nil, 763 ExpectedError: testErr, 764 }, 765 { 766 Name: "Returns error when input validation fails", 767 Input: graphql.FormationTemplateInput{}, 768 TxFn: txGen.ThatDoesntExpectCommit, 769 FormationTemplateService: UnusedFormationTemplateService, 770 FormationTemplateConverter: UnusedFormationTemplateConverter, 771 ExpectedOutput: nil, 772 ExpectedError: errors.New("cannot be blank"), 773 }, 774 { 775 Name: "Returns error when failing on the beginning of a transaction", 776 Input: gqlInputWithoutWebhooks, 777 TxFn: txGen.ThatFailsOnBegin, 778 FormationTemplateService: UnusedFormationTemplateService, 779 FormationTemplateConverter: UnusedFormationTemplateConverter, 780 ExpectedOutput: nil, 781 ExpectedError: testErr, 782 }, 783 } 784 785 for _, testCase := range testCases { 786 t.Run(testCase.Name, func(t *testing.T) { 787 persist, transact := testCase.TxFn() 788 formationTemplateSvc := testCase.FormationTemplateService() 789 formationTemplateConverter := testCase.FormationTemplateConverter() 790 791 resolver := formationtemplate.NewResolver(transact, formationTemplateConverter, formationTemplateSvc, nil, nil, nil) 792 793 // WHEN 794 result, err := resolver.CreateFormationTemplate(ctx, testCase.Input) 795 796 // THEN 797 if testCase.ExpectedError != nil { 798 require.Error(t, err) 799 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 800 } else { 801 assert.NoError(t, err) 802 } 803 assert.Equal(t, testCase.ExpectedOutput, result) 804 805 mock.AssertExpectationsForObjects(t, persist, formationTemplateSvc, formationTemplateConverter) 806 }) 807 } 808 } 809 810 func TestResolver_Webhooks(t *testing.T) { 811 // GIVEN 812 ctx := context.TODO() 813 814 testErr := errors.New("test error") 815 816 modelWebhooks := []*model.Webhook{fixFormationTemplateModelWebhook()} 817 gqlWebhooks := []*graphql.Webhook{fixFormationTemplateGQLWebhook()} 818 819 txGen := txtest.NewTransactionContextGenerator(testErr) 820 testCases := []struct { 821 Name string 822 TxFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 823 Input *graphql.FormationTemplate 824 WebhookConverter func() *automock.WebhookConverter 825 FormationTemplateService func() *automock.FormationTemplateService 826 ExpectedOutput []*graphql.Webhook 827 ExpectedError error 828 }{ 829 { 830 Name: "Success", 831 TxFn: txGen.ThatSucceeds, 832 Input: &graphQLFormationTemplate, 833 FormationTemplateService: func() *automock.FormationTemplateService { 834 svc := &automock.FormationTemplateService{} 835 svc.On("ListWebhooksForFormationTemplate", txtest.CtxWithDBMatcher(), graphQLFormationTemplate.ID).Return(modelWebhooks, nil) 836 return svc 837 }, 838 WebhookConverter: func() *automock.WebhookConverter { 839 converter := &automock.WebhookConverter{} 840 converter.On("MultipleToGraphQL", modelWebhooks).Return(gqlWebhooks, nil) 841 return converter 842 }, 843 ExpectedOutput: gqlWebhooks, 844 ExpectedError: nil, 845 }, 846 { 847 Name: "Error when listing webhooks fails", 848 TxFn: txGen.ThatDoesntExpectCommit, 849 Input: &graphQLFormationTemplate, 850 FormationTemplateService: func() *automock.FormationTemplateService { 851 svc := &automock.FormationTemplateService{} 852 svc.On("ListWebhooksForFormationTemplate", txtest.CtxWithDBMatcher(), graphQLFormationTemplate.ID).Return(nil, testErr) 853 return svc 854 }, 855 WebhookConverter: func() *automock.WebhookConverter { 856 return &automock.WebhookConverter{} 857 }, 858 ExpectedOutput: nil, 859 ExpectedError: testErr, 860 }, 861 { 862 Name: "Error when converting webhooks fails", 863 TxFn: txGen.ThatDoesntExpectCommit, 864 Input: &graphQLFormationTemplate, 865 FormationTemplateService: func() *automock.FormationTemplateService { 866 svc := &automock.FormationTemplateService{} 867 svc.On("ListWebhooksForFormationTemplate", txtest.CtxWithDBMatcher(), graphQLFormationTemplate.ID).Return(modelWebhooks, nil) 868 return svc 869 }, 870 WebhookConverter: func() *automock.WebhookConverter { 871 converter := &automock.WebhookConverter{} 872 converter.On("MultipleToGraphQL", modelWebhooks).Return(nil, testErr) 873 return converter 874 }, 875 ExpectedOutput: nil, 876 ExpectedError: testErr, 877 }, 878 { 879 Name: "Returns error when failing on the committing of a transaction", 880 TxFn: txGen.ThatFailsOnCommit, 881 Input: &graphQLFormationTemplate, 882 FormationTemplateService: func() *automock.FormationTemplateService { 883 svc := &automock.FormationTemplateService{} 884 svc.On("ListWebhooksForFormationTemplate", txtest.CtxWithDBMatcher(), graphQLFormationTemplate.ID).Return(modelWebhooks, nil) 885 return svc 886 }, 887 WebhookConverter: func() *automock.WebhookConverter { 888 converter := &automock.WebhookConverter{} 889 converter.On("MultipleToGraphQL", modelWebhooks).Return(gqlWebhooks, nil) 890 return converter 891 }, 892 ExpectedOutput: nil, 893 ExpectedError: testErr, 894 }, 895 { 896 Name: "Returns error when failing on the beginning of a transaction", 897 TxFn: txGen.ThatFailsOnBegin, 898 Input: &graphQLFormationTemplate, 899 FormationTemplateService: func() *automock.FormationTemplateService { 900 svc := &automock.FormationTemplateService{} 901 svc.On("ListWebhooksForFormationTemplate", txtest.CtxWithDBMatcher(), graphQLFormationTemplate.ID).Return(modelWebhooks, nil) 902 return svc 903 }, 904 WebhookConverter: func() *automock.WebhookConverter { 905 return &automock.WebhookConverter{} 906 }, 907 ExpectedOutput: nil, 908 ExpectedError: testErr, 909 }, 910 { 911 Name: "Returns error when input formation template is nil", 912 TxFn: txGen.ThatFailsOnBegin, 913 Input: nil, 914 FormationTemplateService: func() *automock.FormationTemplateService { 915 return &automock.FormationTemplateService{} 916 }, 917 WebhookConverter: func() *automock.WebhookConverter { 918 return &automock.WebhookConverter{} 919 }, 920 ExpectedOutput: nil, 921 ExpectedError: apperrors.NewInternalError("Formation Template cannot be empty"), 922 }, 923 } 924 925 for _, testCase := range testCases { 926 t.Run(testCase.Name, func(t *testing.T) { 927 persist, transact := testCase.TxFn() 928 formationTemplateSvc := testCase.FormationTemplateService() 929 whConv := testCase.WebhookConverter() 930 931 resolver := formationtemplate.NewResolver(transact, nil, formationTemplateSvc, whConv, nil, nil) 932 933 // WHEN 934 result, err := resolver.Webhooks(ctx, testCase.Input) 935 936 // THEN 937 if testCase.ExpectedError != nil { 938 require.Error(t, err) 939 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 940 } else { 941 assert.NoError(t, err) 942 } 943 assert.Equal(t, testCase.ExpectedOutput, result) 944 945 mock.AssertExpectationsForObjects(t, persist, whConv) 946 }) 947 } 948 } 949 950 func TestResolver_FormationConstraints(t *testing.T) { 951 ctx := context.TODO() 952 txGen := txtest.NewTransactionContextGenerator(testErr) 953 954 formationConstraintIDs := []string{constraintID1, constraintID2} 955 956 formationConstraintsModel := [][]*model.FormationConstraint{{formationConstraint1}, {formationConstraint2}} 957 958 formationConstraintsGql := [][]*graphql.FormationConstraint{{formationConstraintGql1}, {formationConstraintGql2}} 959 960 testCases := []struct { 961 Name string 962 TxFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 963 Input []dataloader.ParamFormationConstraint 964 FormationConstraintSvc func() *automock.FormationConstraintService 965 FormationConstraintConverter func() *automock.FormationConstraintConverter 966 ExpectedConstraints [][]*graphql.FormationConstraint 967 ExpectedErrors []error 968 }{ 969 { 970 Name: "Success", 971 TxFn: txGen.ThatSucceeds, 972 Input: []dataloader.ParamFormationConstraint{{ID: formationConstraintIDs[0], Ctx: ctx}, {ID: formationConstraintIDs[1], Ctx: ctx}}, 973 FormationConstraintSvc: func() *automock.FormationConstraintService { 974 svc := &automock.FormationConstraintService{} 975 svc.On("ListByFormationTemplateIDs", txtest.CtxWithDBMatcher(), formationConstraintIDs).Return(formationConstraintsModel, nil).Once() 976 return svc 977 }, 978 FormationConstraintConverter: func() *automock.FormationConstraintConverter { 979 converter := &automock.FormationConstraintConverter{} 980 converter.On("MultipleToGraphQL", formationConstraintsModel[0]).Return(formationConstraintsGql[0]).Once() 981 converter.On("MultipleToGraphQL", formationConstraintsModel[1]).Return(formationConstraintsGql[1]).Once() 982 return converter 983 }, 984 ExpectedConstraints: formationConstraintsGql, 985 ExpectedErrors: nil, 986 }, 987 { 988 Name: "Returns error if commit fails", 989 TxFn: txGen.ThatFailsOnCommit, 990 Input: []dataloader.ParamFormationConstraint{{ID: formationConstraintIDs[0], Ctx: ctx}, {ID: formationConstraintIDs[1], Ctx: ctx}}, 991 FormationConstraintSvc: func() *automock.FormationConstraintService { 992 svc := &automock.FormationConstraintService{} 993 svc.On("ListByFormationTemplateIDs", txtest.CtxWithDBMatcher(), formationConstraintIDs).Return(formationConstraintsModel, nil).Once() 994 return svc 995 }, 996 FormationConstraintConverter: func() *automock.FormationConstraintConverter { 997 converter := &automock.FormationConstraintConverter{} 998 converter.On("MultipleToGraphQL", formationConstraintsModel[0]).Return(formationConstraintsGql[0]).Once() 999 converter.On("MultipleToGraphQL", formationConstraintsModel[1]).Return(formationConstraintsGql[1]).Once() 1000 return converter 1001 }, 1002 ExpectedConstraints: nil, 1003 ExpectedErrors: []error{testErr}, 1004 }, 1005 { 1006 Name: "Returns error when listing the formation templates by ids fail", 1007 TxFn: txGen.ThatDoesntExpectCommit, 1008 Input: []dataloader.ParamFormationConstraint{{ID: formationConstraintIDs[0], Ctx: ctx}, {ID: formationConstraintIDs[1], Ctx: ctx}}, 1009 FormationConstraintSvc: func() *automock.FormationConstraintService { 1010 svc := &automock.FormationConstraintService{} 1011 svc.On("ListByFormationTemplateIDs", txtest.CtxWithDBMatcher(), formationConstraintIDs).Return(nil, testErr).Once() 1012 return svc 1013 }, 1014 ExpectedConstraints: nil, 1015 ExpectedErrors: []error{testErr}, 1016 }, 1017 { 1018 Name: "Returns error when can't start transaction", 1019 TxFn: txGen.ThatFailsOnBegin, 1020 Input: []dataloader.ParamFormationConstraint{{ID: formationConstraintIDs[0], Ctx: ctx}, {ID: formationConstraintIDs[1], Ctx: ctx}}, 1021 ExpectedConstraints: nil, 1022 ExpectedErrors: []error{testErr}, 1023 }, 1024 { 1025 Name: "Returns error when input does not contain formation templates", 1026 TxFn: txGen.ThatDoesntStartTransaction, 1027 Input: []dataloader.ParamFormationConstraint{}, 1028 ExpectedConstraints: nil, 1029 ExpectedErrors: []error{apperrors.NewInternalError("No Formation Templates found")}, 1030 }, 1031 } 1032 1033 for _, testCase := range testCases { 1034 t.Run(testCase.Name, func(t *testing.T) { 1035 persist, transact := testCase.TxFn() 1036 svc := UnusedFormationConstraintService() 1037 if testCase.FormationConstraintSvc != nil { 1038 svc = testCase.FormationConstraintSvc() 1039 } 1040 converter := UnusedFormationConstraintConverter() 1041 if testCase.FormationConstraintConverter != nil { 1042 converter = testCase.FormationConstraintConverter() 1043 } 1044 1045 resolver := formationtemplate.NewResolver(transact, nil, nil, nil, svc, converter) 1046 1047 res, errs := resolver.FormationConstraintsDataLoader(testCase.Input) 1048 if testCase.ExpectedErrors != nil { 1049 assert.Error(t, errs[0]) 1050 assert.Nil(t, res) 1051 } else { 1052 require.Nil(t, errs) 1053 reflect.DeepEqual(res, testCase.ExpectedConstraints) 1054 } 1055 1056 mock.AssertExpectationsForObjects(t, persist, svc, converter) 1057 }) 1058 } 1059 }