github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/webhook/resolver_test.go (about) 1 package webhook_test 2 3 import ( 4 "context" 5 "errors" 6 "time" 7 8 "github.com/kyma-incubator/compass/components/director/internal/model" 9 10 "github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest" 11 12 "github.com/stretchr/testify/require" 13 14 "testing" 15 16 "github.com/kyma-incubator/compass/components/director/internal/domain/webhook" 17 "github.com/kyma-incubator/compass/components/director/internal/domain/webhook/automock" 18 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 19 persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock" 20 21 "github.com/stretchr/testify/assert" 22 ) 23 24 func TestResolver_AddWebhook(t *testing.T) { 25 // GIVEN 26 testErr := errors.New("Test error") 27 28 givenAppID := "foo" 29 givenAppTemplateID := "test_app_template" 30 givenRuntimeID := "test_runtime" 31 givenFormationTemplateID := "ftID" 32 id := "bar" 33 gqlWebhookInput := fixGQLWebhookInput("foo") 34 modelWebhookInput := fixModelWebhookInput("foo") 35 36 gqlWebhook := fixApplicationGQLWebhook(id, "", "") 37 modelWebhook := fixApplicationModelWebhook(id, givenAppID, givenTenant(), "foo", time.Time{}) 38 39 testCases := []struct { 40 Name string 41 PersistenceFn func() *persistenceautomock.PersistenceTx 42 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 43 ServiceFn func() *automock.WebhookService 44 AppServiceFn func() *automock.ApplicationService 45 AppTemplateServiceFn func() *automock.ApplicationTemplateService 46 RuntimeServiceFn func() *automock.RuntimeService 47 FormationTemplateServiceFn func() *automock.FormationTemplateService 48 ConverterFn func() *automock.WebhookConverter 49 ExpectedWebhook *graphql.Webhook 50 ExpectedErr error 51 }{ 52 { 53 Name: "Success", 54 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 55 TransactionerFn: txtest.TransactionerThatSucceeds, 56 ServiceFn: func() *automock.WebhookService { 57 svc := &automock.WebhookService{} 58 svc.On("Create", txtest.CtxWithDBMatcher(), givenAppID, *modelWebhookInput, model.ApplicationWebhookReference).Return(id, nil).Once() 59 svc.On("Get", txtest.CtxWithDBMatcher(), id, model.ApplicationWebhookReference).Return(modelWebhook, nil).Once() 60 return svc 61 }, 62 AppServiceFn: func() *automock.ApplicationService { 63 appSvc := &automock.ApplicationService{} 64 appSvc.On("Exist", txtest.CtxWithDBMatcher(), givenAppID).Return(true, nil).Once() 65 return appSvc 66 }, 67 ConverterFn: func() *automock.WebhookConverter { 68 conv := &automock.WebhookConverter{} 69 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 70 conv.On("ToGraphQL", modelWebhook).Return(gqlWebhook, nil).Once() 71 return conv 72 }, 73 ExpectedWebhook: gqlWebhook, 74 ExpectedErr: nil, 75 }, 76 { 77 Name: "Returns error on starting transaction", 78 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 79 TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner { 80 transact := &persistenceautomock.Transactioner{} 81 transact.On("Begin").Return(persistTx, givenError()).Once() 82 return transact 83 }, 84 ServiceFn: func() *automock.WebhookService { 85 return &automock.WebhookService{} 86 }, 87 AppServiceFn: func() *automock.ApplicationService { 88 return &automock.ApplicationService{} 89 }, 90 ConverterFn: func() *automock.WebhookConverter { 91 return &automock.WebhookConverter{} 92 }, 93 ExpectedErr: givenError(), 94 }, 95 { 96 Name: "Returns error on webhook conversion", 97 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 98 TransactionerFn: txtest.TransactionerThatDoesARollback, 99 ServiceFn: func() *automock.WebhookService { 100 return &automock.WebhookService{} 101 }, 102 AppServiceFn: func() *automock.ApplicationService { 103 return &automock.ApplicationService{} 104 }, 105 ConverterFn: func() *automock.WebhookConverter { 106 converter := &automock.WebhookConverter{} 107 converter.Mock.On("InputFromGraphQL", gqlWebhookInput).Return(nil, testErr) 108 return converter 109 }, 110 ExpectedErr: errors.New("while converting the WebhookInput: Test error"), 111 }, 112 { 113 Name: "Returns error on committing transaction", 114 PersistenceFn: func() *persistenceautomock.PersistenceTx { 115 persistTx := &persistenceautomock.PersistenceTx{} 116 persistTx.On("Commit").Return(givenError()).Once() 117 return persistTx 118 }, 119 TransactionerFn: txtest.TransactionerThatSucceeds, 120 ServiceFn: func() *automock.WebhookService { 121 svc := &automock.WebhookService{} 122 svc.On("Create", txtest.CtxWithDBMatcher(), givenAppID, *modelWebhookInput, model.ApplicationWebhookReference).Return(id, nil).Once() 123 svc.On("Get", txtest.CtxWithDBMatcher(), id, model.ApplicationWebhookReference).Return(modelWebhook, nil).Once() 124 return svc 125 }, 126 AppServiceFn: func() *automock.ApplicationService { 127 appSvc := &automock.ApplicationService{} 128 appSvc.On("Exist", txtest.CtxWithDBMatcher(), givenAppID).Return(true, nil).Once() 129 return appSvc 130 }, 131 ConverterFn: func() *automock.WebhookConverter { 132 conv := &automock.WebhookConverter{} 133 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 134 return conv 135 }, 136 ExpectedErr: givenError(), 137 }, 138 { 139 Name: "Returns error when application does not exist", 140 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 141 TransactionerFn: txtest.TransactionerThatSucceeds, 142 ServiceFn: func() *automock.WebhookService { 143 svc := &automock.WebhookService{} 144 return svc 145 }, 146 AppServiceFn: func() *automock.ApplicationService { 147 appSvc := &automock.ApplicationService{} 148 appSvc.On("Exist", txtest.CtxWithDBMatcher(), givenAppID).Return(false, nil) 149 return appSvc 150 }, 151 ConverterFn: func() *automock.WebhookConverter { 152 conv := &automock.WebhookConverter{} 153 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 154 return conv 155 }, 156 ExpectedWebhook: nil, 157 ExpectedErr: errors.New("cannot add ApplicationWebhook due to not existing reference entity"), 158 }, 159 { 160 Name: "Returns error when application template does not exist", 161 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 162 TransactionerFn: txtest.TransactionerThatSucceeds, 163 ServiceFn: func() *automock.WebhookService { 164 svc := &automock.WebhookService{} 165 return svc 166 }, 167 AppTemplateServiceFn: func() *automock.ApplicationTemplateService { 168 appTemplateSvc := &automock.ApplicationTemplateService{} 169 appTemplateSvc.On("Exists", txtest.CtxWithDBMatcher(), givenAppTemplateID).Return(false, nil) 170 return appTemplateSvc 171 }, 172 ConverterFn: func() *automock.WebhookConverter { 173 conv := &automock.WebhookConverter{} 174 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 175 return conv 176 }, 177 ExpectedWebhook: nil, 178 ExpectedErr: errors.New("cannot add ApplicationTemplateWebhook due to not existing reference entity"), 179 }, 180 { 181 Name: "Returns error when runtime does not exist", 182 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 183 TransactionerFn: txtest.TransactionerThatSucceeds, 184 ServiceFn: func() *automock.WebhookService { 185 svc := &automock.WebhookService{} 186 return svc 187 }, 188 RuntimeServiceFn: func() *automock.RuntimeService { 189 runtimeSvc := &automock.RuntimeService{} 190 runtimeSvc.On("Exist", txtest.CtxWithDBMatcher(), givenRuntimeID).Return(false, nil) 191 return runtimeSvc 192 }, 193 ConverterFn: func() *automock.WebhookConverter { 194 conv := &automock.WebhookConverter{} 195 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 196 return conv 197 }, 198 ExpectedWebhook: nil, 199 ExpectedErr: errors.New("cannot add RuntimeWebhook due to not existing reference entity"), 200 }, 201 { 202 Name: "Returns error when formation template does not exist", 203 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 204 TransactionerFn: txtest.TransactionerThatSucceeds, 205 ServiceFn: func() *automock.WebhookService { 206 svc := &automock.WebhookService{} 207 return svc 208 }, 209 FormationTemplateServiceFn: func() *automock.FormationTemplateService { 210 ftSvc := &automock.FormationTemplateService{} 211 ftSvc.On("Exist", txtest.CtxWithDBMatcher(), givenFormationTemplateID).Return(false, nil) 212 return ftSvc 213 }, 214 ConverterFn: func() *automock.WebhookConverter { 215 conv := &automock.WebhookConverter{} 216 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 217 return conv 218 }, 219 ExpectedWebhook: nil, 220 ExpectedErr: errors.New("cannot add FormationTemplateWebhook due to not existing reference entity"), 221 }, 222 { 223 Name: "Returns error when application existence check failed", 224 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 225 TransactionerFn: txtest.TransactionerThatSucceeds, 226 ServiceFn: func() *automock.WebhookService { 227 svc := &automock.WebhookService{} 228 return svc 229 }, 230 AppServiceFn: func() *automock.ApplicationService { 231 appSvc := &automock.ApplicationService{} 232 appSvc.On("Exist", txtest.CtxWithDBMatcher(), givenAppID).Return(false, testErr).Once() 233 return appSvc 234 }, 235 ConverterFn: func() *automock.WebhookConverter { 236 conv := &automock.WebhookConverter{} 237 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 238 return conv 239 }, 240 ExpectedWebhook: nil, 241 ExpectedErr: testErr, 242 }, 243 { 244 Name: "Returns error when webhook creation failed", 245 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 246 TransactionerFn: txtest.TransactionerThatSucceeds, 247 ServiceFn: func() *automock.WebhookService { 248 svc := &automock.WebhookService{} 249 svc.On("Create", txtest.CtxWithDBMatcher(), givenAppID, *modelWebhookInput, model.ApplicationWebhookReference).Return("", testErr).Once() 250 return svc 251 }, 252 AppServiceFn: func() *automock.ApplicationService { 253 appSvc := &automock.ApplicationService{} 254 appSvc.On("Exist", txtest.CtxWithDBMatcher(), givenAppID).Return(true, nil).Once() 255 return appSvc 256 }, 257 ConverterFn: func() *automock.WebhookConverter { 258 conv := &automock.WebhookConverter{} 259 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 260 return conv 261 }, 262 ExpectedWebhook: nil, 263 ExpectedErr: testErr, 264 }, 265 { 266 Name: "Returns error when webhook retrieval failed", 267 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 268 TransactionerFn: txtest.TransactionerThatSucceeds, 269 ServiceFn: func() *automock.WebhookService { 270 svc := &automock.WebhookService{} 271 svc.On("Create", txtest.CtxWithDBMatcher(), givenAppID, *modelWebhookInput, model.ApplicationWebhookReference).Return(id, nil).Once() 272 svc.On("Get", txtest.CtxWithDBMatcher(), id, model.ApplicationWebhookReference).Return(nil, testErr).Once() 273 return svc 274 }, 275 AppServiceFn: func() *automock.ApplicationService { 276 appSvc := &automock.ApplicationService{} 277 appSvc.On("Exist", txtest.CtxWithDBMatcher(), givenAppID).Return(true, nil).Once() 278 return appSvc 279 }, 280 ConverterFn: func() *automock.WebhookConverter { 281 conv := &automock.WebhookConverter{} 282 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 283 return conv 284 }, 285 ExpectedWebhook: nil, 286 ExpectedErr: testErr, 287 }, 288 } 289 290 for _, testCase := range testCases { 291 t.Run(testCase.Name, func(t *testing.T) { 292 var appSvc *automock.ApplicationService 293 var appTemplateSvc *automock.ApplicationTemplateService 294 var runtimeSvc *automock.RuntimeService 295 var formationTemplateSvc *automock.FormationTemplateService 296 svc := testCase.ServiceFn() 297 if testCase.AppServiceFn != nil { 298 appSvc = testCase.AppServiceFn() 299 } 300 if testCase.AppTemplateServiceFn != nil { 301 appTemplateSvc = testCase.AppTemplateServiceFn() 302 } 303 if testCase.RuntimeServiceFn != nil { 304 runtimeSvc = testCase.RuntimeServiceFn() 305 } 306 if testCase.FormationTemplateServiceFn != nil { 307 formationTemplateSvc = testCase.FormationTemplateServiceFn() 308 } 309 310 converter := testCase.ConverterFn() 311 312 persistTxMock := testCase.PersistenceFn() 313 transactionerMock := testCase.TransactionerFn(persistTxMock) 314 315 resolver := webhook.NewResolver(transactionerMock, svc, appSvc, appTemplateSvc, runtimeSvc, formationTemplateSvc, converter) 316 317 // WHEN 318 var err error 319 var result *graphql.Webhook 320 if testCase.AppServiceFn != nil { 321 result, err = resolver.AddWebhook(context.TODO(), stringPtr(givenAppID), nil, nil, nil, *gqlWebhookInput) 322 } 323 if testCase.AppTemplateServiceFn != nil { 324 result, err = resolver.AddWebhook(context.TODO(), nil, stringPtr(givenAppTemplateID), nil, nil, *gqlWebhookInput) 325 } 326 if testCase.RuntimeServiceFn != nil { 327 result, err = resolver.AddWebhook(context.TODO(), nil, nil, stringPtr(givenRuntimeID), nil, *gqlWebhookInput) 328 } 329 if testCase.FormationTemplateServiceFn != nil { 330 result, err = resolver.AddWebhook(context.TODO(), nil, nil, nil, stringPtr(givenFormationTemplateID), *gqlWebhookInput) 331 } 332 333 // THEN 334 assert.Equal(t, testCase.ExpectedWebhook, result) 335 if testCase.ExpectedErr == nil { 336 require.NoError(t, err) 337 } else { 338 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 339 } 340 341 svc.AssertExpectations(t) 342 if testCase.AppServiceFn != nil { 343 appSvc.AssertExpectations(t) 344 } 345 if testCase.AppTemplateServiceFn != nil { 346 appTemplateSvc.AssertExpectations(t) 347 } 348 if testCase.RuntimeServiceFn != nil { 349 runtimeSvc.AssertExpectations(t) 350 } 351 if testCase.FormationTemplateServiceFn != nil { 352 formationTemplateSvc.AssertExpectations(t) 353 } 354 converter.AssertExpectations(t) 355 persistTxMock.AssertExpectations(t) 356 transactionerMock.AssertExpectations(t) 357 }) 358 t.Run("Error when more than one of application, application_template, runtime, formation_template is specified", func(t *testing.T) { 359 persistTxMock := txtest.PersistenceContextThatDoesntExpectCommit() 360 transactionerMock := txtest.TransactionerThatSucceeds(persistTxMock) 361 362 resolver := webhook.NewResolver(transactionerMock, nil, nil, nil, nil, nil, nil) 363 _, err := resolver.AddWebhook(context.TODO(), stringPtr("app"), stringPtr("app_template"), stringPtr("runtime"), stringPtr("formation_template"), graphql.WebhookInput{}) 364 assert.Error(t, err) 365 assert.Contains(t, err.Error(), "exactly one of applicationID, applicationTemplateID, runtimeID or formationTemplateID should be specified") 366 }) 367 t.Run("Error when none of application, application_template, runtime, formation_template is specified", func(t *testing.T) { 368 persistTxMock := txtest.PersistenceContextThatDoesntExpectCommit() 369 transactionerMock := txtest.TransactionerThatSucceeds(persistTxMock) 370 371 resolver := webhook.NewResolver(transactionerMock, nil, nil, nil, nil, nil, nil) 372 _, err := resolver.AddWebhook(context.TODO(), nil, nil, nil, nil, graphql.WebhookInput{}) 373 assert.Error(t, err) 374 assert.Contains(t, err.Error(), "exactly one of applicationID, applicationTemplateID, runtimeID or formationTemplateID should be specified") 375 }) 376 } 377 } 378 379 func TestResolver_UpdateWebhook(t *testing.T) { 380 // GIVEN 381 testErr := errors.New("Test error") 382 383 applicationID := "foo" 384 givenWebhookID := "bar" 385 gqlWebhookInput := fixGQLWebhookInput("foo") 386 modelWebhookInput := fixModelWebhookInput("foo") 387 gqlWebhook := fixApplicationGQLWebhook(givenWebhookID, "", "") 388 modelWebhook := fixApplicationModelWebhook(givenWebhookID, applicationID, givenTenant(), "foo", time.Time{}) 389 390 testCases := []struct { 391 Name string 392 ServiceFn func() *automock.WebhookService 393 ConverterFn func() *automock.WebhookConverter 394 PersistenceFn func() *persistenceautomock.PersistenceTx 395 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 396 ExpectedWebhook *graphql.Webhook 397 ExpectedErr error 398 }{ 399 { 400 Name: "Success", 401 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 402 TransactionerFn: txtest.TransactionerThatSucceeds, 403 ServiceFn: func() *automock.WebhookService { 404 svc := &automock.WebhookService{} 405 svc.On("Update", txtest.CtxWithDBMatcher(), givenWebhookID, *modelWebhookInput, model.UnknownWebhookReference).Return(nil).Once() 406 svc.On("Get", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(modelWebhook, nil).Once() 407 return svc 408 }, 409 ConverterFn: func() *automock.WebhookConverter { 410 conv := &automock.WebhookConverter{} 411 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 412 conv.On("ToGraphQL", modelWebhook).Return(gqlWebhook, nil).Once() 413 return conv 414 }, 415 ExpectedWebhook: gqlWebhook, 416 ExpectedErr: nil, 417 }, 418 { 419 Name: "Returns error on starting transaction", 420 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 421 TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner { 422 transact := &persistenceautomock.Transactioner{} 423 transact.On("Begin").Return(persistTx, givenError()).Once() 424 return transact 425 }, 426 ServiceFn: func() *automock.WebhookService { 427 return &automock.WebhookService{} 428 }, 429 ConverterFn: func() *automock.WebhookConverter { 430 return &automock.WebhookConverter{} 431 }, 432 ExpectedErr: givenError(), 433 }, 434 { 435 Name: "Returns error on committing transaction", 436 PersistenceFn: func() *persistenceautomock.PersistenceTx { 437 persistTx := &persistenceautomock.PersistenceTx{} 438 persistTx.On("Commit").Return(givenError()).Once() 439 return persistTx 440 }, 441 TransactionerFn: txtest.TransactionerThatSucceeds, 442 ServiceFn: func() *automock.WebhookService { 443 svc := &automock.WebhookService{} 444 svc.On("Update", txtest.CtxWithDBMatcher(), givenWebhookID, *modelWebhookInput, model.UnknownWebhookReference).Return(nil).Once() 445 svc.On("Get", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(modelWebhook, nil).Once() 446 return svc 447 }, 448 ConverterFn: func() *automock.WebhookConverter { 449 conv := &automock.WebhookConverter{} 450 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 451 return conv 452 }, 453 ExpectedErr: givenError(), 454 }, 455 { 456 Name: "Returns error when webhook conversion failed", 457 TransactionerFn: txtest.TransactionerThatSucceeds, 458 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 459 ServiceFn: func() *automock.WebhookService { 460 return &automock.WebhookService{} 461 }, 462 ConverterFn: func() *automock.WebhookConverter { 463 conv := &automock.WebhookConverter{} 464 conv.On("InputFromGraphQL", gqlWebhookInput).Return(nil, testErr).Once() 465 return conv 466 }, 467 ExpectedWebhook: nil, 468 ExpectedErr: errors.New("while converting the WebhookInput"), 469 }, 470 { 471 Name: "Returns error when webhook update failed", 472 TransactionerFn: txtest.TransactionerThatSucceeds, 473 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 474 ServiceFn: func() *automock.WebhookService { 475 svc := &automock.WebhookService{} 476 svc.On("Update", txtest.CtxWithDBMatcher(), givenWebhookID, *modelWebhookInput, model.UnknownWebhookReference).Return(testErr).Once() 477 return svc 478 }, 479 ConverterFn: func() *automock.WebhookConverter { 480 conv := &automock.WebhookConverter{} 481 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 482 return conv 483 }, 484 ExpectedWebhook: nil, 485 ExpectedErr: testErr, 486 }, 487 { 488 Name: "Returns error when webhook retrieval failed", 489 TransactionerFn: txtest.TransactionerThatSucceeds, 490 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 491 ServiceFn: func() *automock.WebhookService { 492 svc := &automock.WebhookService{} 493 svc.On("Update", txtest.CtxWithDBMatcher(), givenWebhookID, *modelWebhookInput, model.UnknownWebhookReference).Return(nil).Once() 494 svc.On("Get", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(nil, testErr).Once() 495 return svc 496 }, 497 ConverterFn: func() *automock.WebhookConverter { 498 conv := &automock.WebhookConverter{} 499 conv.On("InputFromGraphQL", gqlWebhookInput).Return(modelWebhookInput, nil).Once() 500 return conv 501 }, 502 ExpectedWebhook: nil, 503 ExpectedErr: testErr, 504 }, 505 } 506 507 for _, testCase := range testCases { 508 t.Run(testCase.Name, func(t *testing.T) { 509 svc := testCase.ServiceFn() 510 converter := testCase.ConverterFn() 511 512 persistTxMock := testCase.PersistenceFn() 513 transactionerMock := testCase.TransactionerFn(persistTxMock) 514 515 resolver := webhook.NewResolver(transactionerMock, svc, nil, nil, nil, nil, converter) 516 517 // WHEN 518 result, err := resolver.UpdateWebhook(context.TODO(), givenWebhookID, *gqlWebhookInput) 519 520 // THEN 521 assert.Equal(t, testCase.ExpectedWebhook, result) 522 if testCase.ExpectedErr != nil { 523 assert.Error(t, err) 524 assert.Contains(t, err.Error(), testCase.ExpectedErr.Error()) 525 } 526 svc.AssertExpectations(t) 527 converter.AssertExpectations(t) 528 transactionerMock.AssertExpectations(t) 529 }) 530 } 531 } 532 533 func TestResolver_DeleteWebhook(t *testing.T) { 534 // GIVEN 535 testErr := errors.New("Test error") 536 537 applicationID := "foo" 538 givenWebhookID := "bar" 539 540 gqlWebhook := fixApplicationGQLWebhook(givenWebhookID, "", "") 541 modelWebhook := fixApplicationModelWebhook(givenWebhookID, applicationID, givenTenant(), "foo", time.Time{}) 542 543 testCases := []struct { 544 Name string 545 ServiceFn func() *automock.WebhookService 546 ConverterFn func() *automock.WebhookConverter 547 PersistenceFn func() *persistenceautomock.PersistenceTx 548 TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner 549 ExpectedWebhook *graphql.Webhook 550 ExpectedErr error 551 }{ 552 { 553 Name: "Success", 554 TransactionerFn: txtest.TransactionerThatSucceeds, 555 PersistenceFn: txtest.PersistenceContextThatExpectsCommit, 556 ServiceFn: func() *automock.WebhookService { 557 svc := &automock.WebhookService{} 558 svc.On("Get", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(modelWebhook, nil).Once() 559 svc.On("Delete", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(nil).Once() 560 return svc 561 }, 562 ConverterFn: func() *automock.WebhookConverter { 563 conv := &automock.WebhookConverter{} 564 conv.On("ToGraphQL", modelWebhook).Return(gqlWebhook, nil).Once() 565 return conv 566 }, 567 ExpectedWebhook: gqlWebhook, 568 ExpectedErr: nil, 569 }, 570 { 571 Name: "Returns error on starting transaction", 572 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 573 TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner { 574 transact := &persistenceautomock.Transactioner{} 575 transact.On("Begin").Return(persistTx, givenError()).Once() 576 return transact 577 }, 578 ServiceFn: func() *automock.WebhookService { 579 return &automock.WebhookService{} 580 }, 581 582 ConverterFn: func() *automock.WebhookConverter { 583 return &automock.WebhookConverter{} 584 }, 585 ExpectedErr: givenError(), 586 }, 587 { 588 Name: "Returns error on committing transaction", 589 PersistenceFn: func() *persistenceautomock.PersistenceTx { 590 persistTx := &persistenceautomock.PersistenceTx{} 591 persistTx.On("Commit").Return(givenError()).Once() 592 return persistTx 593 }, 594 TransactionerFn: txtest.TransactionerThatSucceeds, 595 ServiceFn: func() *automock.WebhookService { 596 svc := &automock.WebhookService{} 597 svc.On("Get", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(modelWebhook, nil).Once() 598 svc.On("Delete", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(nil).Once() 599 return svc 600 }, 601 ConverterFn: func() *automock.WebhookConverter { 602 conv := &automock.WebhookConverter{} 603 conv.On("ToGraphQL", modelWebhook).Return(gqlWebhook, nil).Once() 604 return conv 605 }, 606 ExpectedErr: givenError(), 607 }, 608 { 609 Name: "Returns error when webhook retrieval failed", 610 TransactionerFn: txtest.TransactionerThatSucceeds, 611 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 612 ServiceFn: func() *automock.WebhookService { 613 svc := &automock.WebhookService{} 614 svc.On("Get", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(nil, testErr).Once() 615 return svc 616 }, 617 ConverterFn: func() *automock.WebhookConverter { 618 conv := &automock.WebhookConverter{} 619 return conv 620 }, 621 ExpectedWebhook: nil, 622 ExpectedErr: testErr, 623 }, 624 { 625 Name: "Returns error when webhook deletion failed", 626 TransactionerFn: txtest.TransactionerThatSucceeds, 627 PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit, 628 ServiceFn: func() *automock.WebhookService { 629 svc := &automock.WebhookService{} 630 svc.On("Get", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(modelWebhook, nil).Once() 631 svc.On("Delete", txtest.CtxWithDBMatcher(), givenWebhookID, model.UnknownWebhookReference).Return(testErr).Once() 632 return svc 633 }, 634 ConverterFn: func() *automock.WebhookConverter { 635 conv := &automock.WebhookConverter{} 636 conv.On("ToGraphQL", modelWebhook).Return(gqlWebhook, nil).Once() 637 return conv 638 }, 639 ExpectedWebhook: nil, 640 ExpectedErr: testErr, 641 }, 642 } 643 644 for _, testCase := range testCases { 645 t.Run(testCase.Name, func(t *testing.T) { 646 svc := testCase.ServiceFn() 647 converter := testCase.ConverterFn() 648 649 persistTxMock := testCase.PersistenceFn() 650 transactionerMock := testCase.TransactionerFn(persistTxMock) 651 652 resolver := webhook.NewResolver(transactionerMock, svc, nil, nil, nil, nil, converter) 653 654 // WHEN 655 result, err := resolver.DeleteWebhook(context.TODO(), givenWebhookID) 656 657 // THEN 658 assert.Equal(t, testCase.ExpectedWebhook, result) 659 assert.Equal(t, testCase.ExpectedErr, err) 660 661 svc.AssertExpectations(t) 662 converter.AssertExpectations(t) 663 transactionerMock.AssertExpectations(t) 664 }) 665 } 666 }