github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/formation/fixtures_test.go (about)

     1  package formation_test
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"net/http"
     8  	"testing"
     9  	"time"
    10  
    11  	dataloader "github.com/kyma-incubator/compass/components/director/internal/dataloaders"
    12  
    13  	"github.com/kyma-incubator/compass/components/director/internal/domain/formationassignment"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/kyma-incubator/compass/components/director/internal/repo"
    17  
    18  	"github.com/kyma-incubator/compass/components/director/internal/domain/formation"
    19  	"github.com/kyma-incubator/compass/components/director/internal/domain/formation/automock"
    20  	"github.com/kyma-incubator/compass/components/director/internal/domain/tenant"
    21  	databuilderautomock "github.com/kyma-incubator/compass/components/director/internal/domain/webhook/datainputbuilder/automock"
    22  	"github.com/kyma-incubator/compass/components/director/internal/labelfilter"
    23  	"github.com/kyma-incubator/compass/components/director/pkg/formationconstraint"
    24  	"github.com/kyma-incubator/compass/components/director/pkg/pagination"
    25  	"github.com/kyma-incubator/compass/components/director/pkg/str"
    26  	"github.com/kyma-incubator/compass/components/director/pkg/webhook"
    27  	webhookclient "github.com/kyma-incubator/compass/components/director/pkg/webhook_client"
    28  	"github.com/pkg/errors"
    29  	"github.com/stretchr/testify/mock"
    30  
    31  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    32  	tnt "github.com/kyma-incubator/compass/components/director/pkg/tenant"
    33  
    34  	"github.com/google/uuid"
    35  	"github.com/kyma-incubator/compass/components/director/internal/model"
    36  )
    37  
    38  const (
    39  	// Tenant IDs
    40  	TntInternalID = "953ac686-5773-4ad0-8eb1-2349e931f852"
    41  	TntExternalID = "ada4241d-caa1-4ee4-b8bf-f733e180fbf9"
    42  	TntCustomerID = "ede0241d-caa1-4ee4-b8bf-f733e180fbf9"
    43  
    44  	// Automatic Scenario Assignment(ASA) constants
    45  	TargetTenantID  = "targetTenantID-ASA"
    46  	TargetTenantID2 = "targetTenantID2-ASA"
    47  	TenantID2       = "18271026-3998-4391-be58-b783a09fcca8" // used as tenant where the ASA "lives"
    48  	ScenarioName    = "scenario-A"
    49  	ScenarioName2   = "scenario-B"
    50  
    51  	// Entity constants
    52  	ApplicationID           = "04f3568d-3e0c-4f6b-b646-e6979e9d060c"
    53  	Application2ID          = "6f5389cf-4f9e-46b3-9870-624d792d94ad"
    54  	ApplicationTemplateID   = "58963c6f-24f6-4128-a05c-51d5356e7e09"
    55  	ApplicationTemplate2ID  = "88963c6f-24f6-4128-a05c-51d5356e7e09"
    56  	RuntimeID               = "rt-id"
    57  	RuntimeContextRuntimeID = "rt-ctx-rt-id"
    58  	RuntimeContextID        = "rt-ctx-id"
    59  	RuntimeContext2ID       = "rt-ctx-id-2"
    60  	FormationID             = "cf7e396b-ee70-4a47-9aff-9fa9bfa466c1"
    61  
    62  	// Webhook IDs
    63  	WebhookID  = "b5a62a7d-6805-43f9-a3be-370d2d125f0f"
    64  	Webhook2ID = "b9a62a7d-6805-43f9-a3be-370d2d125f0f"
    65  	Webhook3ID = "aaa62a7d-6805-43f9-a3be-370d2d125f0f"
    66  	Webhook4ID = "43fa5d0b-b037-478d-919a-2f0431feedd4"
    67  
    68  	TntParentID                      = "ede0241d-caa1-4ee4-b8bf-f733e180fbf9"
    69  	WebhookForRuntimeContextID       = "5202f196-46d7-4d1e-be50-434dd9fcd157"
    70  	AppTenantMappingWebhookIDForApp1 = "b91e7d97-65ed-4b72-a225-4a3b484c27e1"
    71  	AppTenantMappingWebhookIDForApp2 = "df7e9387-7bdf-46bb-b0c2-de5ec9a40a21"
    72  	FormationLifecycleWebhookID      = "517e0235-0d74-4166-a47c-5a577022d468"
    73  
    74  	// Formation constants
    75  	testFormationName       = "test-formation"
    76  	testFormationState      = string(model.InitialFormationState)
    77  	testFormationEmptyError = "{}"
    78  	secondTestFormationName = "second-formation"
    79  	TargetTenant            = "targetTenant" // used as "assigning tenant" in formation scenarios/flows
    80  
    81  	// Formation Template constants
    82  	FormationTemplateID       = "bda5378d-caa1-4ee4-b8bf-f733e180fbf9"
    83  	testFormationTemplateName = "test-formation-template-name"
    84  
    85  	// Formation Assignment constants
    86  	FormationAssignmentID          = "FormationAssignmentID"
    87  	FormationAssignmentFormationID = "FormationAssignmentFormationID"
    88  	FormationAssignmentTenantID    = "FormationAssignmentTenantID"
    89  	FormationAssignmentSource      = "FormationAssignmentSource"
    90  	FormationAssignmentSourceType  = "FormationAssignmentSourceType"
    91  	FormationAssignmentTarget      = "FormationAssignmentTarget"
    92  	FormationAssignmentTargetType  = "FormationAssignmentTargetType"
    93  	FormationAssignmentState       = "FormationAssignmentState"
    94  
    95  	// Other constants
    96  	ErrMsg          = "some error"
    97  	runtimeType     = "runtimeType"
    98  	applicationType = "applicationType"
    99  	testProvider    = "Compass"
   100  )
   101  
   102  var (
   103  	tenantID               = uuid.New()
   104  	externalTenantID       = uuid.New()
   105  	nilFormationModel      *model.Formation
   106  	runtimeTypeDisplayName = str.Ptr("display name")
   107  
   108  	testErr = errors.New("Test error")
   109  
   110  	CustomerTenantContextPath = &webhook.CustomerTenantContext{
   111  		CustomerID: TntCustomerID,
   112  		AccountID:  nil,
   113  		Path:       str.Ptr(TntExternalID),
   114  	}
   115  
   116  	CustomerTenantContextAccount = fixCustomerTenantContext(TntCustomerID, TntExternalID)
   117  
   118  	modelFormation = model.Formation{
   119  		ID:                  FormationID,
   120  		FormationTemplateID: FormationTemplateID,
   121  		Name:                testFormationName,
   122  	}
   123  	graphqlFormation = graphql.Formation{
   124  		ID:                  FormationID,
   125  		FormationTemplateID: FormationTemplateID,
   126  		Name:                testFormationName,
   127  	}
   128  	testScenario = "test-scenario"
   129  
   130  	subscriptionRuntimeArtifactKind = model.RuntimeArtifactKindSubscription
   131  	formationTemplate               = model.FormationTemplate{
   132  		ID:                     FormationTemplateID,
   133  		RuntimeArtifactKind:    &subscriptionRuntimeArtifactKind,
   134  		RuntimeTypeDisplayName: runtimeTypeDisplayName,
   135  		Name:                   testFormationTemplateName,
   136  		RuntimeTypes:           []string{runtimeType},
   137  	}
   138  	runtimeLblFilters = []*labelfilter.LabelFilter{labelfilter.NewForKeyWithQuery("runtimeType", fmt.Sprintf(`$[*] ? (@ == "%s")`, runtimeType))}
   139  
   140  	TestConfigValueRawJSON = json.RawMessage(
   141  		`{"configKey":"configValue"}`,
   142  	)
   143  	TestConfigValueStr = "{\"configKey\":\"configValue\"}"
   144  
   145  	emptyFormationAssignment = &webhook.FormationAssignment{Value: "\"\""}
   146  
   147  	// Formation assignment notification variables
   148  	runtimeCtxNotificationWithAppTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   149  		Webhook: *fixRuntimeWebhookGQLModel(WebhookID, RuntimeContextRuntimeID),
   150  		Object: &webhook.FormationConfigurationChangeInput{
   151  			Operation:   model.AssignFormation,
   152  			FormationID: fixUUID(),
   153  			ApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   154  				ApplicationTemplate: fixApplicationTemplateModel(),
   155  				Labels:              fixApplicationTemplateLabelsMap(),
   156  			},
   157  			Application: &webhook.ApplicationWithLabels{
   158  				Application: fixApplicationModel(ApplicationID),
   159  				Labels:      fixApplicationLabelsMap(),
   160  			},
   161  			Runtime: &webhook.RuntimeWithLabels{
   162  				Runtime: fixRuntimeModel(RuntimeContextRuntimeID),
   163  				Labels:  fixRuntimeLabelsMap(),
   164  			},
   165  			RuntimeContext: &webhook.RuntimeContextWithLabels{
   166  				RuntimeContext: fixRuntimeContextModel(),
   167  				Labels:         fixRuntimeContextLabelsMap(),
   168  			},
   169  			Assignment:        emptyFormationAssignment,
   170  			ReverseAssignment: emptyFormationAssignment,
   171  		},
   172  		CorrelationID: "",
   173  	}
   174  
   175  	runtimeCtxNotificationWithoutAppTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   176  		Webhook: *fixRuntimeWebhookGQLModel(WebhookID, RuntimeContextRuntimeID),
   177  		Object: &webhook.FormationConfigurationChangeInput{
   178  			Operation:           model.AssignFormation,
   179  			FormationID:         fixUUID(),
   180  			ApplicationTemplate: nil,
   181  			Application: &webhook.ApplicationWithLabels{
   182  				Application: fixApplicationModelWithoutTemplate(Application2ID),
   183  				Labels:      fixApplicationLabelsMap(),
   184  			},
   185  			Runtime: &webhook.RuntimeWithLabels{
   186  				Runtime: fixRuntimeModel(RuntimeContextRuntimeID),
   187  				Labels:  fixRuntimeLabelsMap(),
   188  			},
   189  			RuntimeContext: &webhook.RuntimeContextWithLabels{
   190  				RuntimeContext: fixRuntimeContextModel(),
   191  				Labels:         fixRuntimeContextLabelsMap(),
   192  			},
   193  			Assignment:        emptyFormationAssignment,
   194  			ReverseAssignment: emptyFormationAssignment,
   195  		},
   196  		CorrelationID: "",
   197  	}
   198  
   199  	appNotificationWithRtmCtxAndTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   200  		Webhook: *fixApplicationWebhookGQLModel(WebhookID, ApplicationID),
   201  		Object: &webhook.FormationConfigurationChangeInput{
   202  			Operation:   model.AssignFormation,
   203  			FormationID: fixUUID(),
   204  			ApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   205  				ApplicationTemplate: fixApplicationTemplateModel(),
   206  				Labels:              fixApplicationTemplateLabelsMap(),
   207  			},
   208  			Application: &webhook.ApplicationWithLabels{
   209  				Application: fixApplicationModel(ApplicationID),
   210  				Labels:      fixApplicationLabelsMap(),
   211  			},
   212  			Runtime: &webhook.RuntimeWithLabels{
   213  				Runtime: fixRuntimeModel(RuntimeContextRuntimeID),
   214  				Labels:  fixRuntimeLabelsMap(),
   215  			},
   216  			RuntimeContext: &webhook.RuntimeContextWithLabels{
   217  				RuntimeContext: fixRuntimeContextModel(),
   218  				Labels:         fixRuntimeContextLabelsMap(),
   219  			},
   220  			Assignment:        emptyFormationAssignment,
   221  			ReverseAssignment: emptyFormationAssignment,
   222  		},
   223  		CorrelationID: "",
   224  	}
   225  
   226  	appNotificationWithRtmCtxWithoutTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   227  		Webhook: *fixApplicationWebhookGQLModel(Webhook2ID, Application2ID),
   228  		Object: &webhook.FormationConfigurationChangeInput{
   229  			Operation:           model.AssignFormation,
   230  			FormationID:         fixUUID(),
   231  			ApplicationTemplate: nil,
   232  			Application: &webhook.ApplicationWithLabels{
   233  				Application: fixApplicationModelWithoutTemplate(Application2ID),
   234  				Labels:      fixApplicationLabelsMap(),
   235  			},
   236  			Runtime: &webhook.RuntimeWithLabels{
   237  				Runtime: fixRuntimeModel(RuntimeContextRuntimeID),
   238  				Labels:  fixRuntimeLabelsMap(),
   239  			},
   240  			RuntimeContext: &webhook.RuntimeContextWithLabels{
   241  				RuntimeContext: fixRuntimeContextModel(),
   242  				Labels:         fixRuntimeContextLabelsMap(),
   243  			},
   244  			Assignment:        emptyFormationAssignment,
   245  			ReverseAssignment: emptyFormationAssignment,
   246  		},
   247  		CorrelationID: "",
   248  	}
   249  
   250  	runtimeNotificationWithAppTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   251  		Webhook: *fixRuntimeWebhookGQLModel(WebhookID, RuntimeID),
   252  		Object: &webhook.FormationConfigurationChangeInput{
   253  			Operation:   model.AssignFormation,
   254  			FormationID: fixUUID(),
   255  			ApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   256  				ApplicationTemplate: fixApplicationTemplateModel(),
   257  				Labels:              fixApplicationTemplateLabelsMap(),
   258  			},
   259  			Application: &webhook.ApplicationWithLabels{
   260  				Application: fixApplicationModel(ApplicationID),
   261  				Labels:      fixApplicationLabelsMap(),
   262  			},
   263  			Runtime: &webhook.RuntimeWithLabels{
   264  				Runtime: fixRuntimeModel(RuntimeID),
   265  				Labels:  fixRuntimeLabelsMap(),
   266  			},
   267  			RuntimeContext:    nil,
   268  			Assignment:        emptyFormationAssignment,
   269  			ReverseAssignment: emptyFormationAssignment,
   270  		},
   271  		CorrelationID: "",
   272  	}
   273  
   274  	runtimeNotificationWithoutAppTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   275  		Webhook: *fixRuntimeWebhookGQLModel(WebhookID, RuntimeID),
   276  		Object: &webhook.FormationConfigurationChangeInput{
   277  			Operation:           model.AssignFormation,
   278  			FormationID:         fixUUID(),
   279  			ApplicationTemplate: nil,
   280  			Application: &webhook.ApplicationWithLabels{
   281  				Application: fixApplicationModelWithoutTemplate(Application2ID),
   282  				Labels:      fixApplicationLabelsMap(),
   283  			},
   284  			Runtime: &webhook.RuntimeWithLabels{
   285  				Runtime: fixRuntimeModel(RuntimeID),
   286  				Labels:  fixRuntimeLabelsMap(),
   287  			},
   288  			RuntimeContext:    nil,
   289  			Assignment:        emptyFormationAssignment,
   290  			ReverseAssignment: emptyFormationAssignment,
   291  		},
   292  		CorrelationID: "",
   293  	}
   294  
   295  	applicationsMapping = map[string]*webhook.ApplicationWithLabels{
   296  		ApplicationID: {
   297  			Application: fixApplicationModel(ApplicationID),
   298  			Labels:      fixApplicationLabelsMap(),
   299  		},
   300  		Application2ID: {
   301  			Application: fixApplicationModelWithoutTemplate(Application2ID),
   302  			Labels:      fixApplicationLabelsMap(),
   303  		},
   304  	}
   305  	applicationsMapping2 = map[string]*webhook.ApplicationWithLabels{
   306  		Application2ID: {
   307  			Application: fixApplicationModelWithoutTemplate(Application2ID),
   308  			Labels:      fixApplicationLabelsMap(),
   309  		},
   310  	}
   311  
   312  	applicationsMappingWithApplicationTemplate = map[string]*webhook.ApplicationWithLabels{
   313  		Application2ID: {
   314  			Application: fixApplicationModelWithTemplateID(Application2ID, ApplicationTemplate2ID),
   315  			Labels:      fixApplicationLabelsMap(),
   316  		},
   317  	}
   318  
   319  	emptyApplicationTemplateMappings = map[string]*webhook.ApplicationTemplateWithLabels{}
   320  
   321  	applicationTemplateMappings = map[string]*webhook.ApplicationTemplateWithLabels{
   322  		ApplicationTemplateID: {
   323  			ApplicationTemplate: fixApplicationTemplateModel(),
   324  			Labels:              fixApplicationTemplateLabelsMap(),
   325  		},
   326  	}
   327  
   328  	applicationTemplateMappings2 = map[string]*webhook.ApplicationTemplateWithLabels{
   329  		ApplicationTemplateID: {
   330  			ApplicationTemplate: fixApplicationTemplateModel(),
   331  			Labels:              fixApplicationTemplateLabelsMap(),
   332  		},
   333  		ApplicationTemplate2ID: {
   334  			ApplicationTemplate: fixApplicationTemplateModelWithID(ApplicationTemplate2ID),
   335  			Labels:              fixApplicationTemplateLabelsMap(),
   336  		},
   337  	}
   338  
   339  	runtimeWithLabels             = fixRuntimeWithLabels(RuntimeID)
   340  	runtimeWithRtmCtxWithLabels   = fixRuntimeWithLabels(RuntimeContextRuntimeID)
   341  	emptyRuntimeContextWithLabels *webhook.RuntimeContextWithLabels
   342  	emptyAppTemplateWithLabels    *webhook.ApplicationTemplateWithLabels
   343  
   344  	runtimeCtxWithLabels = &webhook.RuntimeContextWithLabels{
   345  		RuntimeContext: fixRuntimeContextModel(),
   346  		Labels:         fixRuntimeContextLabelsMap(),
   347  	}
   348  	runtimeCtx2WithLabels = &webhook.RuntimeContextWithLabels{
   349  		RuntimeContext: fixRuntimeContextModelWithRuntimeID(RuntimeID),
   350  		Labels:         fixRuntimeContextLabelsMap(),
   351  	}
   352  
   353  	runtimesMapping = map[string]*webhook.RuntimeWithLabels{
   354  		RuntimeID:               runtimeWithLabels,
   355  		RuntimeContextRuntimeID: runtimeWithRtmCtxWithLabels,
   356  	}
   357  
   358  	runtimeContextsMapping = map[string]*webhook.RuntimeContextWithLabels{
   359  		RuntimeContextRuntimeID: runtimeCtxWithLabels,
   360  		RuntimeID:               runtimeCtx2WithLabels,
   361  	}
   362  
   363  	runtimeContextsMapping2 = map[string]*webhook.RuntimeContextWithLabels{
   364  		RuntimeContextRuntimeID: runtimeCtxWithLabels,
   365  	}
   366  
   367  	appWithLabelsWithoutTemplate2 = &webhook.ApplicationWithLabels{
   368  		Application: fixApplicationModelWithoutTemplate(Application2ID),
   369  		Labels:      fixApplicationLabelsMap(),
   370  	}
   371  
   372  	listeningApplications = []*model.Application{{BaseEntity: &model.BaseEntity{ID: Application2ID}}, {ApplicationTemplateID: str.Ptr(ApplicationTemplateID), BaseEntity: &model.BaseEntity{ID: ApplicationID}}}
   373  
   374  	applicationNotificationWithAppTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   375  		Webhook: *fixApplicationWebhookGQLModel(WebhookID, ApplicationID),
   376  		Object: &webhook.FormationConfigurationChangeInput{
   377  			Operation:   model.AssignFormation,
   378  			FormationID: fixUUID(),
   379  			ApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   380  				ApplicationTemplate: fixApplicationTemplateModel(),
   381  				Labels:              fixApplicationTemplateLabelsMap(),
   382  			},
   383  			Application: &webhook.ApplicationWithLabels{
   384  				Application: fixApplicationModel(ApplicationID),
   385  				Labels:      fixApplicationLabelsMap(),
   386  			},
   387  			Runtime: &webhook.RuntimeWithLabels{
   388  				Runtime: fixRuntimeModel(RuntimeID),
   389  				Labels:  fixRuntimeLabelsMap(),
   390  			},
   391  			RuntimeContext:    nil,
   392  			Assignment:        emptyFormationAssignment,
   393  			ReverseAssignment: emptyFormationAssignment,
   394  		},
   395  		CorrelationID: "",
   396  	}
   397  
   398  	applicationNotificationWithoutAppTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   399  		Webhook: *fixApplicationWebhookGQLModel(Webhook2ID, Application2ID),
   400  		Object: &webhook.FormationConfigurationChangeInput{
   401  			Operation:           model.AssignFormation,
   402  			FormationID:         fixUUID(),
   403  			ApplicationTemplate: nil,
   404  			Application: &webhook.ApplicationWithLabels{
   405  				Application: fixApplicationModelWithoutTemplate(Application2ID),
   406  				Labels:      fixApplicationLabelsMap(),
   407  			},
   408  			Runtime: &webhook.RuntimeWithLabels{
   409  				Runtime: fixRuntimeModel(RuntimeID),
   410  				Labels:  fixRuntimeLabelsMap(),
   411  			},
   412  			RuntimeContext:    nil,
   413  			Assignment:        emptyFormationAssignment,
   414  			ReverseAssignment: emptyFormationAssignment,
   415  		},
   416  		CorrelationID: "",
   417  	}
   418  
   419  	runtimeNotificationWithRtmCtxAndAppTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   420  		Webhook: *fixRuntimeWebhookGQLModel(WebhookForRuntimeContextID, RuntimeContextRuntimeID),
   421  		Object: &webhook.FormationConfigurationChangeInput{
   422  			Operation:   model.AssignFormation,
   423  			FormationID: fixUUID(),
   424  			ApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   425  				ApplicationTemplate: fixApplicationTemplateModel(),
   426  				Labels:              fixApplicationTemplateLabelsMap(),
   427  			},
   428  			Application: &webhook.ApplicationWithLabels{
   429  				Application: fixApplicationModel(ApplicationID),
   430  				Labels:      fixApplicationLabelsMap(),
   431  			},
   432  			Runtime: &webhook.RuntimeWithLabels{
   433  				Runtime: fixRuntimeModel(RuntimeContextRuntimeID),
   434  				Labels:  fixRuntimeLabelsMap(),
   435  			},
   436  			RuntimeContext: &webhook.RuntimeContextWithLabels{
   437  				RuntimeContext: fixRuntimeContextModel(),
   438  				Labels:         fixRuntimeContextLabelsMap(),
   439  			},
   440  			Assignment:        emptyFormationAssignment,
   441  			ReverseAssignment: emptyFormationAssignment,
   442  		},
   443  		CorrelationID: "",
   444  	}
   445  
   446  	appNotificationWithRtmCtxRtmIDAndTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   447  		Webhook: *fixApplicationWebhookGQLModel(WebhookID, ApplicationID),
   448  		Object: &webhook.FormationConfigurationChangeInput{
   449  			Operation:   model.AssignFormation,
   450  			FormationID: fixUUID(),
   451  			ApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   452  				ApplicationTemplate: fixApplicationTemplateModel(),
   453  				Labels:              fixApplicationTemplateLabelsMap(),
   454  			},
   455  			Application: &webhook.ApplicationWithLabels{
   456  				Application: fixApplicationModel(ApplicationID),
   457  				Labels:      fixApplicationLabelsMap(),
   458  			},
   459  			Runtime: &webhook.RuntimeWithLabels{
   460  				Runtime: fixRuntimeModel(RuntimeID),
   461  				Labels:  fixRuntimeLabelsMap(),
   462  			},
   463  			RuntimeContext: &webhook.RuntimeContextWithLabels{
   464  				RuntimeContext: fixRuntimeContextModelWithRuntimeID(RuntimeID),
   465  				Labels:         fixRuntimeContextLabelsMap(),
   466  			},
   467  			Assignment:        emptyFormationAssignment,
   468  			ReverseAssignment: emptyFormationAssignment,
   469  		},
   470  		CorrelationID: "",
   471  	}
   472  
   473  	appToAppNotificationWithoutSourceTemplateWithTargetTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   474  		Webhook: *fixApplicationTenantMappingWebhookGQLModel(AppTenantMappingWebhookIDForApp1, ApplicationID),
   475  		Object: &webhook.ApplicationTenantMappingInput{
   476  			Operation:                 model.AssignFormation,
   477  			FormationID:               fixUUID(),
   478  			SourceApplicationTemplate: nil,
   479  			SourceApplication: &webhook.ApplicationWithLabels{
   480  				Application: fixApplicationModelWithoutTemplate(Application2ID),
   481  				Labels:      fixApplicationLabelsMap(),
   482  			},
   483  			TargetApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   484  				ApplicationTemplate: fixApplicationTemplateModel(),
   485  				Labels:              fixApplicationTemplateLabelsMap(),
   486  			},
   487  			TargetApplication: &webhook.ApplicationWithLabels{
   488  				Application: fixApplicationModel(ApplicationID),
   489  				Labels:      fixApplicationLabelsMap(),
   490  			},
   491  			Assignment:        emptyFormationAssignment,
   492  			ReverseAssignment: emptyFormationAssignment,
   493  		},
   494  		CorrelationID: "",
   495  	}
   496  
   497  	appToAppNotificationWithSourceAndTargetTemplates = &webhookclient.FormationAssignmentNotificationRequest{
   498  		Webhook: *fixApplicationTenantMappingWebhookGQLModel(AppTenantMappingWebhookIDForApp2, Application2ID),
   499  		Object: &webhook.ApplicationTenantMappingInput{
   500  			Operation:   model.AssignFormation,
   501  			FormationID: fixUUID(),
   502  			SourceApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   503  				ApplicationTemplate: fixApplicationTemplateModel(),
   504  				Labels:              fixApplicationTemplateLabelsMap(),
   505  			},
   506  			SourceApplication: &webhook.ApplicationWithLabels{
   507  				Application: fixApplicationModel(ApplicationID),
   508  				Labels:      fixApplicationLabelsMap(),
   509  			},
   510  			TargetApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   511  				ApplicationTemplate: fixApplicationTemplateModelWithID(ApplicationTemplate2ID),
   512  				Labels:              fixApplicationTemplateLabelsMap(),
   513  			},
   514  			TargetApplication: &webhook.ApplicationWithLabels{
   515  				Application: fixApplicationModelWithoutTemplate(Application2ID),
   516  				Labels:      fixApplicationLabelsMap(),
   517  			},
   518  			Assignment:        emptyFormationAssignment,
   519  			ReverseAssignment: emptyFormationAssignment,
   520  		},
   521  		CorrelationID: "",
   522  	}
   523  
   524  	appToAppNotificationWithSourceAndTargetTemplatesSwaped = &webhookclient.FormationAssignmentNotificationRequest{
   525  		Webhook: *fixApplicationTenantMappingWebhookGQLModel(AppTenantMappingWebhookIDForApp2, Application2ID),
   526  		Object: &webhook.ApplicationTenantMappingInput{
   527  			Operation:   model.AssignFormation,
   528  			FormationID: fixUUID(),
   529  			TargetApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   530  				ApplicationTemplate: fixApplicationTemplateModel(),
   531  				Labels:              fixApplicationTemplateLabelsMap(),
   532  			},
   533  			TargetApplication: &webhook.ApplicationWithLabels{
   534  				Application: fixApplicationModel(ApplicationID),
   535  				Labels:      fixApplicationLabelsMap(),
   536  			},
   537  			SourceApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   538  				ApplicationTemplate: fixApplicationTemplateModelWithID(ApplicationTemplate2ID),
   539  				Labels:              fixApplicationTemplateLabelsMap(),
   540  			},
   541  			SourceApplication: &webhook.ApplicationWithLabels{
   542  				Application: fixApplicationModelWithoutTemplate(Application2ID),
   543  				Labels:      fixApplicationLabelsMap(),
   544  			},
   545  			Assignment:        emptyFormationAssignment,
   546  			ReverseAssignment: emptyFormationAssignment,
   547  		},
   548  		CorrelationID: "",
   549  	}
   550  
   551  	appToAppNotificationWithSourceTemplateWithoutTargetTemplate = &webhookclient.FormationAssignmentNotificationRequest{
   552  		Webhook: *fixApplicationTenantMappingWebhookGQLModel(AppTenantMappingWebhookIDForApp2, Application2ID),
   553  		Object: &webhook.ApplicationTenantMappingInput{
   554  			Operation:   model.AssignFormation,
   555  			FormationID: fixUUID(),
   556  			SourceApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   557  				ApplicationTemplate: fixApplicationTemplateModel(),
   558  				Labels:              fixApplicationTemplateLabelsMap(),
   559  			},
   560  			SourceApplication: &webhook.ApplicationWithLabels{
   561  				Application: fixApplicationModel(ApplicationID),
   562  				Labels:      fixApplicationLabelsMap(),
   563  			},
   564  			TargetApplicationTemplate: nil,
   565  			TargetApplication: &webhook.ApplicationWithLabels{
   566  				Application: fixApplicationModelWithoutTemplate(Application2ID),
   567  				Labels:      fixApplicationLabelsMap(),
   568  			},
   569  			Assignment:        emptyFormationAssignment,
   570  			ReverseAssignment: emptyFormationAssignment,
   571  		},
   572  		CorrelationID: "",
   573  	}
   574  
   575  	// Formation notification variables
   576  	emptyFormationNotificationRequests = make([]*webhookclient.FormationNotificationRequest, 0)
   577  
   578  	formationNotificationSyncCreateRequest = &webhookclient.FormationNotificationRequest{
   579  		Request: &webhookclient.Request{
   580  			Webhook:       fixFormationLifecycleWebhookGQLModel(FormationLifecycleWebhookID, FormationTemplateID, graphql.WebhookModeSync),
   581  			Object:        fixFormationLifecycleInput(model.CreateFormation, TntCustomerID, TntExternalID),
   582  			CorrelationID: "",
   583  		},
   584  		Operation:     model.CreateFormation,
   585  		Formation:     fixFormationModelWithoutError(),
   586  		FormationType: testFormationTemplateName,
   587  	}
   588  
   589  	formationWithInitialState              = fixFormationModelWithState(model.InitialFormationState)
   590  	formationNotificationSyncDeleteRequest = &webhookclient.FormationNotificationRequest{
   591  		Request: &webhookclient.Request{
   592  			Webhook:       fixFormationLifecycleWebhookGQLModel(FormationLifecycleWebhookID, FormationTemplateID, graphql.WebhookModeSync),
   593  			Object:        fixFormationLifecycleInput(model.DeleteFormation, TntCustomerID, TntExternalID),
   594  			CorrelationID: "",
   595  		},
   596  	}
   597  	formationNotificationAsyncCreateRequest = &webhookclient.FormationNotificationRequest{
   598  		Request: &webhookclient.Request{
   599  			Webhook:       fixFormationLifecycleWebhookGQLModelAsync(FormationLifecycleWebhookID, FormationTemplateID),
   600  			Object:        fixFormationLifecycleInput(model.CreateFormation, TntCustomerID, TntExternalID),
   601  			CorrelationID: "",
   602  		},
   603  		Operation:     model.CreateFormation,
   604  		Formation:     fixFormationModelWithoutError(),
   605  		FormationType: testFormationTemplateName,
   606  	}
   607  
   608  	formationNotificationAsyncDeleteRequest = &webhookclient.FormationNotificationRequest{
   609  		Request: &webhookclient.Request{
   610  			Webhook:       fixFormationLifecycleWebhookGQLModelAsync(FormationLifecycleWebhookID, FormationTemplateID),
   611  			Object:        fixFormationLifecycleInput(model.DeleteFormation, TntCustomerID, TntExternalID),
   612  			CorrelationID: "",
   613  		},
   614  		Operation:     model.DeleteFormation,
   615  		Formation:     fixFormationModelWithState(model.ReadyFormationState),
   616  		FormationType: testFormationTemplateName,
   617  	}
   618  
   619  	formationNotificationSyncCreateRequests  = []*webhookclient.FormationNotificationRequest{formationNotificationSyncCreateRequest}
   620  	formationNotificationSyncDeleteRequests  = []*webhookclient.FormationNotificationRequest{formationNotificationSyncDeleteRequest}
   621  	formationNotificationAsyncDeleteRequests = []*webhookclient.FormationNotificationRequest{formationNotificationAsyncDeleteRequest}
   622  	formationNotificationAsyncCreateRequests = []*webhookclient.FormationNotificationRequest{formationNotificationAsyncCreateRequest}
   623  
   624  	formationNotificationWebhookSuccessResponse = fixFormationNotificationWebhookResponse(http.StatusOK, http.StatusOK, nil)
   625  	formationNotificationWebhookErrorResponse   = fixFormationNotificationWebhookResponse(http.StatusOK, http.StatusOK, str.Ptr(testErr.Error()))
   626  
   627  	formationLifecycleSyncWebhook  = fixFormationLifecycleSyncWebhookModel(FormationLifecycleWebhookID, FormationTemplateID, model.FormationTemplateWebhookReference)
   628  	formationLifecycleSyncWebhooks = []*model.Webhook{formationLifecycleSyncWebhook}
   629  
   630  	formationLifecycleAsyncWebhook  = fixFormationLifecycleAsyncCallbackWebhookModel(FormationLifecycleWebhookID, FormationTemplateID, model.FormationTemplateWebhookReference)
   631  	formationLifecycleAsyncWebhooks = []*model.Webhook{formationLifecycleAsyncWebhook}
   632  	emptyFormationLifecycleWebhooks []*model.Webhook
   633  
   634  	// Formation constraints join point location variables
   635  	preGenerateFormationAssignmentNotificationLocation = formationconstraint.JoinPointLocation{
   636  		OperationName:  model.GenerateFormationAssignmentNotificationOperation,
   637  		ConstraintType: model.PreOperation,
   638  	}
   639  
   640  	postGenerateFormationAssignmentNotificationLocation = formationconstraint.JoinPointLocation{
   641  		OperationName:  model.GenerateFormationAssignmentNotificationOperation,
   642  		ConstraintType: model.PostOperation,
   643  	}
   644  
   645  	preGenerateFormationNotificationLocation = formationconstraint.JoinPointLocation{
   646  		OperationName:  model.GenerateFormationNotificationOperation,
   647  		ConstraintType: model.PreOperation,
   648  	}
   649  
   650  	postGenerateFormationNotificationLocation = formationconstraint.JoinPointLocation{
   651  		OperationName:  model.GenerateFormationNotificationOperation,
   652  		ConstraintType: model.PostOperation,
   653  	}
   654  
   655  	preAssignLocation = formationconstraint.JoinPointLocation{
   656  		OperationName:  model.AssignFormationOperation,
   657  		ConstraintType: model.PreOperation,
   658  	}
   659  
   660  	postAssignLocation = formationconstraint.JoinPointLocation{
   661  		OperationName:  model.AssignFormationOperation,
   662  		ConstraintType: model.PostOperation,
   663  	}
   664  
   665  	preUnassignLocation = formationconstraint.JoinPointLocation{
   666  		OperationName:  model.UnassignFormationOperation,
   667  		ConstraintType: model.PreOperation,
   668  	}
   669  
   670  	postUnassignLocation = formationconstraint.JoinPointLocation{
   671  		OperationName:  model.UnassignFormationOperation,
   672  		ConstraintType: model.PostOperation,
   673  	}
   674  
   675  	preCreateLocation = formationconstraint.JoinPointLocation{
   676  		OperationName:  model.CreateFormationOperation,
   677  		ConstraintType: model.PreOperation,
   678  	}
   679  
   680  	postCreateLocation = formationconstraint.JoinPointLocation{
   681  		OperationName:  model.CreateFormationOperation,
   682  		ConstraintType: model.PostOperation,
   683  	}
   684  
   685  	preDeleteLocation = formationconstraint.JoinPointLocation{
   686  		OperationName:  model.DeleteFormationOperation,
   687  		ConstraintType: model.PreOperation,
   688  	}
   689  
   690  	postDeleteLocation = formationconstraint.JoinPointLocation{
   691  		OperationName:  model.DeleteFormationOperation,
   692  		ConstraintType: model.PostOperation,
   693  	}
   694  
   695  	// Formation constraints join point details variables
   696  	createFormationDetails = &formationconstraint.CRUDFormationOperationDetails{
   697  		FormationType:       testFormationTemplateName,
   698  		FormationTemplateID: FormationTemplateID,
   699  		FormationName:       testFormationName,
   700  		TenantID:            TntInternalID,
   701  	}
   702  
   703  	deleteFormationDetails = &formationconstraint.CRUDFormationOperationDetails{
   704  		FormationType:       testFormationTemplateName,
   705  		FormationTemplateID: FormationTemplateID,
   706  		FormationName:       testFormationName,
   707  		TenantID:            TntInternalID,
   708  	}
   709  
   710  	unassignAppDetails = &formationconstraint.UnassignFormationOperationDetails{
   711  		ResourceType:        model.ApplicationResourceType,
   712  		ResourceSubtype:     applicationType,
   713  		ResourceID:          ApplicationID,
   714  		FormationType:       testFormationTemplateName,
   715  		FormationTemplateID: FormationTemplateID,
   716  		FormationID:         FormationID,
   717  		TenantID:            TntInternalID,
   718  	}
   719  
   720  	assignAppInvalidTypeDetails = &formationconstraint.AssignFormationOperationDetails{
   721  		ResourceType:        model.ApplicationResourceType,
   722  		ResourceSubtype:     "invalidApplicationType",
   723  		ResourceID:          ApplicationID,
   724  		FormationName:       secondTestFormationName,
   725  		FormationType:       testFormationTemplateName,
   726  		FormationTemplateID: FormationTemplateID,
   727  		FormationID:         FormationID,
   728  		TenantID:            TntInternalID,
   729  	}
   730  
   731  	unassignRuntimeDetails = &formationconstraint.UnassignFormationOperationDetails{
   732  		ResourceType:        model.RuntimeResourceType,
   733  		ResourceSubtype:     runtimeType,
   734  		ResourceID:          RuntimeID,
   735  		FormationType:       testFormationTemplateName,
   736  		FormationTemplateID: FormationTemplateID,
   737  		FormationID:         FormationID,
   738  		TenantID:            TntInternalID,
   739  	}
   740  
   741  	assignRuntimeOtherTemplateDetails = &formationconstraint.AssignFormationOperationDetails{
   742  		ResourceType:        model.RuntimeResourceType,
   743  		ResourceSubtype:     runtimeType,
   744  		ResourceID:          RuntimeID,
   745  		FormationName:       testFormationName,
   746  		FormationType:       "some-other-template",
   747  		FormationTemplateID: FormationTemplateID,
   748  		FormationID:         FormationID,
   749  		TenantID:            TntInternalID,
   750  	}
   751  
   752  	assignRuntimeContextOtherTemplateDetails = &formationconstraint.AssignFormationOperationDetails{
   753  		ResourceType:        model.RuntimeContextResourceType,
   754  		ResourceSubtype:     runtimeType,
   755  		ResourceID:          RuntimeContextID,
   756  		FormationName:       testFormationName,
   757  		FormationType:       "some-other-template",
   758  		FormationTemplateID: FormationTemplateID,
   759  		FormationID:         FormationID,
   760  		TenantID:            TntInternalID,
   761  	}
   762  
   763  	unassignTenantDetails = &formationconstraint.UnassignFormationOperationDetails{
   764  		ResourceType:        model.TenantResourceType,
   765  		ResourceSubtype:     "account",
   766  		ResourceID:          TargetTenant,
   767  		FormationType:       testFormationTemplateName,
   768  		FormationTemplateID: FormationTemplateID,
   769  		FormationID:         FormationID,
   770  		TenantID:            TntInternalID,
   771  	}
   772  
   773  	notificationDetails = &formationconstraint.GenerateFormationAssignmentNotificationOperationDetails{}
   774  
   775  	generateConfigurationChangeNotificationDetails = &formationconstraint.GenerateFormationAssignmentNotificationOperationDetails{
   776  		Operation:   model.AssignFormation,
   777  		FormationID: fixUUID(),
   778  		ApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   779  			ApplicationTemplate: fixApplicationTemplateModel(),
   780  			Labels:              fixApplicationTemplateLabelsMap(),
   781  		},
   782  		Application: &webhook.ApplicationWithLabels{
   783  			Application: fixApplicationModel(ApplicationID),
   784  			Labels:      fixApplicationLabelsMap(),
   785  		},
   786  		Runtime: &webhook.RuntimeWithLabels{
   787  			Runtime: fixRuntimeModel(RuntimeID),
   788  			Labels:  fixRuntimeLabelsMap(),
   789  		},
   790  		Assignment:        emptyFormationAssignment,
   791  		ReverseAssignment: emptyFormationAssignment,
   792  	}
   793  
   794  	generateAppToAppNotificationDetails = &formationconstraint.GenerateFormationAssignmentNotificationOperationDetails{
   795  		Operation:                 model.AssignFormation,
   796  		FormationID:               fixUUID(),
   797  		SourceApplicationTemplate: nil,
   798  		SourceApplication: &webhook.ApplicationWithLabels{
   799  			Application: fixApplicationModelWithoutTemplate(Application2ID),
   800  			Labels:      fixApplicationLabelsMap(),
   801  		},
   802  		TargetApplicationTemplate: &webhook.ApplicationTemplateWithLabels{
   803  			ApplicationTemplate: fixApplicationTemplateModel(),
   804  			Labels:              fixApplicationTemplateLabelsMap(),
   805  		},
   806  		TargetApplication: &webhook.ApplicationWithLabels{
   807  			Application: fixApplicationModel(ApplicationID),
   808  			Labels:      fixApplicationLabelsMap(),
   809  		},
   810  		Assignment:        emptyFormationAssignment,
   811  		ReverseAssignment: emptyFormationAssignment,
   812  	}
   813  
   814  	formationNotificationDetails = &formationconstraint.GenerateFormationNotificationOperationDetails{
   815  		Operation:             model.CreateFormation,
   816  		FormationID:           FormationID,
   817  		FormationName:         testFormationName,
   818  		FormationType:         testFormationTemplateName,
   819  		FormationTemplateID:   FormationTemplateID,
   820  		TenantID:              TntInternalID,
   821  		CustomerTenantContext: CustomerTenantContextAccount,
   822  	}
   823  
   824  	gaTenantObject = fixModelBusinessTenantMappingWithType(tnt.Account)
   825  	rgTenantObject = fixModelBusinessTenantMappingWithType(tnt.ResourceGroup)
   826  
   827  	customerTenantContext = &webhook.CustomerTenantContext{
   828  		CustomerID: TntParentID,
   829  		AccountID:  str.Ptr(gaTenantObject.ExternalTenant),
   830  		Path:       nil,
   831  	}
   832  
   833  	rgCustomerTenantContext = &webhook.CustomerTenantContext{
   834  		CustomerID: TntParentID,
   835  		AccountID:  nil,
   836  		Path:       str.Ptr(gaTenantObject.ExternalTenant),
   837  	}
   838  	firstFormationStatusParams  = dataloader.ParamFormationStatus{ID: FormationID, State: string(model.ReadyFormationState)}
   839  	secondFormationStatusParams = dataloader.ParamFormationStatus{ID: FormationID + "2", State: string(model.InitialFormationState)}
   840  	thirdFormationStatusParams  = dataloader.ParamFormationStatus{ID: FormationID + "3", State: string(model.ReadyFormationState)}
   841  	fourthPageFormations        = dataloader.ParamFormationStatus{ID: FormationID + "4", State: string(model.ReadyFormationState)}
   842  )
   843  
   844  func unusedApplicationRepository() *automock.ApplicationRepository {
   845  	return &automock.ApplicationRepository{}
   846  }
   847  
   848  func unusedLabelService() *automock.LabelService {
   849  	return &automock.LabelService{}
   850  }
   851  
   852  func unusedLabelRepo() *automock.LabelRepository {
   853  	return &automock.LabelRepository{}
   854  }
   855  
   856  func unusedASAService() *automock.AutomaticFormationAssignmentService {
   857  	return &automock.AutomaticFormationAssignmentService{}
   858  }
   859  
   860  func unusedASARepo() *automock.AutomaticFormationAssignmentRepository {
   861  	return &automock.AutomaticFormationAssignmentRepository{}
   862  }
   863  
   864  func unusedASAEngine() *automock.AsaEngine {
   865  	return &automock.AsaEngine{}
   866  }
   867  
   868  func unusedRuntimeRepo() *automock.RuntimeRepository {
   869  	return &automock.RuntimeRepository{}
   870  }
   871  
   872  func unusedTenantRepo() *automock.TenantRepository {
   873  	return &automock.TenantRepository{}
   874  }
   875  
   876  func unusedRuntimeContextRepo() *automock.RuntimeContextRepository {
   877  	return &automock.RuntimeContextRepository{}
   878  }
   879  
   880  func unusedDataInputBuilder() *databuilderautomock.DataInputBuilder {
   881  	return &databuilderautomock.DataInputBuilder{}
   882  }
   883  
   884  func expectEmptySliceRuntimeContextRepo() *automock.RuntimeContextRepository {
   885  	repo := &automock.RuntimeContextRepository{}
   886  	repo.On("ListByIDs", mock.Anything, TntInternalID, []string{}).Return(nil, nil).Once()
   887  	return repo
   888  }
   889  
   890  func unusedApplicationRepo() *automock.ApplicationRepository {
   891  	return &automock.ApplicationRepository{}
   892  }
   893  
   894  func unusedWebhookRepository() *automock.WebhookRepository {
   895  	return &automock.WebhookRepository{}
   896  }
   897  
   898  func unusedAppTemplateRepository() *automock.ApplicationTemplateRepository {
   899  	return &automock.ApplicationTemplateRepository{}
   900  }
   901  
   902  func unusedWebhookConverter() *automock.WebhookConverter {
   903  	return &automock.WebhookConverter{}
   904  }
   905  
   906  func unusedWebhookClient() *automock.WebhookClient {
   907  	return &automock.WebhookClient{}
   908  }
   909  
   910  func unusedLabelDefService() *automock.LabelDefService {
   911  	return &automock.LabelDefService{}
   912  }
   913  
   914  func unusedLabelDefRepository() *automock.LabelDefRepository {
   915  	return &automock.LabelDefRepository{}
   916  }
   917  
   918  func unusedUUIDService() *automock.UuidService {
   919  	return &automock.UuidService{}
   920  }
   921  
   922  func unusedConverter() *automock.Converter {
   923  	return &automock.Converter{}
   924  }
   925  
   926  func unusedService() *automock.Service {
   927  	return &automock.Service{}
   928  }
   929  
   930  func unusedFormationRepo() *automock.FormationRepository {
   931  	return &automock.FormationRepository{}
   932  }
   933  
   934  func unusedNotificationsService() *automock.NotificationsService {
   935  	return &automock.NotificationsService{}
   936  }
   937  
   938  func unusedFormationAssignmentService() *automock.FormationAssignmentService {
   939  	return &automock.FormationAssignmentService{}
   940  }
   941  
   942  func unusedFormationAssignmentNotificationService() *automock.FormationAssignmentNotificationsService {
   943  	return &automock.FormationAssignmentNotificationsService{}
   944  }
   945  
   946  func noActionNotificationsService() *automock.NotificationsService {
   947  	notificationSvc := &automock.NotificationsService{}
   948  	notificationSvc.On("GenerateFormationAssignmentNotifications", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
   949  	return notificationSvc
   950  }
   951  
   952  func unusedFormationTemplateRepo() *automock.FormationTemplateRepository {
   953  	return &automock.FormationTemplateRepository{}
   954  }
   955  
   956  func unusedProcessFunc() *automock.ProcessFunc {
   957  	return &automock.ProcessFunc{}
   958  }
   959  
   960  func unusedConstraintEngine() *automock.ConstraintEngine {
   961  	return &automock.ConstraintEngine{}
   962  }
   963  
   964  func unusedNotificationsBuilder() *automock.NotificationBuilder {
   965  	return &automock.NotificationBuilder{}
   966  }
   967  
   968  func unusedNotificationsGenerator() *automock.NotificationsGenerator {
   969  	return &automock.NotificationsGenerator{}
   970  }
   971  
   972  func unusedTenantService() *automock.TenantService {
   973  	return &automock.TenantService{}
   974  }
   975  
   976  func fixCtxWithTenant() context.Context {
   977  	ctx := context.TODO()
   978  	ctx = tenant.SaveToContext(ctx, tenantID.String(), externalTenantID.String())
   979  
   980  	return ctx
   981  }
   982  
   983  func fixModel(scenarioName string) model.AutomaticScenarioAssignment {
   984  	return fixModelWithScenarioName(scenarioName)
   985  }
   986  
   987  func fixModelWithScenarioName(scenario string) model.AutomaticScenarioAssignment {
   988  	return model.AutomaticScenarioAssignment{
   989  		ScenarioName:   scenario,
   990  		Tenant:         tenantID.String(),
   991  		TargetTenantID: TargetTenantID,
   992  	}
   993  }
   994  
   995  func fixError() error {
   996  	return errors.New(ErrMsg)
   997  }
   998  
   999  func mockScenarioDefServiceThatReturns(scenarios []string) *automock.LabelDefService {
  1000  	mockScenarioDefSvc := &automock.LabelDefService{}
  1001  	mockScenarioDefSvc.On("GetAvailableScenarios", mock.Anything, tenantID.String()).Return(scenarios, nil)
  1002  	return mockScenarioDefSvc
  1003  }
  1004  
  1005  func fixUUID() string {
  1006  	return FormationID
  1007  }
  1008  
  1009  func fixColumns() []string {
  1010  	return []string{"id", "tenant_id", "formation_template_id", "name", "state", "error"}
  1011  }
  1012  
  1013  func fixScenariosLabelDefinition(tenantID string, schema interface{}) model.LabelDefinition {
  1014  	return model.LabelDefinition{
  1015  		Key:     model.ScenariosKey,
  1016  		Tenant:  tenantID,
  1017  		Schema:  &schema,
  1018  		Version: 1,
  1019  	}
  1020  }
  1021  
  1022  func fixFormationTemplateModel() *model.FormationTemplate {
  1023  	kind := model.RuntimeArtifactKindEnvironmentInstance
  1024  	return &model.FormationTemplate{
  1025  		ID:                     FormationTemplateID,
  1026  		Name:                   testFormationTemplateName,
  1027  		ApplicationTypes:       []string{"appType1", "appType2"},
  1028  		RuntimeTypes:           []string{"runtimeTypes"},
  1029  		RuntimeTypeDisplayName: str.Ptr("runtimeDisplayName"),
  1030  		RuntimeArtifactKind:    &kind,
  1031  	}
  1032  }
  1033  
  1034  func fixApplicationModelWithoutTemplate(applicationID string) *model.Application {
  1035  	appModel := fixApplicationModel(applicationID)
  1036  	appModel.ApplicationTemplateID = nil
  1037  	return appModel
  1038  }
  1039  
  1040  func fixApplicationModel(applicationID string) *model.Application {
  1041  	return &model.Application{
  1042  		ProviderName:          str.Ptr("application-provider"),
  1043  		ApplicationTemplateID: str.Ptr(ApplicationTemplateID),
  1044  		Name:                  "application-name",
  1045  		Description:           str.Ptr("detailed application description"),
  1046  		Status: &model.ApplicationStatus{
  1047  			Condition: model.ApplicationStatusConditionInitial,
  1048  			Timestamp: time.Time{},
  1049  		},
  1050  		HealthCheckURL:      str.Ptr("localhost/healthz"),
  1051  		BaseURL:             str.Ptr("base_url"),
  1052  		OrdLabels:           json.RawMessage("[]"),
  1053  		CorrelationIDs:      json.RawMessage("[]"),
  1054  		SystemStatus:        str.Ptr("reachable"),
  1055  		DocumentationLabels: json.RawMessage("[]"),
  1056  		BaseEntity: &model.BaseEntity{
  1057  			ID:        applicationID,
  1058  			Ready:     true,
  1059  			Error:     nil,
  1060  			CreatedAt: &time.Time{},
  1061  			UpdatedAt: &time.Time{},
  1062  			DeletedAt: &time.Time{},
  1063  		},
  1064  	}
  1065  }
  1066  
  1067  func fixApplicationModelWithTemplateID(applicationID, templateID string) *model.Application {
  1068  	app := fixApplicationModel(applicationID)
  1069  	app.ApplicationTemplateID = str.Ptr(templateID)
  1070  	return app
  1071  }
  1072  
  1073  func fixModelBusinessTenantMappingWithType(t tnt.Type) *model.BusinessTenantMapping {
  1074  	return &model.BusinessTenantMapping{
  1075  		ID:             TntInternalID,
  1076  		Name:           "test-name",
  1077  		ExternalTenant: TntExternalID,
  1078  		Parent:         TntCustomerID,
  1079  		Type:           t,
  1080  		Provider:       testProvider,
  1081  		Status:         tnt.Active,
  1082  	}
  1083  }
  1084  
  1085  func fixApplicationLabelsMap() map[string]string {
  1086  	return map[string]string{
  1087  		"app-label-key": "app-label-value",
  1088  	}
  1089  }
  1090  
  1091  func fixApplicationTemplateLabelsMap() map[string]string {
  1092  	return map[string]string{
  1093  		"apptemplate-label-key": "apptemplate-label-value",
  1094  	}
  1095  }
  1096  
  1097  func fixRuntimeLabelsMap() map[string]string {
  1098  	return map[string]string{
  1099  		"runtime-label-key": "runtime-label-value",
  1100  	}
  1101  }
  1102  
  1103  func fixRuntimeContextLabelsMap() map[string]string {
  1104  	return map[string]string{
  1105  		"runtime-context-label-key": "runtime-context-label-value",
  1106  	}
  1107  }
  1108  
  1109  func fixConfigurationChangedWebhookModel(webhookID, objectID string, objectType model.WebhookReferenceObjectType) *model.Webhook {
  1110  	return &model.Webhook{
  1111  		ID:         webhookID,
  1112  		ObjectID:   objectID,
  1113  		ObjectType: objectType,
  1114  		Type:       model.WebhookTypeConfigurationChanged,
  1115  	}
  1116  }
  1117  
  1118  func fixApplicationTenantMappingWebhookModel(webhookID, appID string) *model.Webhook {
  1119  	return &model.Webhook{
  1120  		ID:         webhookID,
  1121  		ObjectID:   appID,
  1122  		ObjectType: model.ApplicationWebhookReference,
  1123  		Type:       model.WebhookTypeApplicationTenantMapping,
  1124  	}
  1125  }
  1126  
  1127  func fixFormationLifecycleWebhookModel(webhookID, objectID string, objectType model.WebhookReferenceObjectType, mode model.WebhookMode) *model.Webhook {
  1128  	return &model.Webhook{
  1129  		ID:         webhookID,
  1130  		ObjectID:   objectID,
  1131  		ObjectType: objectType,
  1132  		Type:       model.WebhookTypeFormationLifecycle,
  1133  		Mode:       &mode,
  1134  	}
  1135  }
  1136  
  1137  func fixFormationLifecycleSyncWebhookModel(webhookID, objectID string, objectType model.WebhookReferenceObjectType) *model.Webhook {
  1138  	return fixFormationLifecycleWebhookModel(webhookID, objectID, objectType, model.WebhookModeSync)
  1139  }
  1140  
  1141  func fixFormationLifecycleAsyncCallbackWebhookModel(webhookID, objectID string, objectType model.WebhookReferenceObjectType) *model.Webhook {
  1142  	return fixFormationLifecycleWebhookModel(webhookID, objectID, objectType, model.WebhookModeAsyncCallback)
  1143  }
  1144  
  1145  func fixRuntimeWebhookGQLModel(webhookID, runtimeID string) *graphql.Webhook {
  1146  	return &graphql.Webhook{
  1147  		ID:        webhookID,
  1148  		RuntimeID: str.Ptr(runtimeID),
  1149  		Type:      graphql.WebhookTypeConfigurationChanged,
  1150  	}
  1151  }
  1152  
  1153  func fixRuntimeWebhookModel(webhookID, runtimeID string) *model.Webhook {
  1154  	return &model.Webhook{
  1155  		ID:       webhookID,
  1156  		ObjectID: runtimeID,
  1157  		Type:     model.WebhookTypeConfigurationChanged,
  1158  	}
  1159  }
  1160  
  1161  func fixApplicationWebhookGQLModel(webhookID, appID string) *graphql.Webhook {
  1162  	return &graphql.Webhook{
  1163  		ID:            webhookID,
  1164  		ApplicationID: str.Ptr(appID),
  1165  		Type:          graphql.WebhookTypeConfigurationChanged,
  1166  	}
  1167  }
  1168  
  1169  func fixApplicationTenantMappingWebhookGQLModel(webhookID, appID string) *graphql.Webhook {
  1170  	return &graphql.Webhook{
  1171  		ID:            webhookID,
  1172  		ApplicationID: str.Ptr(appID),
  1173  		Type:          graphql.WebhookTypeApplicationTenantMapping,
  1174  	}
  1175  }
  1176  
  1177  func fixFormationLifecycleWebhookGQLModel(webhookID, formationTemplateID string, mode graphql.WebhookMode) graphql.Webhook {
  1178  	return graphql.Webhook{
  1179  		ID:                  webhookID,
  1180  		Type:                graphql.WebhookTypeFormationLifecycle,
  1181  		FormationTemplateID: &formationTemplateID,
  1182  		Mode:                &mode,
  1183  	}
  1184  }
  1185  
  1186  func fixFormationLifecycleWebhookGQLModelAsync(webhookID, formationTemplateID string) graphql.Webhook {
  1187  	return fixFormationLifecycleWebhookGQLModel(webhookID, formationTemplateID, graphql.WebhookModeAsyncCallback)
  1188  }
  1189  
  1190  func fixFormationLifecycleInput(formationOperation model.FormationOperation, customerTntID, accountTntExternalID string) *webhook.FormationLifecycleInput {
  1191  	return &webhook.FormationLifecycleInput{
  1192  		Operation:             formationOperation,
  1193  		Formation:             fixFormationModelWithoutError(),
  1194  		CustomerTenantContext: fixCustomerTenantContext(customerTntID, accountTntExternalID),
  1195  	}
  1196  }
  1197  
  1198  func fixFormationNotificationWebhookResponse(actualStatusCode, successStatusCode int, err *string) *webhook.Response {
  1199  	return &webhook.Response{
  1200  		SuccessStatusCode: &successStatusCode,
  1201  		ActualStatusCode:  &actualStatusCode,
  1202  		Error:             err,
  1203  	}
  1204  }
  1205  
  1206  func fixCustomerTenantContext(customerTntID, accountTntID string) *webhook.CustomerTenantContext {
  1207  	return &webhook.CustomerTenantContext{
  1208  		CustomerID: customerTntID,
  1209  		AccountID:  &accountTntID,
  1210  	}
  1211  }
  1212  
  1213  func fixApplicationTemplateModel() *model.ApplicationTemplate {
  1214  	return &model.ApplicationTemplate{
  1215  		ID:                   ApplicationTemplateID,
  1216  		Name:                 "application template",
  1217  		Description:          str.Ptr("some very detailed description"),
  1218  		ApplicationInputJSON: `{"name":"foo","providerName":"compass","description":"Lorem ipsum","labels":{"test":["val","val2"]},"healthCheckURL":"https://foo.bar","webhooks":[{"type":"","url":"webhook1.foo.bar","auth":null},{"type":"","url":"webhook2.foo.bar","auth":null}],"integrationSystemID":"iiiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii"}`,
  1219  	}
  1220  }
  1221  
  1222  func fixApplicationTemplateModelWithID(id string) *model.ApplicationTemplate {
  1223  	template := fixApplicationTemplateModel()
  1224  	template.ID = id
  1225  	return template
  1226  }
  1227  
  1228  func fixRuntimeModel(runtimeID string) *model.Runtime {
  1229  	return &model.Runtime{
  1230  		ID:                runtimeID,
  1231  		Name:              "runtime name",
  1232  		Description:       str.Ptr("some description"),
  1233  		CreationTimestamp: time.Time{},
  1234  	}
  1235  }
  1236  
  1237  func fixRuntimeWithLabels(runtimeID string) *webhook.RuntimeWithLabels {
  1238  	return &webhook.RuntimeWithLabels{
  1239  		Runtime: fixRuntimeModel(runtimeID),
  1240  		Labels:  fixRuntimeLabelsMap(),
  1241  	}
  1242  }
  1243  
  1244  func fixRuntimeContextModel() *model.RuntimeContext {
  1245  	return &model.RuntimeContext{
  1246  		ID:        RuntimeContextID,
  1247  		RuntimeID: RuntimeContextRuntimeID,
  1248  		Key:       "some-key",
  1249  		Value:     "some-value",
  1250  	}
  1251  }
  1252  
  1253  func fixRuntimeContextModelWithRuntimeID(rtID string) *model.RuntimeContext {
  1254  	return &model.RuntimeContext{
  1255  		ID:        RuntimeContext2ID,
  1256  		RuntimeID: rtID,
  1257  		Key:       "some-key",
  1258  		Value:     "some-value",
  1259  	}
  1260  }
  1261  
  1262  func fixFormationModel() *model.Formation {
  1263  	return &model.Formation{
  1264  		ID:                  FormationID,
  1265  		TenantID:            TntInternalID,
  1266  		FormationTemplateID: FormationTemplateID,
  1267  		Name:                testFormationName,
  1268  		State:               model.InitialFormationState,
  1269  		Error:               json.RawMessage(testFormationEmptyError),
  1270  	}
  1271  }
  1272  
  1273  func fixFormationModelWithoutError() *model.Formation {
  1274  	return &model.Formation{
  1275  		ID:                  FormationID,
  1276  		TenantID:            TntInternalID,
  1277  		FormationTemplateID: FormationTemplateID,
  1278  		Name:                testFormationName,
  1279  	}
  1280  }
  1281  
  1282  func fixFormationModelWithState(state model.FormationState) *model.Formation {
  1283  	return &model.Formation{
  1284  		ID:                  FormationID,
  1285  		TenantID:            TntInternalID,
  1286  		FormationTemplateID: FormationTemplateID,
  1287  		Name:                testFormationName,
  1288  		State:               state,
  1289  	}
  1290  }
  1291  
  1292  func fixFormationModelWithStateAndAssignmentError(t *testing.T, state model.FormationState, errMsg string, errCode formationassignment.AssignmentErrorCode) *model.Formation {
  1293  	formationError := formationassignment.AssignmentError{
  1294  		Message:   errMsg,
  1295  		ErrorCode: errCode,
  1296  	}
  1297  
  1298  	marshaledErr, err := json.Marshal(formationError)
  1299  	require.NoError(t, err)
  1300  
  1301  	return &model.Formation{
  1302  		ID:                  FormationID,
  1303  		TenantID:            TntInternalID,
  1304  		FormationTemplateID: FormationTemplateID,
  1305  		Name:                testFormationName,
  1306  		State:               state,
  1307  		Error:               marshaledErr,
  1308  	}
  1309  }
  1310  
  1311  func fixFormationEntity() *formation.Entity {
  1312  	return &formation.Entity{
  1313  		ID:                  FormationID,
  1314  		TenantID:            TntInternalID,
  1315  		FormationTemplateID: FormationTemplateID,
  1316  		Name:                testFormationName,
  1317  		State:               string(model.InitialFormationState),
  1318  		Error:               repo.NewNullableStringFromJSONRawMessage(json.RawMessage("{}")),
  1319  	}
  1320  }
  1321  
  1322  func fixGqlFormation() *graphql.Formation {
  1323  	return &graphql.Formation{
  1324  		ID:                  FormationID,
  1325  		Name:                testFormationName,
  1326  		FormationTemplateID: FormationTemplateID,
  1327  		State:               string(model.ReadyFormationState),
  1328  	}
  1329  }
  1330  
  1331  func fixGqlFormationAssignment(state string, configValue *string) *graphql.FormationAssignment {
  1332  	return &graphql.FormationAssignment{
  1333  		ID:         FormationAssignmentID,
  1334  		Source:     FormationAssignmentSource,
  1335  		SourceType: FormationAssignmentSourceType,
  1336  		Target:     FormationAssignmentTarget,
  1337  		TargetType: FormationAssignmentTargetType,
  1338  		State:      state,
  1339  		Value:      configValue,
  1340  	}
  1341  }
  1342  
  1343  func fixGqlFormationAssignmentWithSuffix(state string, configValue *string, suffix string) *graphql.FormationAssignment {
  1344  	return &graphql.FormationAssignment{
  1345  		ID:         FormationAssignmentID + suffix,
  1346  		Source:     FormationAssignmentSource + suffix,
  1347  		SourceType: graphql.FormationAssignmentType(FormationAssignmentSourceType + suffix),
  1348  		Target:     FormationAssignmentTarget + suffix,
  1349  		TargetType: graphql.FormationAssignmentType(FormationAssignmentTargetType + suffix),
  1350  		State:      state,
  1351  		Value:      configValue,
  1352  	}
  1353  }
  1354  
  1355  func fixFormationAssignmentModel(state string, configValue json.RawMessage) *model.FormationAssignment {
  1356  	return &model.FormationAssignment{
  1357  		ID:          FormationAssignmentID,
  1358  		FormationID: FormationAssignmentFormationID,
  1359  		TenantID:    FormationAssignmentTenantID,
  1360  		Source:      FormationAssignmentSource,
  1361  		SourceType:  FormationAssignmentSourceType,
  1362  		Target:      FormationAssignmentTarget,
  1363  		TargetType:  FormationAssignmentTargetType,
  1364  		State:       state,
  1365  		Value:       configValue,
  1366  	}
  1367  }
  1368  
  1369  func fixFormationAssignmentModelWithParameters(id, formationID, source, target string, sourceType, targetType model.FormationAssignmentType, state model.FormationState) *model.FormationAssignment {
  1370  	return &model.FormationAssignment{
  1371  		ID:          id,
  1372  		FormationID: formationID,
  1373  		Source:      source,
  1374  		SourceType:  sourceType,
  1375  		Target:      target,
  1376  		TargetType:  targetType,
  1377  		State:       string(state),
  1378  	}
  1379  }
  1380  
  1381  func fixFormationAssignmentPairWithNoReverseAssignment(request *webhookclient.FormationAssignmentNotificationRequest, assignment *model.FormationAssignment) *formationassignment.AssignmentMappingPairWithOperation {
  1382  	res := &formationassignment.AssignmentMappingPairWithOperation{
  1383  		AssignmentMappingPair: &formationassignment.AssignmentMappingPair{
  1384  			Assignment: &formationassignment.FormationAssignmentRequestMapping{
  1385  				Request:             request,
  1386  				FormationAssignment: assignment,
  1387  			},
  1388  			ReverseAssignment: &formationassignment.FormationAssignmentRequestMapping{
  1389  				Request:             nil,
  1390  				FormationAssignment: nil,
  1391  			},
  1392  		},
  1393  	}
  1394  
  1395  	switch assignment.State {
  1396  	case string(model.InitialAssignmentState), string(model.CreateErrorAssignmentState):
  1397  		res.Operation = model.AssignFormation
  1398  	case string(model.DeletingAssignmentState), string(model.DeleteErrorAssignmentState):
  1399  		res.Operation = model.UnassignFormation
  1400  	}
  1401  
  1402  	return res
  1403  }
  1404  
  1405  func fixFormationAssignmentModelWithSuffix(state string, configValue json.RawMessage, suffix string) *model.FormationAssignment {
  1406  	return &model.FormationAssignment{
  1407  		ID:          FormationAssignmentID + suffix,
  1408  		FormationID: FormationAssignmentFormationID + suffix,
  1409  		TenantID:    FormationAssignmentTenantID + suffix,
  1410  		Source:      FormationAssignmentSource + suffix,
  1411  		SourceType:  model.FormationAssignmentType(FormationAssignmentSourceType + suffix),
  1412  		Target:      FormationAssignmentTarget + suffix,
  1413  		TargetType:  model.FormationAssignmentType(FormationAssignmentTargetType + suffix),
  1414  		State:       state,
  1415  		Value:       configValue,
  1416  	}
  1417  }
  1418  
  1419  func fixFormationAssignmentPage(fas []*model.FormationAssignment) *model.FormationAssignmentPage {
  1420  	return &model.FormationAssignmentPage{
  1421  		Data: fas,
  1422  		PageInfo: &pagination.Page{
  1423  			StartCursor: "start",
  1424  			EndCursor:   "end",
  1425  			HasNextPage: false,
  1426  		},
  1427  		TotalCount: len(fas),
  1428  	}
  1429  }
  1430  
  1431  func fixGQLFormationAssignmentPage(gqlFAS []*graphql.FormationAssignment) *graphql.FormationAssignmentPage {
  1432  	return &graphql.FormationAssignmentPage{
  1433  		Data: gqlFAS,
  1434  		PageInfo: &graphql.PageInfo{
  1435  			StartCursor: "start",
  1436  			EndCursor:   "end",
  1437  			HasNextPage: false,
  1438  		},
  1439  		TotalCount: len(gqlFAS),
  1440  	}
  1441  }
  1442  
  1443  func fixAssignAppDetails(formationName string) *formationconstraint.AssignFormationOperationDetails {
  1444  	return &formationconstraint.AssignFormationOperationDetails{
  1445  		ResourceType:        model.ApplicationResourceType,
  1446  		ResourceSubtype:     applicationType,
  1447  		ResourceID:          ApplicationID,
  1448  		FormationName:       formationName,
  1449  		FormationType:       testFormationTemplateName,
  1450  		FormationTemplateID: FormationTemplateID,
  1451  		FormationID:         FormationID,
  1452  		TenantID:            TntInternalID,
  1453  	}
  1454  }
  1455  
  1456  func fixAssignRuntimeDetails(formationName string) *formationconstraint.AssignFormationOperationDetails {
  1457  	return &formationconstraint.AssignFormationOperationDetails{
  1458  		ResourceType:        model.RuntimeResourceType,
  1459  		ResourceSubtype:     runtimeType,
  1460  		ResourceID:          RuntimeID,
  1461  		FormationName:       formationName,
  1462  		FormationType:       testFormationTemplateName,
  1463  		FormationTemplateID: FormationTemplateID,
  1464  		FormationID:         FormationID,
  1465  		TenantID:            TntInternalID,
  1466  	}
  1467  }
  1468  
  1469  func fixAssignRuntimeCtxDetails(formationName string) *formationconstraint.AssignFormationOperationDetails {
  1470  	return &formationconstraint.AssignFormationOperationDetails{
  1471  		ResourceType:        model.RuntimeContextResourceType,
  1472  		ResourceSubtype:     runtimeType,
  1473  		ResourceID:          RuntimeContextID,
  1474  		FormationName:       formationName,
  1475  		FormationType:       testFormationTemplateName,
  1476  		FormationTemplateID: FormationTemplateID,
  1477  		FormationID:         FormationID,
  1478  		TenantID:            TntInternalID,
  1479  	}
  1480  }
  1481  
  1482  func fixAssignTenantDetails(formationName string) *formationconstraint.AssignFormationOperationDetails {
  1483  	return &formationconstraint.AssignFormationOperationDetails{
  1484  		ResourceType:        model.TenantResourceType,
  1485  		ResourceSubtype:     "account",
  1486  		ResourceID:          TargetTenant,
  1487  		FormationName:       formationName,
  1488  		FormationType:       testFormationTemplateName,
  1489  		FormationTemplateID: FormationTemplateID,
  1490  		FormationID:         FormationID,
  1491  		TenantID:            TntInternalID,
  1492  	}
  1493  }
  1494  
  1495  func fixDetailsForNotificationStatusReturned(formationType string, operation model.FormationOperation, location formationconstraint.JoinPointLocation, formation *model.Formation) *formationconstraint.NotificationStatusReturnedOperationDetails {
  1496  	return &formationconstraint.NotificationStatusReturnedOperationDetails{
  1497  		ResourceType:    model.FormationResourceType,
  1498  		ResourceSubtype: formationType,
  1499  		Location:        location,
  1500  		Operation:       operation,
  1501  		Formation:       formation,
  1502  	}
  1503  }