github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/formation/notificationbuilder_test.go (about) 1 package formation_test 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/kyma-incubator/compass/components/director/internal/domain/formation" 8 "github.com/kyma-incubator/compass/components/director/internal/domain/formation/automock" 9 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 10 "github.com/kyma-incubator/compass/components/director/internal/model" 11 "github.com/kyma-incubator/compass/components/director/pkg/formationconstraint" 12 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 13 webhookdir "github.com/kyma-incubator/compass/components/director/pkg/webhook" 14 webhookclient "github.com/kyma-incubator/compass/components/director/pkg/webhook_client" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/mock" 17 "github.com/stretchr/testify/require" 18 ) 19 20 func TestBuildFormationAssignmentNotificationRequest(t *testing.T) { 21 ctx := context.TODO() 22 ctx = tenant.SaveToContext(ctx, TntInternalID, TntExternalID) 23 24 ApplicationID := "04f3568d-3e0c-4f6b-b646-e6979e9d060c" 25 webhook := fixConfigurationChangedWebhookModel(WebhookID, ApplicationID, model.ApplicationWebhookReference) 26 gqlWebhook := &graphql.Webhook{ID: WebhookID, ApplicationID: &ApplicationID, Type: graphql.WebhookTypeConfigurationChanged} 27 28 applicationTenantMappingWebhook := fixApplicationTenantMappingWebhookModel(AppTenantMappingWebhookIDForApp1, ApplicationID) 29 gqlApplicationTenantMappingWebhook := &graphql.Webhook{ID: AppTenantMappingWebhookIDForApp1, ApplicationID: &ApplicationID, Type: graphql.WebhookTypeApplicationTenantMapping} 30 31 testCases := []struct { 32 Name string 33 WebhookConverter func() *automock.WebhookConverter 34 ConstraintEngineFn func() *automock.ConstraintEngine 35 Details *formationconstraint.GenerateFormationAssignmentNotificationOperationDetails 36 Webhook *model.Webhook 37 ExpectedNotification *webhookclient.FormationAssignmentNotificationRequest 38 ExpectedErrMessage string 39 }{ 40 { 41 Name: "success for configuration changed webhook", 42 WebhookConverter: func() *automock.WebhookConverter { 43 conv := &automock.WebhookConverter{} 44 conv.On("ToGraphQL", webhook).Return(gqlWebhook, nil).Once() 45 return conv 46 }, 47 ConstraintEngineFn: func() *automock.ConstraintEngine { 48 engine := &automock.ConstraintEngine{} 49 engine.On("EnforceConstraints", ctx, preGenerateFormationAssignmentNotificationLocation, generateConfigurationChangeNotificationDetails, FormationTemplateID).Return(nil).Once() 50 engine.On("EnforceConstraints", ctx, postGenerateFormationAssignmentNotificationLocation, generateConfigurationChangeNotificationDetails, FormationTemplateID).Return(nil).Once() 51 return engine 52 }, 53 Details: generateConfigurationChangeNotificationDetails, 54 Webhook: webhook, 55 ExpectedNotification: applicationNotificationWithAppTemplate, 56 ExpectedErrMessage: "", 57 }, 58 { 59 Name: "success for application tenant mapping webhook", 60 WebhookConverter: func() *automock.WebhookConverter { 61 conv := &automock.WebhookConverter{} 62 conv.On("ToGraphQL", applicationTenantMappingWebhook).Return(gqlApplicationTenantMappingWebhook, nil).Once() 63 return conv 64 }, 65 ConstraintEngineFn: func() *automock.ConstraintEngine { 66 engine := &automock.ConstraintEngine{} 67 engine.On("EnforceConstraints", ctx, preGenerateFormationAssignmentNotificationLocation, generateAppToAppNotificationDetails, FormationTemplateID).Return(nil).Once() 68 engine.On("EnforceConstraints", ctx, postGenerateFormationAssignmentNotificationLocation, generateAppToAppNotificationDetails, FormationTemplateID).Return(nil).Once() 69 return engine 70 }, 71 Details: generateAppToAppNotificationDetails, 72 Webhook: applicationTenantMappingWebhook, 73 ExpectedNotification: appToAppNotificationWithoutSourceTemplateWithTargetTemplate, 74 ExpectedErrMessage: "", 75 }, 76 { 77 Name: "error while enforcing constraints pre operation", 78 ConstraintEngineFn: func() *automock.ConstraintEngine { 79 engine := &automock.ConstraintEngine{} 80 engine.On("EnforceConstraints", ctx, preGenerateFormationAssignmentNotificationLocation, generateConfigurationChangeNotificationDetails, FormationTemplateID).Return(testErr).Once() 81 return engine 82 }, 83 Details: generateConfigurationChangeNotificationDetails, 84 Webhook: webhook, 85 }, 86 { 87 Name: "error when webhook type is not supported", 88 ConstraintEngineFn: func() *automock.ConstraintEngine { 89 engine := &automock.ConstraintEngine{} 90 engine.On("EnforceConstraints", ctx, preGenerateFormationAssignmentNotificationLocation, generateConfigurationChangeNotificationDetails, FormationTemplateID).Return(nil).Once() 91 return engine 92 }, 93 Details: generateConfigurationChangeNotificationDetails, 94 Webhook: &model.Webhook{Type: model.WebhookTypeRegisterApplication}, 95 ExpectedErrMessage: "Unsupported Webhook Type", 96 }, 97 { 98 Name: "error while converting webhook", 99 WebhookConverter: func() *automock.WebhookConverter { 100 conv := &automock.WebhookConverter{} 101 conv.On("ToGraphQL", webhook).Return(nil, testErr).Once() 102 return conv 103 }, 104 ConstraintEngineFn: func() *automock.ConstraintEngine { 105 engine := &automock.ConstraintEngine{} 106 engine.On("EnforceConstraints", ctx, preGenerateFormationAssignmentNotificationLocation, generateConfigurationChangeNotificationDetails, FormationTemplateID).Return(nil).Once() 107 return engine 108 }, 109 Details: generateConfigurationChangeNotificationDetails, 110 Webhook: webhook, 111 ExpectedErrMessage: "while converting webhook with ID", 112 }, 113 { 114 Name: "error while enforcing constraints post operation", 115 WebhookConverter: func() *automock.WebhookConverter { 116 conv := &automock.WebhookConverter{} 117 conv.On("ToGraphQL", webhook).Return(gqlWebhook, nil).Once() 118 return conv 119 }, 120 ConstraintEngineFn: func() *automock.ConstraintEngine { 121 engine := &automock.ConstraintEngine{} 122 engine.On("EnforceConstraints", ctx, preGenerateFormationAssignmentNotificationLocation, generateConfigurationChangeNotificationDetails, FormationTemplateID).Return(nil).Once() 123 engine.On("EnforceConstraints", ctx, postGenerateFormationAssignmentNotificationLocation, generateConfigurationChangeNotificationDetails, FormationTemplateID).Return(testErr).Once() 124 return engine 125 }, 126 Details: generateConfigurationChangeNotificationDetails, 127 Webhook: webhook, 128 }, 129 } 130 131 for _, testCase := range testCases { 132 t.Run(testCase.Name, func(t *testing.T) { 133 // GIVEN 134 webhookConverter := unusedWebhookConverter() 135 if testCase.WebhookConverter != nil { 136 webhookConverter = testCase.WebhookConverter() 137 } 138 constraintEngine := unusedConstraintEngine() 139 if testCase.ConstraintEngineFn != nil { 140 constraintEngine = testCase.ConstraintEngineFn() 141 } 142 143 builder := formation.NewNotificationsBuilder(webhookConverter, constraintEngine, runtimeType, applicationType) 144 145 // WHEN 146 actual, err := builder.BuildFormationAssignmentNotificationRequest(ctx, FormationTemplateID, testCase.Details, testCase.Webhook) 147 148 // THEN 149 if testCase.ExpectedErrMessage == "" { 150 require.NoError(t, err) 151 assert.Equal(t, testCase.ExpectedNotification, actual) 152 } else { 153 require.Error(t, err) 154 require.Contains(t, err.Error(), testCase.ExpectedErrMessage) 155 require.Nil(t, actual) 156 } 157 158 mock.AssertExpectationsForObjects(t, webhookConverter, constraintEngine) 159 }) 160 } 161 } 162 163 func TestBuildFormationNotificationRequests(t *testing.T) { 164 ctx := context.Background() 165 formationLifecycleGQLWebhook := fixFormationLifecycleWebhookGQLModel(FormationLifecycleWebhookID, FormationTemplateID, graphql.WebhookModeSync) 166 formationInput := fixFormationModelWithoutError() 167 168 testCases := []struct { 169 name string 170 constraintEngineFn func() *automock.ConstraintEngine 171 webhookConverterFn func() *automock.WebhookConverter 172 formationTemplateWebhooks []*model.Webhook 173 expectedErrMsg string 174 expectedFormationNotificationReqs []*webhookclient.FormationNotificationRequest 175 }{ 176 { 177 name: "Successfully build formation notification requests", 178 constraintEngineFn: func() *automock.ConstraintEngine { 179 engine := &automock.ConstraintEngine{} 180 engine.On("EnforceConstraints", ctx, preGenerateFormationNotificationLocation, formationNotificationDetails, FormationTemplateID).Return(nil).Once() 181 engine.On("EnforceConstraints", ctx, postGenerateFormationNotificationLocation, formationNotificationDetails, FormationTemplateID).Return(nil).Once() 182 return engine 183 }, 184 webhookConverterFn: func() *automock.WebhookConverter { 185 webhookConv := &automock.WebhookConverter{} 186 webhookConv.On("ToGraphQL", formationLifecycleSyncWebhook).Return(&formationLifecycleGQLWebhook, nil).Once() 187 return webhookConv 188 }, 189 formationTemplateWebhooks: formationLifecycleSyncWebhooks, 190 expectedFormationNotificationReqs: formationNotificationSyncCreateRequests, 191 }, 192 { 193 name: "Error when enforcing pre generate formation notification constraints", 194 constraintEngineFn: func() *automock.ConstraintEngine { 195 engine := &automock.ConstraintEngine{} 196 engine.On("EnforceConstraints", ctx, preGenerateFormationNotificationLocation, formationNotificationDetails, FormationTemplateID).Return(testErr).Once() 197 return engine 198 }, 199 formationTemplateWebhooks: formationLifecycleSyncWebhooks, 200 expectedErrMsg: testErr.Error(), 201 }, 202 { 203 name: "Success when there are no formation template webhooks", 204 constraintEngineFn: func() *automock.ConstraintEngine { 205 engine := &automock.ConstraintEngine{} 206 engine.On("EnforceConstraints", ctx, preGenerateFormationNotificationLocation, formationNotificationDetails, FormationTemplateID).Return(nil).Once() 207 return engine 208 }, 209 formationTemplateWebhooks: emptyFormationLifecycleWebhooks, 210 }, 211 { 212 name: "Error when converting formation template webhook to graphql one", 213 constraintEngineFn: func() *automock.ConstraintEngine { 214 engine := &automock.ConstraintEngine{} 215 engine.On("EnforceConstraints", ctx, preGenerateFormationNotificationLocation, formationNotificationDetails, FormationTemplateID).Return(nil).Once() 216 return engine 217 }, 218 webhookConverterFn: func() *automock.WebhookConverter { 219 webhookConv := &automock.WebhookConverter{} 220 webhookConv.On("ToGraphQL", formationLifecycleSyncWebhook).Return(nil, testErr).Once() 221 return webhookConv 222 }, 223 formationTemplateWebhooks: formationLifecycleSyncWebhooks, 224 expectedErrMsg: testErr.Error(), 225 }, 226 { 227 name: "Error when enforcing post generate formation notification constraints", 228 constraintEngineFn: func() *automock.ConstraintEngine { 229 engine := &automock.ConstraintEngine{} 230 engine.On("EnforceConstraints", ctx, preGenerateFormationNotificationLocation, formationNotificationDetails, FormationTemplateID).Return(nil).Once() 231 engine.On("EnforceConstraints", ctx, postGenerateFormationNotificationLocation, formationNotificationDetails, FormationTemplateID).Return(testErr).Once() 232 return engine 233 }, 234 webhookConverterFn: func() *automock.WebhookConverter { 235 webhookConv := &automock.WebhookConverter{} 236 webhookConv.On("ToGraphQL", formationLifecycleSyncWebhook).Return(&formationLifecycleGQLWebhook, nil).Once() 237 return webhookConv 238 }, 239 formationTemplateWebhooks: formationLifecycleSyncWebhooks, 240 expectedErrMsg: testErr.Error(), 241 }, 242 } 243 244 for _, testCase := range testCases { 245 t.Run(testCase.name, func(t *testing.T) { 246 constraintEngine := unusedConstraintEngine() 247 if testCase.constraintEngineFn != nil { 248 constraintEngine = testCase.constraintEngineFn() 249 } 250 251 webhookConv := unusedWebhookConverter() 252 if testCase.webhookConverterFn != nil { 253 webhookConv = testCase.webhookConverterFn() 254 } 255 256 defer mock.AssertExpectationsForObjects(t, constraintEngine, webhookConv) 257 258 builder := formation.NewNotificationsBuilder(webhookConv, constraintEngine, runtimeType, applicationType) 259 formationNotificationReqs, err := builder.BuildFormationNotificationRequests(ctx, formationNotificationDetails, formationInput, testCase.formationTemplateWebhooks) 260 261 if testCase.expectedErrMsg != "" { 262 require.Error(t, err) 263 require.Contains(t, err.Error(), testCase.expectedErrMsg) 264 require.Empty(t, formationNotificationReqs) 265 } else { 266 require.NoError(t, err) 267 require.ElementsMatch(t, formationNotificationReqs, testCase.expectedFormationNotificationReqs) 268 } 269 }) 270 } 271 } 272 273 func TestNotificationBuilder_PrepareDetailsForConfigurationChangeNotificationGeneration(t *testing.T) { 274 applicationTemplate := &webhookdir.ApplicationTemplateWithLabels{ 275 ApplicationTemplate: fixApplicationTemplateModel(), 276 Labels: fixApplicationTemplateLabelsMap(), 277 } 278 279 application := &webhookdir.ApplicationWithLabels{ 280 Application: fixApplicationModel(ApplicationID), 281 Labels: map[string]string{ 282 applicationType: applicationType, 283 }, 284 } 285 286 runtime := &webhookdir.RuntimeWithLabels{ 287 Runtime: fixRuntimeModel(RuntimeContextRuntimeID), 288 Labels: map[string]string{ 289 runtimeType: runtimeType, 290 }, 291 } 292 293 applicationWithoutType := &webhookdir.ApplicationWithLabels{ 294 Application: fixApplicationModel(ApplicationID), 295 Labels: map[string]string{}, 296 } 297 298 runtimeWithoutType := &webhookdir.RuntimeWithLabels{ 299 Runtime: fixRuntimeModel(RuntimeContextRuntimeID), 300 Labels: map[string]string{}, 301 } 302 303 runtimeContext := &webhookdir.RuntimeContextWithLabels{ 304 RuntimeContext: fixRuntimeContextModel(), 305 Labels: fixRuntimeContextLabelsMap(), 306 } 307 308 testCases := []struct { 309 Name string 310 Operation model.FormationOperation 311 FormationID string 312 ApplicationTemplate *webhookdir.ApplicationTemplateWithLabels 313 Application *webhookdir.ApplicationWithLabels 314 Runtime *webhookdir.RuntimeWithLabels 315 RuntimeContext *webhookdir.RuntimeContextWithLabels 316 Assignment *webhookdir.FormationAssignment 317 ReverseAssignment *webhookdir.FormationAssignment 318 TargetType model.ResourceType 319 ExpectedNotificationDetails *formationconstraint.GenerateFormationAssignmentNotificationOperationDetails 320 ExpectedErrMessage string 321 }{ 322 { 323 Name: "success resource type application", 324 Operation: model.AssignFormation, 325 FormationID: fixUUID(), 326 ApplicationTemplate: applicationTemplate, 327 Application: application, 328 Runtime: runtime, 329 RuntimeContext: runtimeContext, 330 Assignment: emptyFormationAssignment, 331 ReverseAssignment: emptyFormationAssignment, 332 TargetType: model.ApplicationResourceType, 333 ExpectedNotificationDetails: &formationconstraint.GenerateFormationAssignmentNotificationOperationDetails{ 334 Operation: model.AssignFormation, 335 FormationID: fixUUID(), 336 FormationTemplateID: FormationTemplateID, 337 ResourceType: model.ApplicationResourceType, 338 ResourceSubtype: applicationType, 339 ResourceID: ApplicationID, 340 ApplicationTemplate: applicationTemplate, 341 Application: application, 342 Runtime: runtime, 343 RuntimeContext: runtimeContext, 344 Assignment: emptyFormationAssignment, 345 ReverseAssignment: emptyFormationAssignment, 346 TenantID: tenantID.String(), 347 }, 348 ExpectedErrMessage: "", 349 }, 350 { 351 Name: "success resource type runtime", 352 Operation: model.AssignFormation, 353 FormationID: fixUUID(), 354 ApplicationTemplate: applicationTemplate, 355 Application: application, 356 Runtime: runtime, 357 RuntimeContext: runtimeContext, 358 Assignment: emptyFormationAssignment, 359 ReverseAssignment: emptyFormationAssignment, 360 TargetType: model.RuntimeResourceType, 361 ExpectedNotificationDetails: &formationconstraint.GenerateFormationAssignmentNotificationOperationDetails{ 362 Operation: model.AssignFormation, 363 FormationID: fixUUID(), 364 FormationTemplateID: FormationTemplateID, 365 ResourceType: model.RuntimeResourceType, 366 ResourceSubtype: runtimeType, 367 ResourceID: RuntimeContextRuntimeID, 368 ApplicationTemplate: applicationTemplate, 369 Application: application, 370 Runtime: runtime, 371 RuntimeContext: runtimeContext, 372 Assignment: emptyFormationAssignment, 373 ReverseAssignment: emptyFormationAssignment, 374 TenantID: tenantID.String(), 375 }, 376 ExpectedErrMessage: "", 377 }, 378 { 379 Name: "success resource type runtime context", 380 Operation: model.AssignFormation, 381 FormationID: fixUUID(), 382 ApplicationTemplate: applicationTemplate, 383 Application: application, 384 Runtime: runtime, 385 RuntimeContext: runtimeContext, 386 Assignment: emptyFormationAssignment, 387 ReverseAssignment: emptyFormationAssignment, 388 TargetType: model.RuntimeContextResourceType, 389 ExpectedNotificationDetails: &formationconstraint.GenerateFormationAssignmentNotificationOperationDetails{ 390 Operation: model.AssignFormation, 391 FormationID: fixUUID(), 392 FormationTemplateID: FormationTemplateID, 393 ResourceType: model.RuntimeContextResourceType, 394 ResourceSubtype: runtimeType, 395 ResourceID: RuntimeContextID, 396 ApplicationTemplate: applicationTemplate, 397 Application: application, 398 Runtime: runtime, 399 RuntimeContext: runtimeContext, 400 Assignment: emptyFormationAssignment, 401 ReverseAssignment: emptyFormationAssignment, 402 TenantID: tenantID.String(), 403 }, 404 ExpectedErrMessage: "", 405 }, 406 { 407 Name: "fail to determine application type", 408 Operation: model.AssignFormation, 409 FormationID: fixUUID(), 410 ApplicationTemplate: applicationTemplate, 411 Application: applicationWithoutType, 412 Runtime: runtime, 413 RuntimeContext: runtimeContext, 414 Assignment: emptyFormationAssignment, 415 ReverseAssignment: emptyFormationAssignment, 416 TargetType: model.ApplicationResourceType, 417 ExpectedErrMessage: "While determining subtype for application with ID", 418 }, 419 { 420 Name: "fail to determine runtime type", 421 Operation: model.AssignFormation, 422 FormationID: fixUUID(), 423 ApplicationTemplate: applicationTemplate, 424 Application: application, 425 Runtime: runtimeWithoutType, 426 RuntimeContext: runtimeContext, 427 Assignment: emptyFormationAssignment, 428 ReverseAssignment: emptyFormationAssignment, 429 TargetType: model.RuntimeResourceType, 430 ExpectedErrMessage: "While determining subtype for runtime with ID", 431 }, 432 { 433 Name: "fail to determine runtime context type", 434 Operation: model.AssignFormation, 435 FormationID: fixUUID(), 436 ApplicationTemplate: applicationTemplate, 437 Application: application, 438 Runtime: runtimeWithoutType, 439 RuntimeContext: runtimeContext, 440 Assignment: emptyFormationAssignment, 441 ReverseAssignment: emptyFormationAssignment, 442 TargetType: model.RuntimeContextResourceType, 443 ExpectedErrMessage: "While determining subtype for runtime context with ID", 444 }, 445 { 446 Name: "unsupported resource type", 447 Operation: model.AssignFormation, 448 FormationID: fixUUID(), 449 ApplicationTemplate: applicationTemplate, 450 Application: application, 451 Runtime: runtimeWithoutType, 452 RuntimeContext: runtimeContext, 453 Assignment: emptyFormationAssignment, 454 ReverseAssignment: emptyFormationAssignment, 455 TargetType: model.FormationResourceType, 456 ExpectedErrMessage: "Unsuported target resource subtype \"FORMATION\"", 457 }, 458 } 459 460 for _, testCase := range testCases { 461 t.Run(testCase.Name, func(t *testing.T) { 462 // GIVEN 463 builder := formation.NewNotificationsBuilder(nil, nil, runtimeType, applicationType) 464 465 // WHEN 466 actual, err := builder.PrepareDetailsForConfigurationChangeNotificationGeneration(testCase.Operation, testCase.FormationID, FormationTemplateID, testCase.ApplicationTemplate, testCase.Application, testCase.Runtime, testCase.RuntimeContext, testCase.Assignment, testCase.ReverseAssignment, testCase.TargetType, nil, tenantID.String()) 467 468 // THEN 469 if testCase.ExpectedErrMessage == "" { 470 require.NoError(t, err) 471 assert.Equal(t, testCase.ExpectedNotificationDetails, actual) 472 } else { 473 require.Error(t, err) 474 require.Contains(t, err.Error(), testCase.ExpectedErrMessage) 475 require.Nil(t, actual) 476 } 477 }) 478 } 479 } 480 481 func TestNotificationBuilder_PrepareDetailsForApplicationTenantMappingNotificationGeneration(t *testing.T) { 482 applicationTemplate := &webhookdir.ApplicationTemplateWithLabels{ 483 ApplicationTemplate: fixApplicationTemplateModel(), 484 Labels: fixApplicationTemplateLabelsMap(), 485 } 486 487 application := &webhookdir.ApplicationWithLabels{ 488 Application: fixApplicationModel(ApplicationID), 489 Labels: map[string]string{ 490 applicationType: applicationType, 491 }, 492 } 493 494 applicationWithoutType := &webhookdir.ApplicationWithLabels{ 495 Application: fixApplicationModel(ApplicationID), 496 Labels: map[string]string{}, 497 } 498 499 testCases := []struct { 500 Name string 501 Operation model.FormationOperation 502 FormationID string 503 SourceApplicationTemplate *webhookdir.ApplicationTemplateWithLabels 504 SourceApplication *webhookdir.ApplicationWithLabels 505 TargetApplicationTemplate *webhookdir.ApplicationTemplateWithLabels 506 TargetApplication *webhookdir.ApplicationWithLabels 507 Assignment *webhookdir.FormationAssignment 508 ReverseAssignment *webhookdir.FormationAssignment 509 TargetType model.ResourceType 510 ExpectedNotificationDetails *formationconstraint.GenerateFormationAssignmentNotificationOperationDetails 511 ExpectedErrMessage string 512 }{ 513 { 514 Name: "success resource type application", 515 Operation: model.AssignFormation, 516 FormationID: fixUUID(), 517 SourceApplicationTemplate: applicationTemplate, 518 SourceApplication: application, 519 TargetApplicationTemplate: applicationTemplate, 520 TargetApplication: application, 521 Assignment: emptyFormationAssignment, 522 ReverseAssignment: emptyFormationAssignment, 523 TargetType: model.ApplicationResourceType, 524 ExpectedNotificationDetails: &formationconstraint.GenerateFormationAssignmentNotificationOperationDetails{ 525 Operation: model.AssignFormation, 526 FormationID: fixUUID(), 527 FormationTemplateID: FormationTemplateID, 528 ResourceType: model.ApplicationResourceType, 529 ResourceSubtype: applicationType, 530 ResourceID: ApplicationID, 531 SourceApplicationTemplate: applicationTemplate, 532 SourceApplication: application, 533 TargetApplicationTemplate: applicationTemplate, 534 TargetApplication: application, 535 Assignment: emptyFormationAssignment, 536 ReverseAssignment: emptyFormationAssignment, 537 TenantID: tenantID.String(), 538 }, 539 ExpectedErrMessage: "", 540 }, 541 { 542 Name: "fail to determine target application type", 543 Operation: model.AssignFormation, 544 FormationID: fixUUID(), 545 SourceApplicationTemplate: applicationTemplate, 546 SourceApplication: application, 547 TargetApplicationTemplate: applicationTemplate, 548 TargetApplication: applicationWithoutType, 549 Assignment: emptyFormationAssignment, 550 ReverseAssignment: emptyFormationAssignment, 551 TargetType: model.ApplicationResourceType, 552 ExpectedErrMessage: "While determining subtype for application with", 553 }, 554 } 555 556 for _, testCase := range testCases { 557 t.Run(testCase.Name, func(t *testing.T) { 558 // GIVEN 559 builder := formation.NewNotificationsBuilder(nil, nil, runtimeType, applicationType) 560 561 // WHEN 562 actual, err := builder.PrepareDetailsForApplicationTenantMappingNotificationGeneration(testCase.Operation, testCase.FormationID, FormationTemplateID, testCase.SourceApplicationTemplate, testCase.SourceApplication, testCase.TargetApplicationTemplate, testCase.TargetApplication, testCase.Assignment, testCase.ReverseAssignment, nil, tenantID.String()) 563 564 // THEN 565 if testCase.ExpectedErrMessage == "" { 566 require.NoError(t, err) 567 assert.Equal(t, testCase.ExpectedNotificationDetails, actual) 568 } else { 569 require.Error(t, err) 570 require.Contains(t, err.Error(), testCase.ExpectedErrMessage) 571 require.Nil(t, actual) 572 } 573 }) 574 } 575 }