github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/formationassignment/notifications_test.go (about) 1 package formationassignment_test 2 3 import ( 4 "context" 5 "fmt" 6 "testing" 7 8 "github.com/kyma-incubator/compass/components/director/pkg/formationconstraint" 9 10 "github.com/kyma-incubator/compass/components/director/pkg/str" 11 12 databuilderautomock "github.com/kyma-incubator/compass/components/director/internal/domain/webhook/datainputbuilder/automock" 13 14 "github.com/kyma-incubator/compass/components/director/internal/domain/formationassignment" 15 "github.com/kyma-incubator/compass/components/director/internal/domain/formationassignment/automock" 16 "github.com/kyma-incubator/compass/components/director/internal/model" 17 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 18 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 19 "github.com/kyma-incubator/compass/components/director/pkg/resource" 20 tnt "github.com/kyma-incubator/compass/components/director/pkg/tenant" 21 "github.com/kyma-incubator/compass/components/director/pkg/webhook" 22 webhookclient "github.com/kyma-incubator/compass/components/director/pkg/webhook_client" 23 "github.com/stretchr/testify/mock" 24 "github.com/stretchr/testify/require" 25 ) 26 27 var ( 28 testRuntimeID = "testRuntimeID" 29 testAppTemplateID = "testAppTemplateID" 30 31 testAppWebhook = &model.Webhook{ 32 ID: "TestAppWebhookID", 33 ObjectID: TestSource, 34 ObjectType: model.ApplicationWebhookReference, 35 } 36 37 testRuntimeWebhook = &model.Webhook{ 38 ID: "TestRuntimeWebhookID", 39 ObjectID: TestSource, 40 ObjectType: model.RuntimeWebhookReference, 41 } 42 43 testRuntimeWithLabels = &webhook.RuntimeWithLabels{ 44 Runtime: &model.Runtime{ 45 Name: "testRuntimeName", 46 }, 47 Labels: testLabels, 48 } 49 testRuntimeCtxWithLabels = &webhook.RuntimeContextWithLabels{ 50 RuntimeContext: &model.RuntimeContext{ 51 ID: "testRuntimeCtxID", 52 RuntimeID: testRuntimeID, 53 Key: "testKey", 54 Value: "testValue", 55 }, 56 Labels: testLabels, 57 } 58 59 testLabels = map[string]string{"testLabelKey": "testLabelValue"} 60 testAppWithLabels = &webhook.ApplicationWithLabels{ 61 Application: &model.Application{ 62 Name: "testAppName", 63 ApplicationTemplateID: str.Ptr(testAppTemplateID), 64 }, 65 Labels: testLabels, 66 } 67 testAppTemplateWithLabels = &webhook.ApplicationTemplateWithLabels{ 68 ApplicationTemplate: &model.ApplicationTemplate{ 69 ID: testAppTemplateID, 70 Name: "testAppTemplateName", 71 }, 72 Labels: testLabels, 73 } 74 75 testGqlAppWebhook = &graphql.Webhook{ 76 ID: testAppWebhook.ID, 77 Type: graphql.WebhookType(testAppWebhook.Type), 78 } 79 80 testCustomerTenantContext = &webhook.CustomerTenantContext{ 81 CustomerID: TntParentID, 82 AccountID: str.Ptr(TestTenantID), 83 Path: nil, 84 } 85 86 faWithSourceAppAndTargetApp = fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeApplication, model.FormationAssignmentTypeApplication, string(model.ReadyAssignmentState), TestConfigValueRawJSON) 87 faWithSourceAppAndTargetAppReverse = fixReverseFormationAssignment(faWithSourceAppAndTargetApp) 88 webhookFaWithSourceAppAndTargetApp = convertFormationAssignmentFromModel(faWithSourceAppAndTargetApp) 89 webhookFaWithSourceAppAndTargetAppReverse = convertFormationAssignmentFromModel(faWithSourceAppAndTargetAppReverse) 90 91 testAppTenantMappingWebhookInput = fixAppTenantMappingWebhookInput(TestFormationID, testAppWithLabels, testAppWithLabels, testAppTemplateWithLabels, testAppTemplateWithLabels, testCustomerTenantContext, fixConvertFAFromModel(faWithSourceAppAndTargetApp), fixConvertFAFromModel(faWithSourceAppAndTargetAppReverse)) 92 testAppNotificationReqWithTenantMappingType = &webhookclient.FormationAssignmentNotificationRequest{ 93 Webhook: *testGqlAppWebhook, 94 Object: testAppTenantMappingWebhookInput, 95 CorrelationID: "", 96 } 97 98 applicationLabelInput = &model.LabelInput{ 99 Key: appTypeLabelKey, 100 ObjectID: TestTarget, 101 ObjectType: model.ApplicationLabelableObject, 102 } 103 applicationTypeLabel = &model.Label{Value: appSubtype} 104 runtimeTypeLabel = &model.Label{Value: rtmSubtype} 105 ) 106 107 func Test_GenerateFormationAssignmentNotification(t *testing.T) { 108 ctx := context.TODO() 109 110 testNotFoundErr := apperrors.NewNotFoundError(resource.Webhook, TestTarget) 111 faWithInvalidTypes := fixFormationAssignmentModel(TestConfigValueRawJSON) 112 113 faWithSourceRuntimeAndTargetApp := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeRuntime, model.FormationAssignmentTypeApplication, string(model.ReadyAssignmentState), TestConfigValueRawJSON) 114 faWithSourceRuntimeAndTargetAppReverse := fixReverseFormationAssignment(faWithSourceRuntimeAndTargetApp) 115 116 faWithSourceRuntimeCtxAndTargetApp := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeRuntimeContext, model.FormationAssignmentTypeApplication, string(model.ReadyAssignmentState), TestConfigValueRawJSON) 117 faWithSourceRuntimeCtxAndTargetAppReverse := fixReverseFormationAssignment(faWithSourceRuntimeCtxAndTargetApp) 118 119 faWithSourceAppAndTargetRuntime := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeApplication, model.FormationAssignmentTypeRuntime, string(model.ReadyAssignmentState), TestConfigValueRawJSON) 120 faWithSourceAppAndTargetRuntimeReverse := fixReverseFormationAssignment(faWithSourceAppAndTargetRuntime) 121 122 faWithSourceInvalidAndTargetRuntime := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeRuntime, model.FormationAssignmentTypeRuntime, string(model.ReadyAssignmentState), TestConfigValueRawJSON) 123 faWithSourceInvalidAndTargetRtmCtx := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeRuntimeContext, model.FormationAssignmentTypeRuntimeContext, string(model.ReadyAssignmentState), TestConfigValueRawJSON) 124 125 faWithSourceAppCtxAndTargetRtmCtx := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeApplication, model.FormationAssignmentTypeRuntimeContext, string(model.ReadyAssignmentState), TestConfigValueRawJSON) 126 faWithSourceAppCtxAndTargetRtmCtxReverse := fixReverseFormationAssignment(faWithSourceAppCtxAndTargetRtmCtx) 127 128 testGqlRuntimeWebhook := &graphql.Webhook{ 129 ID: testRuntimeWebhook.ID, 130 Type: graphql.WebhookType(testRuntimeWebhook.Type), 131 } 132 133 testCustomerTenantContextWithPath := &webhook.CustomerTenantContext{ 134 CustomerID: TntParentID, 135 AccountID: nil, 136 Path: str.Ptr(TestTenantID), 137 } 138 139 testAppTenantMappingWebhookInputWithTenantPath := fixAppTenantMappingWebhookInput(TestFormationID, testAppWithLabels, testAppWithLabels, testAppTemplateWithLabels, testAppTemplateWithLabels, testCustomerTenantContextWithPath, fixConvertFAFromModel(faWithSourceAppAndTargetApp), fixConvertFAFromModel(faWithSourceAppAndTargetAppReverse)) 140 testAppNotificationReqWithTenantMappingTypeWithTenantPath := &webhookclient.FormationAssignmentNotificationRequest{ 141 Webhook: *testGqlAppWebhook, 142 Object: testAppTenantMappingWebhookInputWithTenantPath, 143 CorrelationID: "", 144 } 145 146 testFormationConfigurationChangeInputWithSourceRuntimeAndTargetApp := fixFormationConfigurationChangeInput(TestFormationID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, testCustomerTenantContext, fixConvertFAFromModel(faWithSourceRuntimeAndTargetApp), fixConvertFAFromModel(faWithSourceRuntimeAndTargetAppReverse)) 147 testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceRuntimeAndTargetApp := &webhookclient.FormationAssignmentNotificationRequest{ 148 Webhook: *testGqlAppWebhook, 149 Object: testFormationConfigurationChangeInputWithSourceRuntimeAndTargetApp, 150 CorrelationID: "", 151 } 152 153 testFormationConfigurationChangeInputWithSourceRtmCtxAndTargetApp := fixFormationConfigurationChangeInput(TestFormationID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, testCustomerTenantContext, fixConvertFAFromModel(faWithSourceRuntimeCtxAndTargetApp), fixConvertFAFromModel(faWithSourceRuntimeCtxAndTargetAppReverse)) 154 testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceRtmCtxAndTargetApp := &webhookclient.FormationAssignmentNotificationRequest{ 155 Webhook: *testGqlAppWebhook, 156 Object: testFormationConfigurationChangeInputWithSourceRtmCtxAndTargetApp, 157 CorrelationID: "", 158 } 159 160 testFormationConfigurationChangeInputWithSourceAppAndTargetRuntime := fixFormationConfigurationChangeInput(TestFormationID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, nil, testCustomerTenantContext, fixConvertFAFromModel(faWithSourceAppAndTargetRuntime), fixConvertFAFromModel(faWithSourceAppAndTargetRuntimeReverse)) 161 testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceAppAndTargetRuntime := &webhookclient.FormationAssignmentNotificationRequest{ 162 Webhook: *testGqlRuntimeWebhook, 163 Object: testFormationConfigurationChangeInputWithSourceAppAndTargetRuntime, 164 CorrelationID: "", 165 } 166 167 testFormationConfigurationChangeInputWithSourceAppAndTargetRtmCtx := fixFormationConfigurationChangeInput(TestFormationID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, testCustomerTenantContext, fixConvertFAFromModel(faWithSourceAppCtxAndTargetRtmCtx), fixConvertFAFromModel(faWithSourceAppCtxAndTargetRtmCtxReverse)) 168 testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceAppAndTargetRtmCtx := &webhookclient.FormationAssignmentNotificationRequest{ 169 Webhook: *testGqlRuntimeWebhook, 170 Object: testFormationConfigurationChangeInputWithSourceAppAndTargetRtmCtx, 171 CorrelationID: "", 172 } 173 174 formation := &model.Formation{FormationTemplateID: TestFormationTemplateID} 175 details := &formationconstraint.GenerateFormationAssignmentNotificationOperationDetails{} 176 177 var emptyRuntimeCtx *webhook.RuntimeContextWithLabels 178 gaTenantObject := fixModelBusinessTenantMappingWithType(tnt.Account) 179 rgTenantObject := fixModelBusinessTenantMappingWithType(tnt.ResourceGroup) 180 181 testCases := []struct { 182 name string 183 formationAssignment *model.FormationAssignment 184 formationOperation model.FormationOperation 185 webhookRepo func() *automock.WebhookRepository 186 webhookDataInputBuilder func() *databuilderautomock.DataInputBuilder 187 formationAssignmentRepo func() *automock.FormationAssignmentRepository 188 formationRepo func() *automock.FormationRepository 189 notificationBuilder func() *automock.NotificationBuilder 190 tenantRepo func() *automock.TenantRepository 191 expectedNotification *webhookclient.FormationAssignmentNotificationRequest 192 expectedErrMsg string 193 }{ 194 { 195 name: "Error when formation assignment type is invalid", 196 formationRepo: func() *automock.FormationRepository { 197 repo := &automock.FormationRepository{} 198 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(nil, nil).Once() 199 return repo 200 }, 201 formationAssignment: faWithInvalidTypes, 202 formationOperation: model.AssignFormation, 203 tenantRepo: func() *automock.TenantRepository { 204 repo := &automock.TenantRepository{} 205 repo.On("Get", emptyCtx, faWithInvalidTypes.TenantID).Return(gaTenantObject, nil) 206 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithInvalidTypes.TenantID).Return(TntParentID, nil) 207 return repo 208 }, 209 expectedErrMsg: "Unknown formation assignment type:", 210 }, 211 // application formation assignment notifications with source application 212 { 213 name: "Successfully generate application notification when source type is application and tenant is global account", 214 formationAssignment: faWithSourceAppAndTargetApp, 215 formationOperation: model.AssignFormation, 216 tenantRepo: func() *automock.TenantRepository { 217 repo := &automock.TenantRepository{} 218 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 219 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 220 return repo 221 }, 222 webhookRepo: func() *automock.WebhookRepository { 223 webhookRepo := &automock.WebhookRepository{} 224 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeApplicationTenantMapping).Return(testAppWebhook, nil).Once() 225 return webhookRepo 226 }, 227 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 228 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 229 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 230 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 231 return webhookDataInputBuilder 232 }, 233 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 234 faRepo := &automock.FormationAssignmentRepository{} 235 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetAppReverse, nil).Once() 236 return faRepo 237 }, 238 formationRepo: func() *automock.FormationRepository { 239 repo := &automock.FormationRepository{} 240 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 241 return repo 242 }, 243 notificationBuilder: func() *automock.NotificationBuilder { 244 notificationsBuilder := &automock.NotificationBuilder{} 245 246 notificationsBuilder.On("PrepareDetailsForApplicationTenantMappingNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testAppTemplateWithLabels, testAppWithLabels, webhookFaWithSourceAppAndTargetApp, webhookFaWithSourceAppAndTargetAppReverse, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 247 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testAppWebhook).Return(testAppNotificationReqWithTenantMappingType, nil).Once() 248 249 return notificationsBuilder 250 }, 251 expectedNotification: testAppNotificationReqWithTenantMappingType, 252 }, 253 { 254 name: "Successfully generate application notification when source type is application and tenant is resource group", 255 formationAssignment: faWithSourceAppAndTargetApp, 256 formationOperation: model.AssignFormation, 257 tenantRepo: func() *automock.TenantRepository { 258 repo := &automock.TenantRepository{} 259 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(rgTenantObject, nil) 260 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 261 return repo 262 }, 263 webhookRepo: func() *automock.WebhookRepository { 264 webhookRepo := &automock.WebhookRepository{} 265 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeApplicationTenantMapping).Return(testAppWebhook, nil).Once() 266 return webhookRepo 267 }, 268 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 269 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 270 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 271 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 272 return webhookDataInputBuilder 273 }, 274 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 275 faRepo := &automock.FormationAssignmentRepository{} 276 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetAppReverse, nil).Once() 277 return faRepo 278 }, 279 formationRepo: func() *automock.FormationRepository { 280 repo := &automock.FormationRepository{} 281 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 282 return repo 283 }, 284 notificationBuilder: func() *automock.NotificationBuilder { 285 notificationsBuilder := &automock.NotificationBuilder{} 286 287 notificationsBuilder.On("PrepareDetailsForApplicationTenantMappingNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testAppTemplateWithLabels, testAppWithLabels, webhookFaWithSourceAppAndTargetApp, webhookFaWithSourceAppAndTargetAppReverse, testCustomerTenantContextWithPath, TestTenantID).Return(details, nil).Once() 288 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testAppWebhook).Return(testAppNotificationReqWithTenantMappingTypeWithTenantPath, nil).Once() 289 290 return notificationsBuilder 291 }, 292 expectedNotification: testAppNotificationReqWithTenantMappingTypeWithTenantPath, 293 }, 294 { 295 name: "Success when application webhook is not found", 296 formationAssignment: faWithSourceAppAndTargetApp, 297 formationOperation: model.AssignFormation, 298 tenantRepo: func() *automock.TenantRepository { 299 repo := &automock.TenantRepository{} 300 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 301 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 302 return repo 303 }, 304 webhookRepo: func() *automock.WebhookRepository { 305 webhookRepo := &automock.WebhookRepository{} 306 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeApplicationTenantMapping).Return(nil, testNotFoundErr).Once() 307 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testAppTemplateID, model.ApplicationTemplateWebhookReference, model.WebhookTypeApplicationTenantMapping).Return(nil, testNotFoundErr).Once() 308 return webhookRepo 309 }, 310 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 311 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 312 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 313 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 314 return webhookDataInputBuilder 315 }, 316 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 317 faRepo := &automock.FormationAssignmentRepository{} 318 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetAppReverse, nil).Once() 319 return faRepo 320 }, 321 formationRepo: func() *automock.FormationRepository { 322 repo := &automock.FormationRepository{} 323 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 324 return repo 325 }, 326 notificationBuilder: func() *automock.NotificationBuilder { 327 notificationsBuilder := &automock.NotificationBuilder{} 328 329 notificationsBuilder.On("PrepareDetailsForApplicationTenantMappingNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testAppTemplateWithLabels, testAppWithLabels, webhookFaWithSourceAppAndTargetApp, webhookFaWithSourceAppAndTargetAppReverse, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 330 331 return notificationsBuilder 332 }, 333 }, 334 { 335 name: "Error when getting formation by ID", 336 formationAssignment: faWithSourceAppAndTargetApp, 337 formationOperation: model.AssignFormation, 338 tenantRepo: func() *automock.TenantRepository { 339 repo := &automock.TenantRepository{} 340 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 341 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 342 return repo 343 }, 344 formationRepo: func() *automock.FormationRepository { 345 repo := &automock.FormationRepository{} 346 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(nil, testErr).Once() 347 return repo 348 }, 349 expectedErrMsg: testErr.Error(), 350 }, 351 { 352 name: "Error when getting tenant fails", 353 formationAssignment: faWithSourceAppAndTargetApp, 354 formationOperation: model.AssignFormation, 355 tenantRepo: func() *automock.TenantRepository { 356 repo := &automock.TenantRepository{} 357 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(nil, testErr) 358 return repo 359 }, 360 expectedErrMsg: testErr.Error(), 361 }, 362 { 363 name: "Error when getting parent customer id fails", 364 formationAssignment: faWithSourceAppAndTargetApp, 365 formationOperation: model.AssignFormation, 366 tenantRepo: func() *automock.TenantRepository { 367 repo := &automock.TenantRepository{} 368 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 369 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return("", testErr) 370 return repo 371 }, 372 expectedErrMsg: testErr.Error(), 373 }, 374 { 375 name: "Error when getting application template webhook by ID and type", 376 formationAssignment: faWithSourceAppAndTargetApp, 377 formationOperation: model.AssignFormation, 378 tenantRepo: func() *automock.TenantRepository { 379 repo := &automock.TenantRepository{} 380 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 381 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 382 return repo 383 }, 384 webhookRepo: func() *automock.WebhookRepository { 385 webhookRepo := &automock.WebhookRepository{} 386 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeApplicationTenantMapping).Return(nil, testNotFoundErr).Once() 387 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testAppTemplateID, model.ApplicationTemplateWebhookReference, model.WebhookTypeApplicationTenantMapping).Return(nil, testErr).Once() 388 389 return webhookRepo 390 }, 391 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 392 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 393 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 394 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 395 return webhookDataInputBuilder 396 }, 397 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 398 faRepo := &automock.FormationAssignmentRepository{} 399 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetAppReverse, nil).Once() 400 return faRepo 401 }, 402 formationRepo: func() *automock.FormationRepository { 403 repo := &automock.FormationRepository{} 404 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 405 return repo 406 }, 407 notificationBuilder: func() *automock.NotificationBuilder { 408 notificationsBuilder := &automock.NotificationBuilder{} 409 410 notificationsBuilder.On("PrepareDetailsForApplicationTenantMappingNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testAppTemplateWithLabels, testAppWithLabels, webhookFaWithSourceAppAndTargetApp, webhookFaWithSourceAppAndTargetAppReverse, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 411 412 return notificationsBuilder 413 }, 414 expectedErrMsg: fmt.Sprintf("while listing %q webhooks for application template with ID: %q on behalf of application with ID: %q", model.WebhookTypeApplicationTenantMapping, testAppTemplateID, TestTarget), 415 }, 416 { 417 name: "Error when preparing app and app template with labels for source type application", 418 formationAssignment: faWithSourceAppAndTargetApp, 419 formationOperation: model.AssignFormation, 420 tenantRepo: func() *automock.TenantRepository { 421 repo := &automock.TenantRepository{} 422 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 423 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 424 return repo 425 }, 426 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 427 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 428 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(nil, nil, testErr).Once() 429 return webhookDataInputBuilder 430 }, 431 formationRepo: func() *automock.FormationRepository { 432 repo := &automock.FormationRepository{} 433 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 434 return repo 435 }, 436 expectedErrMsg: testErr.Error(), 437 }, 438 { 439 name: "Error when preparing reverse app and app template with labels for source type application", 440 formationAssignment: faWithSourceAppAndTargetApp, 441 formationOperation: model.AssignFormation, 442 tenantRepo: func() *automock.TenantRepository { 443 repo := &automock.TenantRepository{} 444 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 445 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 446 return repo 447 }, 448 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 449 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 450 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 451 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(nil, nil, testErr).Once() 452 return webhookDataInputBuilder 453 }, 454 formationRepo: func() *automock.FormationRepository { 455 repo := &automock.FormationRepository{} 456 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 457 return repo 458 }, 459 expectedErrMsg: testErr.Error(), 460 }, 461 { 462 name: "Error when getting reverse formation assignment by source and target for source type application", 463 formationAssignment: faWithSourceAppAndTargetApp, 464 formationOperation: model.AssignFormation, 465 tenantRepo: func() *automock.TenantRepository { 466 repo := &automock.TenantRepository{} 467 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 468 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 469 return repo 470 }, 471 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 472 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 473 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 474 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 475 return webhookDataInputBuilder 476 }, 477 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 478 faRepo := &automock.FormationAssignmentRepository{} 479 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(nil, testErr).Once() 480 return faRepo 481 }, 482 formationRepo: func() *automock.FormationRepository { 483 repo := &automock.FormationRepository{} 484 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 485 return repo 486 }, 487 expectedErrMsg: testErr.Error(), 488 }, 489 { 490 name: "Error when preparing details", 491 formationAssignment: faWithSourceAppAndTargetApp, 492 formationOperation: model.AssignFormation, 493 tenantRepo: func() *automock.TenantRepository { 494 repo := &automock.TenantRepository{} 495 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 496 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 497 return repo 498 }, 499 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 500 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 501 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 502 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 503 return webhookDataInputBuilder 504 }, 505 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 506 faRepo := &automock.FormationAssignmentRepository{} 507 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetAppReverse, nil).Once() 508 return faRepo 509 }, 510 formationRepo: func() *automock.FormationRepository { 511 repo := &automock.FormationRepository{} 512 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 513 return repo 514 }, 515 notificationBuilder: func() *automock.NotificationBuilder { 516 notificationsBuilder := &automock.NotificationBuilder{} 517 518 notificationsBuilder.On("PrepareDetailsForApplicationTenantMappingNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testAppTemplateWithLabels, testAppWithLabels, webhookFaWithSourceAppAndTargetApp, webhookFaWithSourceAppAndTargetAppReverse, testCustomerTenantContext, TestTenantID).Return(nil, testErr).Once() 519 520 return notificationsBuilder 521 }, 522 expectedErrMsg: testErr.Error(), 523 }, 524 { 525 name: "Error while building notification request", 526 formationAssignment: faWithSourceAppAndTargetApp, 527 formationOperation: model.AssignFormation, 528 tenantRepo: func() *automock.TenantRepository { 529 repo := &automock.TenantRepository{} 530 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 531 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 532 return repo 533 }, 534 webhookRepo: func() *automock.WebhookRepository { 535 webhookRepo := &automock.WebhookRepository{} 536 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeApplicationTenantMapping).Return(testAppWebhook, nil).Once() 537 return webhookRepo 538 }, 539 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 540 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 541 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 542 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 543 return webhookDataInputBuilder 544 }, 545 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 546 faRepo := &automock.FormationAssignmentRepository{} 547 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetAppReverse, nil).Once() 548 return faRepo 549 }, 550 formationRepo: func() *automock.FormationRepository { 551 repo := &automock.FormationRepository{} 552 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 553 return repo 554 }, 555 notificationBuilder: func() *automock.NotificationBuilder { 556 notificationsBuilder := &automock.NotificationBuilder{} 557 558 notificationsBuilder.On("PrepareDetailsForApplicationTenantMappingNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testAppTemplateWithLabels, testAppWithLabels, webhookFaWithSourceAppAndTargetApp, webhookFaWithSourceAppAndTargetAppReverse, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 559 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testAppWebhook).Return(nil, testErr).Once() 560 561 return notificationsBuilder 562 }, 563 expectedErrMsg: testErr.Error(), 564 }, 565 { 566 name: "Error when getting application webhook by ID and type", 567 formationAssignment: faWithSourceAppAndTargetApp, 568 formationOperation: model.AssignFormation, 569 tenantRepo: func() *automock.TenantRepository { 570 repo := &automock.TenantRepository{} 571 repo.On("Get", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(gaTenantObject, nil) 572 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetApp.TenantID).Return(TntParentID, nil) 573 return repo 574 }, 575 webhookRepo: func() *automock.WebhookRepository { 576 webhookRepo := &automock.WebhookRepository{} 577 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeApplicationTenantMapping).Return(nil, testErr).Once() 578 return webhookRepo 579 }, 580 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 581 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 582 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 583 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 584 return webhookDataInputBuilder 585 }, 586 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 587 faRepo := &automock.FormationAssignmentRepository{} 588 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetAppReverse, nil).Once() 589 return faRepo 590 }, 591 formationRepo: func() *automock.FormationRepository { 592 repo := &automock.FormationRepository{} 593 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 594 return repo 595 }, 596 notificationBuilder: func() *automock.NotificationBuilder { 597 notificationsBuilder := &automock.NotificationBuilder{} 598 599 notificationsBuilder.On("PrepareDetailsForApplicationTenantMappingNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testAppTemplateWithLabels, testAppWithLabels, webhookFaWithSourceAppAndTargetApp, webhookFaWithSourceAppAndTargetAppReverse, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 600 601 return notificationsBuilder 602 }, 603 expectedErrMsg: testErr.Error(), 604 }, 605 // application formation assignment notifications with source runtime 606 { 607 name: "Successfully generate application notification when source type is runtime", 608 formationAssignment: faWithSourceRuntimeAndTargetApp, 609 formationOperation: model.AssignFormation, 610 tenantRepo: func() *automock.TenantRepository { 611 repo := &automock.TenantRepository{} 612 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 613 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 614 return repo 615 }, 616 webhookRepo: func() *automock.WebhookRepository { 617 webhookRepo := &automock.WebhookRepository{} 618 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeConfigurationChanged).Return(testAppWebhook, nil).Once() 619 return webhookRepo 620 }, 621 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 622 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 623 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 624 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeWithLabels, nil).Once() 625 return webhookDataInputBuilder 626 }, 627 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 628 faRepo := &automock.FormationAssignmentRepository{} 629 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeAndTargetAppReverse, nil).Once() 630 return faRepo 631 }, 632 formationRepo: func() *automock.FormationRepository { 633 repo := &automock.FormationRepository{} 634 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 635 return repo 636 }, 637 notificationBuilder: func() *automock.NotificationBuilder { 638 notificationsBuilder := &automock.NotificationBuilder{} 639 640 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, emptyRuntimeCtx, convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 641 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testAppWebhook).Return(testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceRuntimeAndTargetApp, nil).Once() 642 643 return notificationsBuilder 644 }, 645 expectedNotification: testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceRuntimeAndTargetApp, 646 }, 647 { 648 name: "Error when getting tenant fails", 649 formationAssignment: faWithSourceRuntimeAndTargetApp, 650 formationOperation: model.AssignFormation, 651 tenantRepo: func() *automock.TenantRepository { 652 repo := &automock.TenantRepository{} 653 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(nil, testErr) 654 return repo 655 }, 656 expectedErrMsg: testErr.Error(), 657 }, 658 { 659 name: "Error when getting parent customer id fails", 660 formationAssignment: faWithSourceRuntimeAndTargetApp, 661 formationOperation: model.AssignFormation, 662 tenantRepo: func() *automock.TenantRepository { 663 repo := &automock.TenantRepository{} 664 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 665 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return("", testErr) 666 return repo 667 }, 668 expectedErrMsg: testErr.Error(), 669 }, 670 { 671 name: "Error when preparing app and app template with labels for source type runtime", 672 formationAssignment: faWithSourceRuntimeAndTargetApp, 673 formationOperation: model.AssignFormation, 674 tenantRepo: func() *automock.TenantRepository { 675 repo := &automock.TenantRepository{} 676 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 677 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 678 return repo 679 }, 680 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 681 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 682 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(nil, nil, testErr).Once() 683 return webhookDataInputBuilder 684 }, 685 formationRepo: func() *automock.FormationRepository { 686 repo := &automock.FormationRepository{} 687 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 688 return repo 689 }, 690 expectedErrMsg: testErr.Error(), 691 }, 692 { 693 name: "Error when preparing runtime and runtime context with labels for source type runtime", 694 formationAssignment: faWithSourceRuntimeAndTargetApp, 695 formationOperation: model.AssignFormation, 696 tenantRepo: func() *automock.TenantRepository { 697 repo := &automock.TenantRepository{} 698 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 699 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 700 return repo 701 }, 702 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 703 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 704 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 705 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestSource).Return(nil, testErr).Once() 706 return webhookDataInputBuilder 707 }, 708 formationRepo: func() *automock.FormationRepository { 709 repo := &automock.FormationRepository{} 710 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 711 return repo 712 }, 713 expectedErrMsg: testErr.Error(), 714 }, 715 { 716 name: "Error when getting reverse formation assignment by source and target for source type runtime", 717 formationAssignment: faWithSourceRuntimeAndTargetApp, 718 formationOperation: model.AssignFormation, 719 tenantRepo: func() *automock.TenantRepository { 720 repo := &automock.TenantRepository{} 721 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 722 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 723 return repo 724 }, 725 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 726 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 727 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 728 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeWithLabels, nil).Once() 729 return webhookDataInputBuilder 730 }, 731 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 732 faRepo := &automock.FormationAssignmentRepository{} 733 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(nil, testErr).Once() 734 return faRepo 735 }, 736 formationRepo: func() *automock.FormationRepository { 737 repo := &automock.FormationRepository{} 738 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 739 return repo 740 }, 741 expectedErrMsg: testErr.Error(), 742 }, 743 { 744 name: "Error when preparing details for source type runtime", 745 formationAssignment: faWithSourceRuntimeAndTargetApp, 746 formationOperation: model.AssignFormation, 747 tenantRepo: func() *automock.TenantRepository { 748 repo := &automock.TenantRepository{} 749 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 750 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 751 return repo 752 }, 753 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 754 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 755 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 756 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeWithLabels, nil).Once() 757 return webhookDataInputBuilder 758 }, 759 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 760 faRepo := &automock.FormationAssignmentRepository{} 761 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeAndTargetAppReverse, nil).Once() 762 return faRepo 763 }, 764 formationRepo: func() *automock.FormationRepository { 765 repo := &automock.FormationRepository{} 766 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 767 return repo 768 }, 769 notificationBuilder: func() *automock.NotificationBuilder { 770 notificationsBuilder := &automock.NotificationBuilder{} 771 772 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, emptyRuntimeCtx, convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(nil, testErr).Once() 773 774 return notificationsBuilder 775 }, 776 expectedErrMsg: testErr.Error(), 777 }, 778 { 779 name: "Success when getting application webhook return not found error", 780 formationAssignment: faWithSourceRuntimeAndTargetApp, 781 formationOperation: model.AssignFormation, 782 tenantRepo: func() *automock.TenantRepository { 783 repo := &automock.TenantRepository{} 784 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 785 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 786 return repo 787 }, 788 webhookRepo: func() *automock.WebhookRepository { 789 webhookRepo := &automock.WebhookRepository{} 790 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testNotFoundErr).Once() 791 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testAppTemplateID, model.ApplicationTemplateWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testNotFoundErr).Once() 792 return webhookRepo 793 }, 794 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 795 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 796 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 797 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeWithLabels, nil).Once() 798 return webhookDataInputBuilder 799 }, 800 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 801 faRepo := &automock.FormationAssignmentRepository{} 802 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeAndTargetAppReverse, nil).Once() 803 return faRepo 804 }, 805 formationRepo: func() *automock.FormationRepository { 806 repo := &automock.FormationRepository{} 807 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 808 return repo 809 }, 810 notificationBuilder: func() *automock.NotificationBuilder { 811 notificationsBuilder := &automock.NotificationBuilder{} 812 813 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, emptyRuntimeCtx, convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 814 815 return notificationsBuilder 816 }, 817 }, 818 { 819 name: "Error when getting application webhook by ID and type", 820 formationAssignment: faWithSourceRuntimeAndTargetApp, 821 formationOperation: model.AssignFormation, 822 tenantRepo: func() *automock.TenantRepository { 823 repo := &automock.TenantRepository{} 824 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 825 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 826 return repo 827 }, 828 webhookRepo: func() *automock.WebhookRepository { 829 webhookRepo := &automock.WebhookRepository{} 830 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testErr).Once() 831 return webhookRepo 832 }, 833 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 834 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 835 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 836 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeWithLabels, nil).Once() 837 return webhookDataInputBuilder 838 }, 839 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 840 faRepo := &automock.FormationAssignmentRepository{} 841 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeAndTargetAppReverse, nil).Once() 842 return faRepo 843 }, 844 formationRepo: func() *automock.FormationRepository { 845 repo := &automock.FormationRepository{} 846 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 847 return repo 848 }, 849 notificationBuilder: func() *automock.NotificationBuilder { 850 notificationsBuilder := &automock.NotificationBuilder{} 851 852 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, emptyRuntimeCtx, convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 853 854 return notificationsBuilder 855 }, 856 expectedErrMsg: testErr.Error(), 857 }, 858 { 859 name: "Error when building notification request for source type runtime", 860 formationAssignment: faWithSourceRuntimeAndTargetApp, 861 formationOperation: model.AssignFormation, 862 tenantRepo: func() *automock.TenantRepository { 863 repo := &automock.TenantRepository{} 864 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 865 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 866 return repo 867 }, 868 webhookRepo: func() *automock.WebhookRepository { 869 webhookRepo := &automock.WebhookRepository{} 870 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeConfigurationChanged).Return(testAppWebhook, nil).Once() 871 return webhookRepo 872 }, 873 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 874 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 875 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 876 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeWithLabels, nil).Once() 877 return webhookDataInputBuilder 878 }, 879 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 880 faRepo := &automock.FormationAssignmentRepository{} 881 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeAndTargetAppReverse, nil).Once() 882 return faRepo 883 }, 884 formationRepo: func() *automock.FormationRepository { 885 repo := &automock.FormationRepository{} 886 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 887 return repo 888 }, 889 notificationBuilder: func() *automock.NotificationBuilder { 890 notificationsBuilder := &automock.NotificationBuilder{} 891 892 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, emptyRuntimeCtx, convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 893 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testAppWebhook).Return(nil, testErr).Once() 894 895 return notificationsBuilder 896 }, 897 expectedErrMsg: testErr.Error(), 898 }, 899 // application formation assignment notifications with source runtime context 900 { 901 name: "Successfully generate application notification when source type is runtime context", 902 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 903 formationOperation: model.AssignFormation, 904 tenantRepo: func() *automock.TenantRepository { 905 repo := &automock.TenantRepository{} 906 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(gaTenantObject, nil) 907 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(TntParentID, nil) 908 return repo 909 }, 910 webhookRepo: func() *automock.WebhookRepository { 911 webhookRepo := &automock.WebhookRepository{} 912 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeConfigurationChanged).Return(testAppWebhook, nil).Once() 913 return webhookRepo 914 }, 915 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 916 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 917 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 918 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeCtxWithLabels, nil).Once() 919 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 920 return webhookDataInputBuilder 921 }, 922 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 923 faRepo := &automock.FormationAssignmentRepository{} 924 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeCtxAndTargetAppReverse, nil).Once() 925 return faRepo 926 }, 927 formationRepo: func() *automock.FormationRepository { 928 repo := &automock.FormationRepository{} 929 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 930 return repo 931 }, 932 notificationBuilder: func() *automock.NotificationBuilder { 933 notificationsBuilder := &automock.NotificationBuilder{} 934 935 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 936 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testAppWebhook).Return(testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceRtmCtxAndTargetApp, nil).Once() 937 938 return notificationsBuilder 939 }, 940 expectedNotification: testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceRtmCtxAndTargetApp, 941 }, 942 { 943 name: "Error when getting tenant fails", 944 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 945 formationOperation: model.AssignFormation, 946 tenantRepo: func() *automock.TenantRepository { 947 repo := &automock.TenantRepository{} 948 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(nil, testErr) 949 return repo 950 }, 951 expectedErrMsg: testErr.Error(), 952 }, 953 { 954 name: "Error when getting parent customer id fails", 955 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 956 formationOperation: model.AssignFormation, 957 tenantRepo: func() *automock.TenantRepository { 958 repo := &automock.TenantRepository{} 959 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(gaTenantObject, nil) 960 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return("", testErr) 961 return repo 962 }, 963 expectedErrMsg: testErr.Error(), 964 }, 965 { 966 name: "Error when preparing app and app template with labels for source type runtime context", 967 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 968 formationOperation: model.AssignFormation, 969 tenantRepo: func() *automock.TenantRepository { 970 repo := &automock.TenantRepository{} 971 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(gaTenantObject, nil) 972 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(TntParentID, nil) 973 return repo 974 }, 975 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 976 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 977 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(nil, nil, testErr).Once() 978 return webhookDataInputBuilder 979 }, 980 formationRepo: func() *automock.FormationRepository { 981 repo := &automock.FormationRepository{} 982 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 983 return repo 984 }, 985 expectedErrMsg: testErr.Error(), 986 }, 987 { 988 name: "Error when preparing runtime context with labels for source type runtime context", 989 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 990 formationOperation: model.AssignFormation, 991 tenantRepo: func() *automock.TenantRepository { 992 repo := &automock.TenantRepository{} 993 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(gaTenantObject, nil) 994 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(TntParentID, nil) 995 return repo 996 }, 997 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 998 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 999 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1000 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestSource).Return(nil, testErr).Once() 1001 return webhookDataInputBuilder 1002 }, 1003 formationRepo: func() *automock.FormationRepository { 1004 repo := &automock.FormationRepository{} 1005 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1006 return repo 1007 }, 1008 expectedErrMsg: testErr.Error(), 1009 }, 1010 { 1011 name: "Error when preparing runtime with labels for source type runtime context", 1012 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 1013 formationOperation: model.AssignFormation, 1014 tenantRepo: func() *automock.TenantRepository { 1015 repo := &automock.TenantRepository{} 1016 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(gaTenantObject, nil) 1017 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(TntParentID, nil) 1018 return repo 1019 }, 1020 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1021 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1022 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1023 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeCtxWithLabels, nil).Once() 1024 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(nil, testErr).Once() 1025 return webhookDataInputBuilder 1026 }, 1027 formationRepo: func() *automock.FormationRepository { 1028 repo := &automock.FormationRepository{} 1029 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1030 return repo 1031 }, 1032 expectedErrMsg: testErr.Error(), 1033 }, 1034 { 1035 name: "Error when getting reverse formation assignment by source and target for source type runtime context", 1036 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 1037 formationOperation: model.AssignFormation, 1038 tenantRepo: func() *automock.TenantRepository { 1039 repo := &automock.TenantRepository{} 1040 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(gaTenantObject, nil) 1041 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(TntParentID, nil) 1042 return repo 1043 }, 1044 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1045 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1046 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1047 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeCtxWithLabels, nil).Once() 1048 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 1049 return webhookDataInputBuilder 1050 }, 1051 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1052 faRepo := &automock.FormationAssignmentRepository{} 1053 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(nil, testErr).Once() 1054 return faRepo 1055 }, 1056 formationRepo: func() *automock.FormationRepository { 1057 repo := &automock.FormationRepository{} 1058 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1059 return repo 1060 }, 1061 expectedErrMsg: testErr.Error(), 1062 }, 1063 { 1064 name: "Error when preparing details for source type runtime context", 1065 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 1066 formationOperation: model.AssignFormation, 1067 tenantRepo: func() *automock.TenantRepository { 1068 repo := &automock.TenantRepository{} 1069 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(gaTenantObject, nil) 1070 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(TntParentID, nil) 1071 return repo 1072 }, 1073 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1074 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1075 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1076 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeCtxWithLabels, nil).Once() 1077 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 1078 return webhookDataInputBuilder 1079 }, 1080 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1081 faRepo := &automock.FormationAssignmentRepository{} 1082 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeCtxAndTargetAppReverse, nil).Once() 1083 return faRepo 1084 }, 1085 formationRepo: func() *automock.FormationRepository { 1086 repo := &automock.FormationRepository{} 1087 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1088 return repo 1089 }, 1090 notificationBuilder: func() *automock.NotificationBuilder { 1091 notificationsBuilder := &automock.NotificationBuilder{} 1092 1093 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(nil, testErr).Once() 1094 1095 return notificationsBuilder 1096 }, 1097 expectedErrMsg: testErr.Error(), 1098 }, 1099 { 1100 name: "Success when getting application webhook by ID and type return not found error", 1101 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 1102 formationOperation: model.AssignFormation, 1103 tenantRepo: func() *automock.TenantRepository { 1104 repo := &automock.TenantRepository{} 1105 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(gaTenantObject, nil) 1106 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(TntParentID, nil) 1107 return repo 1108 }, 1109 webhookRepo: func() *automock.WebhookRepository { 1110 webhookRepo := &automock.WebhookRepository{} 1111 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testNotFoundErr).Once() 1112 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testAppTemplateID, model.ApplicationTemplateWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testNotFoundErr).Once() 1113 1114 return webhookRepo 1115 }, 1116 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1117 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1118 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1119 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeCtxWithLabels, nil).Once() 1120 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 1121 return webhookDataInputBuilder 1122 }, 1123 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1124 faRepo := &automock.FormationAssignmentRepository{} 1125 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeCtxAndTargetAppReverse, nil).Once() 1126 return faRepo 1127 }, 1128 formationRepo: func() *automock.FormationRepository { 1129 repo := &automock.FormationRepository{} 1130 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1131 return repo 1132 }, 1133 notificationBuilder: func() *automock.NotificationBuilder { 1134 notificationsBuilder := &automock.NotificationBuilder{} 1135 1136 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 1137 1138 return notificationsBuilder 1139 }, 1140 }, 1141 { 1142 name: "Error when getting application webhook by ID and type", 1143 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 1144 formationOperation: model.AssignFormation, 1145 tenantRepo: func() *automock.TenantRepository { 1146 repo := &automock.TenantRepository{} 1147 repo.On("Get", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(gaTenantObject, nil) 1148 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeCtxAndTargetApp.TenantID).Return(TntParentID, nil) 1149 return repo 1150 }, 1151 webhookRepo: func() *automock.WebhookRepository { 1152 webhookRepo := &automock.WebhookRepository{} 1153 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testErr).Once() 1154 return webhookRepo 1155 }, 1156 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1157 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1158 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1159 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeCtxWithLabels, nil).Once() 1160 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 1161 return webhookDataInputBuilder 1162 }, 1163 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1164 faRepo := &automock.FormationAssignmentRepository{} 1165 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeCtxAndTargetAppReverse, nil).Once() 1166 return faRepo 1167 }, 1168 formationRepo: func() *automock.FormationRepository { 1169 repo := &automock.FormationRepository{} 1170 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1171 return repo 1172 }, 1173 notificationBuilder: func() *automock.NotificationBuilder { 1174 notificationsBuilder := &automock.NotificationBuilder{} 1175 1176 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 1177 1178 return notificationsBuilder 1179 }, 1180 expectedErrMsg: testErr.Error(), 1181 }, 1182 { 1183 name: "Error when building notification request for source type runtime context", 1184 formationAssignment: faWithSourceRuntimeCtxAndTargetApp, 1185 formationOperation: model.AssignFormation, 1186 tenantRepo: func() *automock.TenantRepository { 1187 repo := &automock.TenantRepository{} 1188 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 1189 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 1190 return repo 1191 }, 1192 webhookRepo: func() *automock.WebhookRepository { 1193 webhookRepo := &automock.WebhookRepository{} 1194 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.ApplicationWebhookReference, model.WebhookTypeConfigurationChanged).Return(testAppWebhook, nil).Once() 1195 return webhookRepo 1196 }, 1197 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1198 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1199 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1200 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestSource).Return(testRuntimeCtxWithLabels, nil).Once() 1201 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 1202 return webhookDataInputBuilder 1203 }, 1204 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1205 faRepo := &automock.FormationAssignmentRepository{} 1206 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceRuntimeCtxAndTargetAppReverse, nil).Once() 1207 return faRepo 1208 }, 1209 formationRepo: func() *automock.FormationRepository { 1210 repo := &automock.FormationRepository{} 1211 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1212 return repo 1213 }, 1214 notificationBuilder: func() *automock.NotificationBuilder { 1215 notificationsBuilder := &automock.NotificationBuilder{} 1216 1217 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetApp), convertFormationAssignmentFromModel(faWithSourceRuntimeCtxAndTargetAppReverse), model.ApplicationResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 1218 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testAppWebhook).Return(nil, testErr).Once() 1219 1220 return notificationsBuilder 1221 }, 1222 expectedErrMsg: testErr.Error(), 1223 }, 1224 // runtime formation assignment notifications with source application 1225 { 1226 name: "Successfully generate runtime notification when source type is application", 1227 formationAssignment: faWithSourceAppAndTargetRuntime, 1228 formationOperation: model.AssignFormation, 1229 tenantRepo: func() *automock.TenantRepository { 1230 repo := &automock.TenantRepository{} 1231 repo.On("Get", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(gaTenantObject, nil) 1232 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(TntParentID, nil) 1233 return repo 1234 }, 1235 webhookRepo: func() *automock.WebhookRepository { 1236 webhookRepo := &automock.WebhookRepository{} 1237 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1238 return webhookRepo 1239 }, 1240 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1241 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1242 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1243 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeWithLabels, nil).Once() 1244 return webhookDataInputBuilder 1245 }, 1246 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1247 faRepo := &automock.FormationAssignmentRepository{} 1248 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetRuntimeReverse, nil).Once() 1249 return faRepo 1250 }, 1251 formationRepo: func() *automock.FormationRepository { 1252 repo := &automock.FormationRepository{} 1253 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1254 return repo 1255 }, 1256 notificationBuilder: func() *automock.NotificationBuilder { 1257 notificationsBuilder := &automock.NotificationBuilder{} 1258 1259 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, emptyRuntimeCtx, convertFormationAssignmentFromModel(faWithSourceAppAndTargetRuntime), convertFormationAssignmentFromModel(faWithSourceAppAndTargetRuntimeReverse), model.RuntimeResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 1260 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testRuntimeWebhook).Return(testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceAppAndTargetRuntime, nil).Once() 1261 1262 return notificationsBuilder 1263 }, 1264 expectedNotification: testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceAppAndTargetRuntime, 1265 }, 1266 { 1267 name: "Success when runtime webhook is not found", 1268 formationAssignment: faWithSourceAppAndTargetRuntime, 1269 formationOperation: model.AssignFormation, 1270 tenantRepo: func() *automock.TenantRepository { 1271 repo := &automock.TenantRepository{} 1272 repo.On("Get", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(gaTenantObject, nil) 1273 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(TntParentID, nil) 1274 return repo 1275 }, 1276 webhookRepo: func() *automock.WebhookRepository { 1277 webhookRepo := &automock.WebhookRepository{} 1278 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testNotFoundErr).Once() 1279 return webhookRepo 1280 }, 1281 formationRepo: func() *automock.FormationRepository { 1282 repo := &automock.FormationRepository{} 1283 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1284 return repo 1285 }, 1286 }, 1287 { 1288 name: "Error when getting tenant fails", 1289 formationAssignment: faWithSourceAppAndTargetRuntime, 1290 formationOperation: model.AssignFormation, 1291 tenantRepo: func() *automock.TenantRepository { 1292 repo := &automock.TenantRepository{} 1293 repo.On("Get", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(nil, testErr) 1294 return repo 1295 }, 1296 expectedErrMsg: testErr.Error(), 1297 }, 1298 { 1299 name: "Error when getting parent customer id fails", 1300 formationAssignment: faWithSourceAppAndTargetRuntime, 1301 formationOperation: model.AssignFormation, 1302 tenantRepo: func() *automock.TenantRepository { 1303 repo := &automock.TenantRepository{} 1304 repo.On("Get", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(gaTenantObject, nil) 1305 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return("", testErr) 1306 return repo 1307 }, 1308 expectedErrMsg: testErr.Error(), 1309 }, 1310 { 1311 name: "Error when getting runtime webhook by ID and type for runtime target", 1312 formationAssignment: faWithSourceAppAndTargetRuntime, 1313 formationOperation: model.AssignFormation, 1314 tenantRepo: func() *automock.TenantRepository { 1315 repo := &automock.TenantRepository{} 1316 repo.On("Get", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(gaTenantObject, nil) 1317 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(TntParentID, nil) 1318 return repo 1319 }, 1320 webhookRepo: func() *automock.WebhookRepository { 1321 webhookRepo := &automock.WebhookRepository{} 1322 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testErr).Once() 1323 return webhookRepo 1324 }, 1325 formationRepo: func() *automock.FormationRepository { 1326 repo := &automock.FormationRepository{} 1327 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1328 return repo 1329 }, 1330 expectedErrMsg: "while getting configuration changed webhook for runtime with ID:", 1331 }, 1332 { 1333 name: "Error when source type is different than application for runtime target", 1334 formationAssignment: faWithSourceInvalidAndTargetRuntime, 1335 formationOperation: model.AssignFormation, 1336 tenantRepo: func() *automock.TenantRepository { 1337 repo := &automock.TenantRepository{} 1338 repo.On("Get", emptyCtx, faWithSourceInvalidAndTargetRuntime.TenantID).Return(gaTenantObject, nil) 1339 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceInvalidAndTargetRuntime.TenantID).Return(TntParentID, nil) 1340 return repo 1341 }, 1342 webhookRepo: func() *automock.WebhookRepository { 1343 webhookRepo := &automock.WebhookRepository{} 1344 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1345 return webhookRepo 1346 }, 1347 formationRepo: func() *automock.FormationRepository { 1348 repo := &automock.FormationRepository{} 1349 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1350 return repo 1351 }, 1352 expectedErrMsg: fmt.Sprintf("The formation assignmet with ID: %q and target type: %q has unsupported reverse(source) type: %q", TestID, model.FormationAssignmentTypeRuntime, model.FormationAssignmentTypeRuntime), 1353 }, 1354 { 1355 name: "Error when preparing app and app template with labels for source type application and runtime target", 1356 formationAssignment: faWithSourceAppAndTargetRuntime, 1357 formationOperation: model.AssignFormation, 1358 tenantRepo: func() *automock.TenantRepository { 1359 repo := &automock.TenantRepository{} 1360 repo.On("Get", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(gaTenantObject, nil) 1361 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(TntParentID, nil) 1362 return repo 1363 }, 1364 webhookRepo: func() *automock.WebhookRepository { 1365 webhookRepo := &automock.WebhookRepository{} 1366 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1367 return webhookRepo 1368 }, 1369 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1370 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1371 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(nil, nil, testErr).Once() 1372 return webhookDataInputBuilder 1373 }, 1374 formationRepo: func() *automock.FormationRepository { 1375 repo := &automock.FormationRepository{} 1376 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1377 return repo 1378 }, 1379 expectedErrMsg: testErr.Error(), 1380 }, 1381 { 1382 name: "Error when preparing runtime with labels for source type application", 1383 formationAssignment: faWithSourceAppAndTargetRuntime, 1384 formationOperation: model.AssignFormation, 1385 tenantRepo: func() *automock.TenantRepository { 1386 repo := &automock.TenantRepository{} 1387 repo.On("Get", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(gaTenantObject, nil) 1388 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(TntParentID, nil) 1389 return repo 1390 }, 1391 webhookRepo: func() *automock.WebhookRepository { 1392 webhookRepo := &automock.WebhookRepository{} 1393 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1394 return webhookRepo 1395 }, 1396 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1397 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1398 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1399 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestTarget).Return(nil, testErr).Once() 1400 return webhookDataInputBuilder 1401 }, 1402 formationRepo: func() *automock.FormationRepository { 1403 repo := &automock.FormationRepository{} 1404 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1405 return repo 1406 }, 1407 expectedErrMsg: testErr.Error(), 1408 }, 1409 { 1410 name: "Error when getting reverse FA by application source and runtime target", 1411 formationAssignment: faWithSourceAppAndTargetRuntime, 1412 formationOperation: model.AssignFormation, 1413 tenantRepo: func() *automock.TenantRepository { 1414 repo := &automock.TenantRepository{} 1415 repo.On("Get", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(gaTenantObject, nil) 1416 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(TntParentID, nil) 1417 return repo 1418 }, 1419 webhookRepo: func() *automock.WebhookRepository { 1420 webhookRepo := &automock.WebhookRepository{} 1421 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1422 return webhookRepo 1423 }, 1424 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1425 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1426 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1427 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeWithLabels, nil).Once() 1428 return webhookDataInputBuilder 1429 }, 1430 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1431 faRepo := &automock.FormationAssignmentRepository{} 1432 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(nil, testErr).Once() 1433 return faRepo 1434 }, 1435 formationRepo: func() *automock.FormationRepository { 1436 repo := &automock.FormationRepository{} 1437 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1438 return repo 1439 }, 1440 expectedErrMsg: testErr.Error(), 1441 }, 1442 { 1443 name: "Error when preparing details for source type application and runtime target", 1444 formationAssignment: faWithSourceAppAndTargetRuntime, 1445 formationOperation: model.AssignFormation, 1446 tenantRepo: func() *automock.TenantRepository { 1447 repo := &automock.TenantRepository{} 1448 repo.On("Get", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(gaTenantObject, nil) 1449 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppAndTargetRuntime.TenantID).Return(TntParentID, nil) 1450 return repo 1451 }, 1452 webhookRepo: func() *automock.WebhookRepository { 1453 webhookRepo := &automock.WebhookRepository{} 1454 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1455 return webhookRepo 1456 }, 1457 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1458 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1459 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1460 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeWithLabels, nil).Once() 1461 return webhookDataInputBuilder 1462 }, 1463 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1464 faRepo := &automock.FormationAssignmentRepository{} 1465 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetRuntimeReverse, nil).Once() 1466 return faRepo 1467 }, 1468 formationRepo: func() *automock.FormationRepository { 1469 repo := &automock.FormationRepository{} 1470 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1471 return repo 1472 }, 1473 notificationBuilder: func() *automock.NotificationBuilder { 1474 notificationsBuilder := &automock.NotificationBuilder{} 1475 1476 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, emptyRuntimeCtx, convertFormationAssignmentFromModel(faWithSourceAppAndTargetRuntime), convertFormationAssignmentFromModel(faWithSourceAppAndTargetRuntimeReverse), model.RuntimeResourceType, testCustomerTenantContext, TestTenantID).Return(nil, testErr).Once() 1477 1478 return notificationsBuilder 1479 }, 1480 expectedErrMsg: testErr.Error(), 1481 }, 1482 { 1483 name: "Error when building notification request for source type application and runtime target", 1484 formationAssignment: faWithSourceAppAndTargetRuntime, 1485 formationOperation: model.AssignFormation, 1486 tenantRepo: func() *automock.TenantRepository { 1487 repo := &automock.TenantRepository{} 1488 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 1489 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 1490 return repo 1491 }, 1492 webhookRepo: func() *automock.WebhookRepository { 1493 webhookRepo := &automock.WebhookRepository{} 1494 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, TestTarget, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1495 return webhookRepo 1496 }, 1497 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1498 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1499 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1500 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeWithLabels, nil).Once() 1501 return webhookDataInputBuilder 1502 }, 1503 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1504 faRepo := &automock.FormationAssignmentRepository{} 1505 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppAndTargetRuntimeReverse, nil).Once() 1506 return faRepo 1507 }, 1508 formationRepo: func() *automock.FormationRepository { 1509 repo := &automock.FormationRepository{} 1510 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1511 return repo 1512 }, 1513 notificationBuilder: func() *automock.NotificationBuilder { 1514 notificationsBuilder := &automock.NotificationBuilder{} 1515 1516 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, emptyRuntimeCtx, convertFormationAssignmentFromModel(faWithSourceAppAndTargetRuntime), convertFormationAssignmentFromModel(faWithSourceAppAndTargetRuntimeReverse), model.RuntimeResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 1517 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testRuntimeWebhook).Return(nil, testErr).Once() 1518 1519 return notificationsBuilder 1520 }, 1521 expectedErrMsg: testErr.Error(), 1522 }, 1523 // runtime context formation assignment notifications with source application 1524 { 1525 name: "Successfully generate runtime context notification when source type is application", 1526 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1527 formationOperation: model.AssignFormation, 1528 tenantRepo: func() *automock.TenantRepository { 1529 repo := &automock.TenantRepository{} 1530 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1531 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(TntParentID, nil) 1532 return repo 1533 }, 1534 webhookRepo: func() *automock.WebhookRepository { 1535 webhookRepo := &automock.WebhookRepository{} 1536 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testRuntimeID, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1537 return webhookRepo 1538 }, 1539 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1540 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1541 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1542 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 1543 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeCtxWithLabels, nil).Once() 1544 return webhookDataInputBuilder 1545 }, 1546 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1547 faRepo := &automock.FormationAssignmentRepository{} 1548 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppCtxAndTargetRtmCtxReverse, nil).Once() 1549 return faRepo 1550 }, 1551 formationRepo: func() *automock.FormationRepository { 1552 repo := &automock.FormationRepository{} 1553 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1554 return repo 1555 }, 1556 notificationBuilder: func() *automock.NotificationBuilder { 1557 notificationsBuilder := &automock.NotificationBuilder{} 1558 1559 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, convertFormationAssignmentFromModel(faWithSourceAppCtxAndTargetRtmCtx), convertFormationAssignmentFromModel(faWithSourceAppCtxAndTargetRtmCtxReverse), model.RuntimeContextResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 1560 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testRuntimeWebhook).Return(testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceAppAndTargetRtmCtx, nil).Once() 1561 1562 return notificationsBuilder 1563 }, 1564 expectedNotification: testAppNotificationReqWithFormationConfigurationChangeTypeWithSourceAppAndTargetRtmCtx, 1565 }, 1566 { 1567 name: "Error when getting tenant fails", 1568 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1569 formationOperation: model.AssignFormation, 1570 tenantRepo: func() *automock.TenantRepository { 1571 repo := &automock.TenantRepository{} 1572 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(nil, testErr) 1573 return repo 1574 }, 1575 expectedErrMsg: testErr.Error(), 1576 }, 1577 { 1578 name: "Error when getting parent customer id fails", 1579 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1580 formationOperation: model.AssignFormation, 1581 tenantRepo: func() *automock.TenantRepository { 1582 repo := &automock.TenantRepository{} 1583 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1584 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return("", testErr) 1585 return repo 1586 }, 1587 expectedErrMsg: testErr.Error(), 1588 }, 1589 { 1590 name: "Error when preparing runtime context with labels for source type application", 1591 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1592 formationOperation: model.AssignFormation, 1593 tenantRepo: func() *automock.TenantRepository { 1594 repo := &automock.TenantRepository{} 1595 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1596 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(TntParentID, nil) 1597 return repo 1598 }, 1599 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1600 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1601 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(nil, testErr).Once() 1602 return webhookDataInputBuilder 1603 }, 1604 formationRepo: func() *automock.FormationRepository { 1605 repo := &automock.FormationRepository{} 1606 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1607 return repo 1608 }, 1609 expectedErrMsg: testErr.Error(), 1610 }, 1611 { 1612 name: "Success when runtime webhook is not found for runtime context target", 1613 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1614 formationOperation: model.AssignFormation, 1615 tenantRepo: func() *automock.TenantRepository { 1616 repo := &automock.TenantRepository{} 1617 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1618 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(TntParentID, nil) 1619 return repo 1620 }, 1621 webhookRepo: func() *automock.WebhookRepository { 1622 webhookRepo := &automock.WebhookRepository{} 1623 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testRuntimeID, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testNotFoundErr).Once() 1624 return webhookRepo 1625 }, 1626 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1627 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1628 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeCtxWithLabels, nil).Once() 1629 return webhookDataInputBuilder 1630 }, 1631 formationRepo: func() *automock.FormationRepository { 1632 repo := &automock.FormationRepository{} 1633 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1634 return repo 1635 }, 1636 }, 1637 { 1638 name: "Error when getting runtime webhook by ID and type for runtime context target", 1639 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1640 formationOperation: model.AssignFormation, 1641 tenantRepo: func() *automock.TenantRepository { 1642 repo := &automock.TenantRepository{} 1643 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1644 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(TntParentID, nil) 1645 return repo 1646 }, 1647 webhookRepo: func() *automock.WebhookRepository { 1648 webhookRepo := &automock.WebhookRepository{} 1649 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testRuntimeID, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(nil, testErr).Once() 1650 return webhookRepo 1651 }, 1652 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1653 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1654 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeCtxWithLabels, nil).Once() 1655 return webhookDataInputBuilder 1656 }, 1657 formationRepo: func() *automock.FormationRepository { 1658 repo := &automock.FormationRepository{} 1659 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1660 return repo 1661 }, 1662 expectedErrMsg: "while getting configuration changed webhook for runtime with ID:", 1663 }, 1664 { 1665 name: "Error when source type is different than application for runtime context target", 1666 formationAssignment: faWithSourceInvalidAndTargetRtmCtx, 1667 formationOperation: model.AssignFormation, 1668 tenantRepo: func() *automock.TenantRepository { 1669 repo := &automock.TenantRepository{} 1670 repo.On("Get", emptyCtx, faWithSourceInvalidAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1671 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceInvalidAndTargetRtmCtx.TenantID).Return(TntParentID, nil) 1672 return repo 1673 }, 1674 webhookRepo: func() *automock.WebhookRepository { 1675 webhookRepo := &automock.WebhookRepository{} 1676 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testRuntimeID, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1677 return webhookRepo 1678 }, 1679 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1680 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1681 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeCtxWithLabels, nil).Once() 1682 return webhookDataInputBuilder 1683 }, 1684 formationRepo: func() *automock.FormationRepository { 1685 repo := &automock.FormationRepository{} 1686 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1687 return repo 1688 }, 1689 expectedErrMsg: fmt.Sprintf("The formation assignmet with ID: %q and target type: %q has unsupported reverse(source) type: %q", TestID, model.FormationAssignmentTypeRuntimeContext, model.FormationAssignmentTypeRuntimeContext), 1690 }, 1691 { 1692 name: "Error when preparing app and app template with labels for source type application and runtime ctx target", 1693 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1694 formationOperation: model.AssignFormation, 1695 tenantRepo: func() *automock.TenantRepository { 1696 repo := &automock.TenantRepository{} 1697 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1698 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(TntParentID, nil) 1699 return repo 1700 }, 1701 webhookRepo: func() *automock.WebhookRepository { 1702 webhookRepo := &automock.WebhookRepository{} 1703 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testRuntimeID, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1704 return webhookRepo 1705 }, 1706 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1707 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1708 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(nil, nil, testErr).Once() 1709 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeCtxWithLabels, nil).Once() 1710 return webhookDataInputBuilder 1711 }, 1712 formationRepo: func() *automock.FormationRepository { 1713 repo := &automock.FormationRepository{} 1714 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1715 return repo 1716 }, 1717 expectedErrMsg: testErr.Error(), 1718 }, 1719 { 1720 name: "Error when preparing runtime with labels for source type application and runtime ctx target", 1721 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1722 formationOperation: model.AssignFormation, 1723 tenantRepo: func() *automock.TenantRepository { 1724 repo := &automock.TenantRepository{} 1725 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1726 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(TntParentID, nil) 1727 return repo 1728 }, 1729 webhookRepo: func() *automock.WebhookRepository { 1730 webhookRepo := &automock.WebhookRepository{} 1731 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testRuntimeID, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1732 return webhookRepo 1733 }, 1734 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1735 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1736 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1737 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(nil, testErr).Once() 1738 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeCtxWithLabels, nil).Once() 1739 return webhookDataInputBuilder 1740 }, 1741 formationRepo: func() *automock.FormationRepository { 1742 repo := &automock.FormationRepository{} 1743 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1744 return repo 1745 }, 1746 expectedErrMsg: testErr.Error(), 1747 }, 1748 { 1749 name: "Error when getting reverse FA by app source and runtime context target", 1750 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1751 formationOperation: model.AssignFormation, 1752 tenantRepo: func() *automock.TenantRepository { 1753 repo := &automock.TenantRepository{} 1754 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1755 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(TntParentID, nil) 1756 return repo 1757 }, 1758 webhookRepo: func() *automock.WebhookRepository { 1759 webhookRepo := &automock.WebhookRepository{} 1760 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testRuntimeID, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1761 return webhookRepo 1762 }, 1763 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1764 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1765 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1766 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 1767 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeCtxWithLabels, nil).Once() 1768 return webhookDataInputBuilder 1769 }, 1770 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1771 faRepo := &automock.FormationAssignmentRepository{} 1772 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(nil, testErr).Once() 1773 return faRepo 1774 }, 1775 formationRepo: func() *automock.FormationRepository { 1776 repo := &automock.FormationRepository{} 1777 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1778 return repo 1779 }, 1780 expectedErrMsg: testErr.Error(), 1781 }, 1782 { 1783 name: "Error when building details source type application and runtime context target", 1784 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1785 formationOperation: model.AssignFormation, 1786 tenantRepo: func() *automock.TenantRepository { 1787 repo := &automock.TenantRepository{} 1788 repo.On("Get", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(gaTenantObject, nil) 1789 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceAppCtxAndTargetRtmCtx.TenantID).Return(TntParentID, nil) 1790 return repo 1791 }, 1792 webhookRepo: func() *automock.WebhookRepository { 1793 webhookRepo := &automock.WebhookRepository{} 1794 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testRuntimeID, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1795 return webhookRepo 1796 }, 1797 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1798 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1799 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1800 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 1801 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeCtxWithLabels, nil).Once() 1802 return webhookDataInputBuilder 1803 }, 1804 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1805 faRepo := &automock.FormationAssignmentRepository{} 1806 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppCtxAndTargetRtmCtxReverse, nil).Once() 1807 return faRepo 1808 }, 1809 formationRepo: func() *automock.FormationRepository { 1810 repo := &automock.FormationRepository{} 1811 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1812 return repo 1813 }, 1814 notificationBuilder: func() *automock.NotificationBuilder { 1815 notificationsBuilder := &automock.NotificationBuilder{} 1816 1817 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, convertFormationAssignmentFromModel(faWithSourceAppCtxAndTargetRtmCtx), convertFormationAssignmentFromModel(faWithSourceAppCtxAndTargetRtmCtxReverse), model.RuntimeContextResourceType, testCustomerTenantContext, TestTenantID).Return(nil, testErr).Once() 1818 1819 return notificationsBuilder 1820 }, 1821 expectedErrMsg: testErr.Error(), 1822 }, 1823 { 1824 name: "Error when building notification request for source type application and runtime context target", 1825 formationAssignment: faWithSourceAppCtxAndTargetRtmCtx, 1826 formationOperation: model.AssignFormation, 1827 tenantRepo: func() *automock.TenantRepository { 1828 repo := &automock.TenantRepository{} 1829 repo.On("Get", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(gaTenantObject, nil) 1830 repo.On("GetCustomerIDParentRecursively", emptyCtx, faWithSourceRuntimeAndTargetApp.TenantID).Return(TntParentID, nil) 1831 return repo 1832 }, 1833 webhookRepo: func() *automock.WebhookRepository { 1834 webhookRepo := &automock.WebhookRepository{} 1835 webhookRepo.On("GetByIDAndWebhookType", emptyCtx, TestTenantID, testRuntimeID, model.RuntimeWebhookReference, model.WebhookTypeConfigurationChanged).Return(testRuntimeWebhook, nil).Once() 1836 return webhookRepo 1837 }, 1838 webhookDataInputBuilder: func() *databuilderautomock.DataInputBuilder { 1839 webhookDataInputBuilder := &databuilderautomock.DataInputBuilder{} 1840 webhookDataInputBuilder.On("PrepareApplicationAndAppTemplateWithLabels", emptyCtx, TestTenantID, TestSource).Return(testAppWithLabels, testAppTemplateWithLabels, nil).Once() 1841 webhookDataInputBuilder.On("PrepareRuntimeWithLabels", emptyCtx, TestTenantID, testRuntimeID).Return(testRuntimeWithLabels, nil).Once() 1842 webhookDataInputBuilder.On("PrepareRuntimeContextWithLabels", emptyCtx, TestTenantID, TestTarget).Return(testRuntimeCtxWithLabels, nil).Once() 1843 return webhookDataInputBuilder 1844 }, 1845 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1846 faRepo := &automock.FormationAssignmentRepository{} 1847 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(faWithSourceAppCtxAndTargetRtmCtxReverse, nil).Once() 1848 return faRepo 1849 }, 1850 formationRepo: func() *automock.FormationRepository { 1851 repo := &automock.FormationRepository{} 1852 repo.On("Get", ctx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1853 return repo 1854 }, 1855 notificationBuilder: func() *automock.NotificationBuilder { 1856 notificationsBuilder := &automock.NotificationBuilder{} 1857 1858 notificationsBuilder.On("PrepareDetailsForConfigurationChangeNotificationGeneration", model.AssignFormation, TestFormationID, TestFormationTemplateID, testAppTemplateWithLabels, testAppWithLabels, testRuntimeWithLabels, testRuntimeCtxWithLabels, convertFormationAssignmentFromModel(faWithSourceAppCtxAndTargetRtmCtx), convertFormationAssignmentFromModel(faWithSourceAppCtxAndTargetRtmCtxReverse), model.RuntimeContextResourceType, testCustomerTenantContext, TestTenantID).Return(details, nil).Once() 1859 notificationsBuilder.On("BuildFormationAssignmentNotificationRequest", ctx, TestFormationTemplateID, details, testRuntimeWebhook).Return(nil, testErr).Once() 1860 1861 return notificationsBuilder 1862 }, 1863 expectedErrMsg: testErr.Error(), 1864 }, 1865 } 1866 1867 for _, tCase := range testCases { 1868 t.Run(tCase.name, func(t *testing.T) { 1869 // GIVEN 1870 faRepo := unusedFormationAssignmentRepository() 1871 if tCase.formationAssignmentRepo != nil { 1872 faRepo = tCase.formationAssignmentRepo() 1873 } 1874 1875 webhookRepo := unusedWebhookRepo() 1876 if tCase.webhookRepo != nil { 1877 webhookRepo = tCase.webhookRepo() 1878 } 1879 1880 tenantRepo := unusedTenantRepo() 1881 if tCase.tenantRepo != nil { 1882 tenantRepo = tCase.tenantRepo() 1883 } 1884 1885 webhookDataInputBuilder := unusedWebhookDataInputBuilder() 1886 if tCase.webhookDataInputBuilder != nil { 1887 webhookDataInputBuilder = tCase.webhookDataInputBuilder() 1888 } 1889 1890 formationRepo := unusedFormationRepo() 1891 if tCase.formationRepo != nil { 1892 formationRepo = tCase.formationRepo() 1893 } 1894 1895 notificationBuilder := unusedNotificationBuilder() 1896 if tCase.notificationBuilder != nil { 1897 notificationBuilder = tCase.notificationBuilder() 1898 } 1899 1900 defer mock.AssertExpectationsForObjects(t, faRepo, webhookRepo, webhookDataInputBuilder, formationRepo, notificationBuilder) 1901 1902 faNotificationSvc := formationassignment.NewFormationAssignmentNotificationService(faRepo, nil, webhookRepo, tenantRepo, webhookDataInputBuilder, formationRepo, notificationBuilder, nil, nil, "", "") 1903 defer mock.AssertExpectationsForObjects(t, faRepo, webhookRepo, tenantRepo, webhookDataInputBuilder) 1904 1905 // WHEN 1906 notificationReq, err := faNotificationSvc.GenerateFormationAssignmentNotification(emptyCtx, tCase.formationAssignment, tCase.formationOperation) 1907 1908 // THEN 1909 if tCase.expectedErrMsg != "" { 1910 require.Error(t, err) 1911 require.Contains(t, err.Error(), tCase.expectedErrMsg) 1912 require.Nil(t, tCase.expectedNotification) 1913 } else { 1914 require.NoError(t, err) 1915 require.Equal(t, tCase.expectedNotification, notificationReq) 1916 } 1917 }) 1918 } 1919 } 1920 1921 func Test_PrepareDetailsForNotificationStatusReturned(t *testing.T) { 1922 emptyCtx = context.TODO() 1923 1924 faWithTargetTypeApplication := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeApplication, model.FormationAssignmentTypeApplication, string(model.ReadyAssignmentState), nil) 1925 reverseFaWithTargetTypeApplication := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestTarget, TestSource, model.FormationAssignmentTypeApplication, model.FormationAssignmentTypeApplication, string(model.ReadyAssignmentState), nil) 1926 1927 faWithTargetTypeRuntime := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeRuntime, model.FormationAssignmentTypeRuntime, string(model.ReadyAssignmentState), nil) 1928 reverseFaWithTargetTypeRuntime := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestTarget, TestSource, model.FormationAssignmentTypeRuntime, model.FormationAssignmentTypeRuntime, string(model.ReadyAssignmentState), nil) 1929 1930 faWithTargetTypeRuntimeCtx := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestSource, TestTarget, model.FormationAssignmentTypeRuntimeContext, model.FormationAssignmentTypeRuntimeContext, string(model.ReadyAssignmentState), nil) 1931 reverseFaWithTargetTypeRuntimeCtx := fixFormationAssignmentModelWithParameters(TestID, TestFormationID, TestTenantID, TestTarget, TestSource, model.FormationAssignmentTypeRuntimeContext, model.FormationAssignmentTypeRuntimeContext, string(model.ReadyAssignmentState), nil) 1932 1933 runtimeLabelInput := &model.LabelInput{ 1934 Key: rtmTypeLabelKey, 1935 ObjectID: TestTarget, 1936 ObjectType: model.RuntimeLabelableObject, 1937 } 1938 1939 expectedDetailsForApp := fixNotificationStatusReturnedDetails(model.ApplicationResourceType, appSubtype, faWithTargetTypeApplication, reverseFaWithTargetTypeApplication, formationconstraint.JoinPointLocation{}) 1940 1941 testCases := []struct { 1942 name string 1943 formationAssignment *model.FormationAssignment 1944 formationAssignmentRepo func() *automock.FormationAssignmentRepository 1945 formationRepo func() *automock.FormationRepository 1946 labelSvc func() *automock.LabelService 1947 runtimeCtxRepo func() *automock.RuntimeContextRepository 1948 expectedDetails *formationconstraint.NotificationStatusReturnedOperationDetails 1949 expectedErrMsg string 1950 }{ 1951 { 1952 name: "Success for FA with target type application", 1953 formationAssignment: faWithTargetTypeApplication, 1954 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1955 faRepo := &automock.FormationAssignmentRepository{} 1956 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(reverseFaWithTargetTypeApplication, nil).Once() 1957 return faRepo 1958 }, 1959 formationRepo: func() *automock.FormationRepository { 1960 formationRepo := &automock.FormationRepository{} 1961 formationRepo.On("Get", emptyCtx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1962 return formationRepo 1963 }, 1964 labelSvc: func() *automock.LabelService { 1965 lblSvc := &automock.LabelService{} 1966 lblSvc.On("GetLabel", emptyCtx, TestTenantID, applicationLabelInput).Return(applicationTypeLabel, nil).Once() 1967 return lblSvc 1968 }, 1969 expectedDetails: expectedDetailsForApp, 1970 }, 1971 { 1972 name: "Success for FA with target type runtime", 1973 formationAssignment: faWithTargetTypeRuntime, 1974 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1975 faRepo := &automock.FormationAssignmentRepository{} 1976 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(reverseFaWithTargetTypeRuntime, nil).Once() 1977 return faRepo 1978 }, 1979 formationRepo: func() *automock.FormationRepository { 1980 formationRepo := &automock.FormationRepository{} 1981 formationRepo.On("Get", emptyCtx, TestFormationID, TestTenantID).Return(formation, nil).Once() 1982 return formationRepo 1983 }, 1984 labelSvc: func() *automock.LabelService { 1985 lblSvc := &automock.LabelService{} 1986 lblSvc.On("GetLabel", emptyCtx, TestTenantID, runtimeLabelInput).Return(runtimeTypeLabel, nil).Once() 1987 return lblSvc 1988 }, 1989 expectedDetails: fixNotificationStatusReturnedDetails(model.RuntimeResourceType, rtmSubtype, faWithTargetTypeRuntime, reverseFaWithTargetTypeRuntime, formationconstraint.JoinPointLocation{}), 1990 }, 1991 { 1992 name: "Success for FA with target type runtime context", 1993 formationAssignment: faWithTargetTypeRuntimeCtx, 1994 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 1995 faRepo := &automock.FormationAssignmentRepository{} 1996 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(reverseFaWithTargetTypeRuntimeCtx, nil).Once() 1997 return faRepo 1998 }, 1999 formationRepo: func() *automock.FormationRepository { 2000 formationRepo := &automock.FormationRepository{} 2001 formationRepo.On("Get", emptyCtx, TestFormationID, TestTenantID).Return(formation, nil).Once() 2002 return formationRepo 2003 }, 2004 labelSvc: func() *automock.LabelService { 2005 lblSvc := &automock.LabelService{} 2006 lblSvc.On("GetLabel", emptyCtx, TestTenantID, runtimeLabelInput).Return(runtimeTypeLabel, nil).Once() 2007 return lblSvc 2008 }, 2009 runtimeCtxRepo: func() *automock.RuntimeContextRepository { 2010 rtmCtxRepo := &automock.RuntimeContextRepository{} 2011 rtmCtxRepo.On("GetByID", emptyCtx, TestTenantID, TestTarget).Return(&model.RuntimeContext{RuntimeID: TestTarget}, nil).Once() 2012 return rtmCtxRepo 2013 }, 2014 expectedDetails: fixNotificationStatusReturnedDetails(model.RuntimeContextResourceType, rtmSubtype, faWithTargetTypeRuntimeCtx, reverseFaWithTargetTypeRuntimeCtx, formationconstraint.JoinPointLocation{}), 2015 }, 2016 { 2017 name: "Success for application when there is no reverse fa", 2018 formationAssignment: faWithTargetTypeApplication, 2019 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 2020 faRepo := &automock.FormationAssignmentRepository{} 2021 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(nil, notFoundError).Once() 2022 return faRepo 2023 }, 2024 formationRepo: func() *automock.FormationRepository { 2025 formationRepo := &automock.FormationRepository{} 2026 formationRepo.On("Get", emptyCtx, TestFormationID, TestTenantID).Return(formation, nil).Once() 2027 return formationRepo 2028 }, 2029 labelSvc: func() *automock.LabelService { 2030 lblSvc := &automock.LabelService{} 2031 lblSvc.On("GetLabel", emptyCtx, TestTenantID, applicationLabelInput).Return(applicationTypeLabel, nil).Once() 2032 return lblSvc 2033 }, 2034 expectedDetails: fixNotificationStatusReturnedDetails(model.ApplicationResourceType, appSubtype, faWithTargetTypeApplication, nil, formationconstraint.JoinPointLocation{}), 2035 }, 2036 { 2037 name: "Error when can't get reverse fa", 2038 formationAssignment: faWithTargetTypeApplication, 2039 formationAssignmentRepo: func() *automock.FormationAssignmentRepository { 2040 faRepo := &automock.FormationAssignmentRepository{} 2041 faRepo.On("GetReverseBySourceAndTarget", emptyCtx, TestTenantID, TestFormationID, TestSource, TestTarget).Return(nil, testErr).Once() 2042 return faRepo 2043 }, 2044 formationRepo: func() *automock.FormationRepository { 2045 formationRepo := &automock.FormationRepository{} 2046 formationRepo.On("Get", emptyCtx, TestFormationID, TestTenantID).Return(formation, nil).Once() 2047 return formationRepo 2048 }, 2049 labelSvc: func() *automock.LabelService { 2050 lblSvc := &automock.LabelService{} 2051 lblSvc.On("GetLabel", emptyCtx, TestTenantID, applicationLabelInput).Return(applicationTypeLabel, nil).Once() 2052 return lblSvc 2053 }, 2054 expectedErrMsg: testErr.Error(), 2055 }, 2056 { 2057 name: "Error when can't get formation", 2058 formationAssignment: faWithTargetTypeApplication, 2059 formationRepo: func() *automock.FormationRepository { 2060 formationRepo := &automock.FormationRepository{} 2061 formationRepo.On("Get", emptyCtx, TestFormationID, TestTenantID).Return(nil, testErr).Once() 2062 return formationRepo 2063 }, 2064 labelSvc: func() *automock.LabelService { 2065 lblSvc := &automock.LabelService{} 2066 lblSvc.On("GetLabel", emptyCtx, TestTenantID, applicationLabelInput).Return(applicationTypeLabel, nil).Once() 2067 return lblSvc 2068 }, 2069 expectedErrMsg: testErr.Error(), 2070 }, 2071 { 2072 name: "Error when can't get application label", 2073 formationAssignment: faWithTargetTypeApplication, 2074 labelSvc: func() *automock.LabelService { 2075 lblSvc := &automock.LabelService{} 2076 lblSvc.On("GetLabel", emptyCtx, TestTenantID, applicationLabelInput).Return(nil, testErr).Once() 2077 return lblSvc 2078 }, 2079 expectedErrMsg: testErr.Error(), 2080 }, 2081 { 2082 name: "Error when can't get runtime label when target type is runtime", 2083 formationAssignment: faWithTargetTypeRuntime, 2084 labelSvc: func() *automock.LabelService { 2085 lblSvc := &automock.LabelService{} 2086 lblSvc.On("GetLabel", emptyCtx, TestTenantID, runtimeLabelInput).Return(nil, testErr).Once() 2087 return lblSvc 2088 }, 2089 expectedErrMsg: testErr.Error(), 2090 }, 2091 { 2092 name: "Error when can't get runtime label when target type is runtime context", 2093 formationAssignment: faWithTargetTypeRuntimeCtx, 2094 labelSvc: func() *automock.LabelService { 2095 lblSvc := &automock.LabelService{} 2096 lblSvc.On("GetLabel", emptyCtx, TestTenantID, runtimeLabelInput).Return(nil, testErr).Once() 2097 return lblSvc 2098 }, 2099 runtimeCtxRepo: func() *automock.RuntimeContextRepository { 2100 rtmCtxRepo := &automock.RuntimeContextRepository{} 2101 rtmCtxRepo.On("GetByID", emptyCtx, TestTenantID, TestTarget).Return(&model.RuntimeContext{RuntimeID: TestTarget}, nil).Once() 2102 return rtmCtxRepo 2103 }, 2104 expectedErrMsg: testErr.Error(), 2105 }, 2106 { 2107 name: "Error when can't get runtime context", 2108 formationAssignment: faWithTargetTypeRuntimeCtx, 2109 runtimeCtxRepo: func() *automock.RuntimeContextRepository { 2110 rtmCtxRepo := &automock.RuntimeContextRepository{} 2111 rtmCtxRepo.On("GetByID", emptyCtx, TestTenantID, TestTarget).Return(nil, testErr).Once() 2112 return rtmCtxRepo 2113 }, 2114 expectedErrMsg: testErr.Error(), 2115 }, 2116 { 2117 name: "Error when the object type is unknown", 2118 formationAssignment: &model.FormationAssignment{TargetType: "unknown"}, 2119 expectedErrMsg: fmt.Sprintf("unknown object type %q", "unknown"), 2120 }, 2121 } 2122 2123 for _, tCase := range testCases { 2124 t.Run(tCase.name, func(t *testing.T) { 2125 // GIVEN 2126 faRepo := unusedFormationAssignmentRepository() 2127 if tCase.formationAssignmentRepo != nil { 2128 faRepo = tCase.formationAssignmentRepo() 2129 } 2130 formationRepo := unusedFormationRepo() 2131 if tCase.formationRepo != nil { 2132 formationRepo = tCase.formationRepo() 2133 } 2134 labelSvc := &automock.LabelService{} 2135 if tCase.labelSvc != nil { 2136 labelSvc = tCase.labelSvc() 2137 } 2138 rtmCtxSvc := &automock.RuntimeContextRepository{} 2139 if tCase.runtimeCtxRepo != nil { 2140 rtmCtxSvc = tCase.runtimeCtxRepo() 2141 } 2142 2143 defer mock.AssertExpectationsForObjects(t, faRepo, formationRepo, labelSvc, rtmCtxSvc) 2144 2145 faNotificationSvc := formationassignment.NewFormationAssignmentNotificationService(faRepo, nil, nil, nil, nil, formationRepo, nil, rtmCtxSvc, labelSvc, rtmTypeLabelKey, appTypeLabelKey) 2146 2147 // WHEN 2148 notificationReq, err := faNotificationSvc.PrepareDetailsForNotificationStatusReturned(emptyCtx, TestTenantID, tCase.formationAssignment, model.AssignFormation) 2149 2150 // THEN 2151 if tCase.expectedErrMsg != "" { 2152 require.Error(t, err) 2153 require.Contains(t, err.Error(), tCase.expectedErrMsg) 2154 require.Nil(t, tCase.expectedDetails) 2155 } else { 2156 require.NoError(t, err) 2157 require.Equal(t, tCase.expectedDetails, notificationReq) 2158 } 2159 }) 2160 } 2161 } 2162 2163 func Test_GenerateFormationAssignmentNotificationExt(t *testing.T) { 2164 faRequestMapping := &formationassignment.FormationAssignmentRequestMapping{ 2165 Request: testAppNotificationReqWithTenantMappingType, 2166 FormationAssignment: faWithSourceAppAndTargetApp, 2167 } 2168 reverseFaRequestMapping := &formationassignment.FormationAssignmentRequestMapping{ 2169 Request: testAppNotificationReqWithTenantMappingType, 2170 FormationAssignment: faWithSourceAppAndTargetAppReverse, 2171 } 2172 2173 expectedExtNotificationReq := &webhookclient.FormationAssignmentNotificationRequestExt{ 2174 FormationAssignmentNotificationRequest: faRequestMapping.Request, 2175 Operation: model.AssignFormation, 2176 FormationAssignment: faWithSourceAppAndTargetApp, 2177 ReverseFormationAssignment: faWithSourceAppAndTargetAppReverse, 2178 Formation: formation, 2179 TargetSubtype: appSubtype, 2180 } 2181 2182 var testCases = []struct { 2183 name string 2184 faRequestMapping *formationassignment.FormationAssignmentRequestMapping 2185 reverseFaRequestMapping *formationassignment.FormationAssignmentRequestMapping 2186 formationRepo func() *automock.FormationRepository 2187 labelSvc func() *automock.LabelService 2188 expectedExtNotificationReq *webhookclient.FormationAssignmentNotificationRequestExt 2189 expectedErrMsg string 2190 }{ 2191 { 2192 name: "Success", 2193 faRequestMapping: faRequestMapping, 2194 reverseFaRequestMapping: reverseFaRequestMapping, 2195 formationRepo: func() *automock.FormationRepository { 2196 formationRepo := &automock.FormationRepository{} 2197 formationRepo.On("Get", emptyCtx, TestFormationID, TestTenantID).Return(formation, nil).Once() 2198 return formationRepo 2199 }, 2200 labelSvc: func() *automock.LabelService { 2201 lblSvc := &automock.LabelService{} 2202 lblSvc.On("GetLabel", emptyCtx, TestTenantID, applicationLabelInput).Return(applicationTypeLabel, nil).Once() 2203 return lblSvc 2204 }, 2205 expectedExtNotificationReq: expectedExtNotificationReq, 2206 }, 2207 { 2208 name: "Success when there is no reverse fa", 2209 faRequestMapping: faRequestMapping, 2210 formationRepo: func() *automock.FormationRepository { 2211 formationRepo := &automock.FormationRepository{} 2212 formationRepo.On("Get", emptyCtx, TestFormationID, TestTenantID).Return(formation, nil).Once() 2213 return formationRepo 2214 }, 2215 labelSvc: func() *automock.LabelService { 2216 lblSvc := &automock.LabelService{} 2217 lblSvc.On("GetLabel", emptyCtx, TestTenantID, applicationLabelInput).Return(applicationTypeLabel, nil).Once() 2218 return lblSvc 2219 }, 2220 expectedExtNotificationReq: &webhookclient.FormationAssignmentNotificationRequestExt{ 2221 FormationAssignmentNotificationRequest: faRequestMapping.Request, 2222 Operation: model.AssignFormation, 2223 FormationAssignment: faWithSourceAppAndTargetApp, 2224 ReverseFormationAssignment: nil, 2225 Formation: formation, 2226 TargetSubtype: appSubtype, 2227 }, 2228 }, 2229 { 2230 name: "Returns error when can't get formation", 2231 faRequestMapping: faRequestMapping, 2232 reverseFaRequestMapping: reverseFaRequestMapping, 2233 formationRepo: func() *automock.FormationRepository { 2234 formationRepo := &automock.FormationRepository{} 2235 formationRepo.On("Get", emptyCtx, TestFormationID, TestTenantID).Return(nil, testErr).Once() 2236 return formationRepo 2237 }, 2238 labelSvc: func() *automock.LabelService { 2239 lblSvc := &automock.LabelService{} 2240 lblSvc.On("GetLabel", emptyCtx, TestTenantID, applicationLabelInput).Return(applicationTypeLabel, nil).Once() 2241 return lblSvc 2242 }, 2243 expectedErrMsg: testErr.Error(), 2244 }, 2245 { 2246 name: "Returns error when can't get subtype", 2247 faRequestMapping: faRequestMapping, 2248 reverseFaRequestMapping: reverseFaRequestMapping, 2249 labelSvc: func() *automock.LabelService { 2250 lblSvc := &automock.LabelService{} 2251 lblSvc.On("GetLabel", emptyCtx, TestTenantID, applicationLabelInput).Return(nil, testErr).Once() 2252 return lblSvc 2253 }, 2254 expectedErrMsg: testErr.Error(), 2255 }, 2256 } 2257 for _, tCase := range testCases { 2258 t.Run(tCase.name, func(t *testing.T) { 2259 // GIVEN 2260 formationRepo := unusedFormationRepo() 2261 if tCase.formationRepo != nil { 2262 formationRepo = tCase.formationRepo() 2263 } 2264 labelSvc := &automock.LabelService{} 2265 if tCase.labelSvc != nil { 2266 labelSvc = tCase.labelSvc() 2267 } 2268 2269 defer mock.AssertExpectationsForObjects(t, formationRepo, labelSvc) 2270 2271 faNotificationSvc := formationassignment.NewFormationAssignmentNotificationService(nil, nil, nil, nil, nil, formationRepo, nil, nil, labelSvc, rtmTypeLabelKey, appTypeLabelKey) 2272 2273 // WHEN 2274 extNotificationRequest, err := faNotificationSvc.GenerateFormationAssignmentNotificationExt(emptyCtx, tCase.faRequestMapping, tCase.reverseFaRequestMapping, model.AssignFormation) 2275 2276 // THEN 2277 if tCase.expectedErrMsg != "" { 2278 require.Error(t, err) 2279 require.Contains(t, err.Error(), tCase.expectedErrMsg) 2280 require.Nil(t, tCase.expectedExtNotificationReq) 2281 } else { 2282 require.NoError(t, err) 2283 require.Equal(t, tCase.expectedExtNotificationReq, extNotificationRequest) 2284 } 2285 }) 2286 } 2287 }