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

     1  package formationassignment_test
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	"github.com/kyma-incubator/compass/components/director/pkg/formationconstraint"
     7  
     8  	tnt "github.com/kyma-incubator/compass/components/director/pkg/tenant"
     9  
    10  	databuilderautomock "github.com/kyma-incubator/compass/components/director/internal/domain/webhook/datainputbuilder/automock"
    11  
    12  	"github.com/kyma-incubator/compass/components/director/internal/domain/formationassignment"
    13  	"github.com/kyma-incubator/compass/components/director/internal/domain/formationassignment/automock"
    14  	"github.com/kyma-incubator/compass/components/director/internal/model"
    15  	"github.com/kyma-incubator/compass/components/director/internal/repo"
    16  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    17  	"github.com/kyma-incubator/compass/components/director/pkg/webhook"
    18  	webhookclient "github.com/kyma-incubator/compass/components/director/pkg/webhook_client"
    19  )
    20  
    21  const (
    22  	TestID                  = "c861c3db-1265-4143-a05c-1ced1291d816"
    23  	TestFormationName       = "test-formation"
    24  	TestFormationID         = "a7c0bd01-2441-4ca1-9b5e-a54e74fd7773"
    25  	TestFormationTemplateID = "jjc0bd01-2441-4ca1-9b5e-a54e74fd7773"
    26  	TestTenantID            = "b4d1bd32-dd07-4141-9655-42bc33a4ae37"
    27  	TestSource              = "05e10560-2259-4adf-bb3e-6aee0518f573"
    28  	TestSourceType          = "application"
    29  	TestTarget              = "1c22035a-72e4-4a78-9025-bbcb1f87760b"
    30  	TestTargetType          = "runtimeContext"
    31  	TestStateInitial        = "INITIAL"
    32  	TestReadyState          = "READY"
    33  	TestWebhookID           = "eca98d44-aac0-4e44-898b-c394beab2e94"
    34  	TestReverseWebhookID    = "aecec253-b4d8-416a-be5c-a27677ee5157"
    35  	TntParentID             = "2d11035a-72e4-4a78-9025-bbcb1f87760b"
    36  )
    37  
    38  var (
    39  	TestConfigValueRawJSON        = json.RawMessage(`{"configKey":"configValue"}`)
    40  	TestInvalidConfigValueRawJSON = json.RawMessage(`{invalid}`)
    41  	TestConfigValueStr            = "{\"configKey\":\"configValue\"}"
    42  	fixColumns                    = []string{"id", "formation_id", "tenant_id", "source", "source_type", "target", "target_type", "state", "value"}
    43  
    44  	nilFormationAssignmentModel *model.FormationAssignment
    45  
    46  	faModel  = fixFormationAssignmentModel(TestConfigValueRawJSON)
    47  	faEntity = fixFormationAssignmentEntity(TestConfigValueStr)
    48  
    49  	appSubtype = "app-subtype"
    50  	rtmSubtype = "rtm-subtype"
    51  )
    52  
    53  func fixFormationAssignmentGQLModel(configValue *string) *graphql.FormationAssignment {
    54  	return &graphql.FormationAssignment{
    55  		ID:         TestID,
    56  		Source:     TestSource,
    57  		SourceType: TestSourceType,
    58  		Target:     TestTarget,
    59  		TargetType: TestTargetType,
    60  		State:      TestStateInitial,
    61  		Value:      configValue,
    62  	}
    63  }
    64  
    65  func fixFormationAssignmentModel(configValue json.RawMessage) *model.FormationAssignment {
    66  	return &model.FormationAssignment{
    67  		ID:          TestID,
    68  		FormationID: TestFormationID,
    69  		TenantID:    TestTenantID,
    70  		Source:      TestSource,
    71  		SourceType:  TestSourceType,
    72  		Target:      TestTarget,
    73  		TargetType:  TestTargetType,
    74  		State:       TestStateInitial,
    75  		Value:       configValue,
    76  	}
    77  }
    78  
    79  func fixFormationAssignmentModelWithParameters(id, formationID, tenantID, sourceID, targetID string, sourceType, targetType model.FormationAssignmentType, state string, configValue json.RawMessage) *model.FormationAssignment {
    80  	return &model.FormationAssignment{
    81  		ID:          id,
    82  		FormationID: formationID,
    83  		TenantID:    tenantID,
    84  		Source:      sourceID,
    85  		SourceType:  sourceType,
    86  		Target:      targetID,
    87  		TargetType:  targetType,
    88  		State:       state,
    89  		Value:       configValue,
    90  	}
    91  }
    92  
    93  func fixFormationAssignmentModelWithFormationID(formationID string) *model.FormationAssignment {
    94  	return &model.FormationAssignment{
    95  		ID:          TestID,
    96  		FormationID: formationID,
    97  		TenantID:    TestTenantID,
    98  		Source:      TestSource,
    99  		SourceType:  TestSourceType,
   100  		Target:      TestTarget,
   101  		TargetType:  TestTargetType,
   102  		State:       TestStateInitial,
   103  		Value:       TestConfigValueRawJSON,
   104  	}
   105  }
   106  
   107  func fixFormationAssignmentModelWithIDAndTenantID(fa *model.FormationAssignment) *model.FormationAssignment {
   108  	return &model.FormationAssignment{
   109  		ID:          TestID,
   110  		FormationID: fa.FormationID,
   111  		TenantID:    TestTenantID,
   112  		Source:      fa.Source,
   113  		SourceType:  fa.SourceType,
   114  		Target:      fa.Target,
   115  		TargetType:  fa.TargetType,
   116  		State:       fa.State,
   117  		Value:       fa.Value,
   118  	}
   119  }
   120  
   121  func fixFormationAssignmentModelInput(configValue json.RawMessage) *model.FormationAssignmentInput {
   122  	return &model.FormationAssignmentInput{
   123  		FormationID: TestFormationID,
   124  		Source:      TestSource,
   125  		SourceType:  TestSourceType,
   126  		Target:      TestTarget,
   127  		TargetType:  TestTargetType,
   128  		State:       TestStateInitial,
   129  		Value:       configValue,
   130  	}
   131  }
   132  
   133  func fixFormationAssignmentEntity(configValue string) *formationassignment.Entity {
   134  	return &formationassignment.Entity{
   135  		ID:          TestID,
   136  		FormationID: TestFormationID,
   137  		TenantID:    TestTenantID,
   138  		Source:      TestSource,
   139  		SourceType:  TestSourceType,
   140  		Target:      TestTarget,
   141  		TargetType:  TestTargetType,
   142  		State:       TestStateInitial,
   143  		Value:       repo.NewValidNullableString(configValue),
   144  	}
   145  }
   146  
   147  func fixFormationAssignmentEntityWithFormationID(formationID string) *formationassignment.Entity {
   148  	return &formationassignment.Entity{
   149  		ID:          TestID,
   150  		FormationID: formationID,
   151  		TenantID:    TestTenantID,
   152  		Source:      TestSource,
   153  		SourceType:  TestSourceType,
   154  		Target:      TestTarget,
   155  		TargetType:  TestTargetType,
   156  		State:       TestStateInitial,
   157  		Value:       repo.NewValidNullableString(TestConfigValueStr),
   158  	}
   159  }
   160  
   161  func fixAppTenantMappingWebhookInput(formationID string, sourceApp, targetApp *webhook.ApplicationWithLabels, sourceAppTemplate, targetAppTemplate *webhook.ApplicationTemplateWithLabels, customerTenantContext *webhook.CustomerTenantContext, assignment, reverseAssignment *webhook.FormationAssignment) *webhook.ApplicationTenantMappingInput {
   162  	return &webhook.ApplicationTenantMappingInput{
   163  		Operation:                 model.AssignFormation,
   164  		FormationID:               formationID,
   165  		SourceApplicationTemplate: sourceAppTemplate,
   166  		SourceApplication:         sourceApp,
   167  		TargetApplicationTemplate: targetAppTemplate,
   168  		TargetApplication:         targetApp,
   169  		CustomerTenantContext:     customerTenantContext,
   170  		Assignment:                assignment,
   171  		ReverseAssignment:         reverseAssignment,
   172  	}
   173  }
   174  
   175  func fixFormationConfigurationChangeInput(formationID string, appTemplate *webhook.ApplicationTemplateWithLabels, app *webhook.ApplicationWithLabels, runtime *webhook.RuntimeWithLabels, runtimeCtx *webhook.RuntimeContextWithLabels, customerTenantContext *webhook.CustomerTenantContext, assignment, reverseAssignment *webhook.FormationAssignment) *webhook.FormationConfigurationChangeInput {
   176  	return &webhook.FormationConfigurationChangeInput{
   177  		Operation:             model.AssignFormation,
   178  		FormationID:           formationID,
   179  		ApplicationTemplate:   appTemplate,
   180  		Application:           app,
   181  		Runtime:               runtime,
   182  		RuntimeContext:        runtimeCtx,
   183  		CustomerTenantContext: customerTenantContext,
   184  		Assignment:            assignment,
   185  		ReverseAssignment:     reverseAssignment,
   186  	}
   187  }
   188  
   189  func fixModelBusinessTenantMappingWithType(t tnt.Type) *model.BusinessTenantMapping {
   190  	return &model.BusinessTenantMapping{
   191  		ID:             TestTenantID,
   192  		Name:           "test-name",
   193  		ExternalTenant: TestTenantID,
   194  		Parent:         TntParentID,
   195  		Type:           t,
   196  		Provider:       "Compass",
   197  		Status:         tnt.Active,
   198  	}
   199  }
   200  
   201  func fixAssignmentMappingPairWithID(id string) *formationassignment.AssignmentMappingPairWithOperation {
   202  	return &formationassignment.AssignmentMappingPairWithOperation{
   203  		AssignmentMappingPair: &formationassignment.AssignmentMappingPair{
   204  			Assignment: &formationassignment.FormationAssignmentRequestMapping{
   205  				Request:             nil,
   206  				FormationAssignment: &model.FormationAssignment{ID: id, Source: "source"},
   207  			},
   208  			ReverseAssignment: nil,
   209  		},
   210  		Operation: model.AssignFormation,
   211  	}
   212  }
   213  
   214  func fixAssignmentMappingPairWithAssignmentAndRequest(assignment *model.FormationAssignment, req *webhookclient.FormationAssignmentNotificationRequest) *formationassignment.AssignmentMappingPairWithOperation {
   215  	return &formationassignment.AssignmentMappingPairWithOperation{
   216  		AssignmentMappingPair: &formationassignment.AssignmentMappingPair{
   217  			Assignment: &formationassignment.FormationAssignmentRequestMapping{
   218  				Request:             req,
   219  				FormationAssignment: assignment,
   220  			},
   221  			ReverseAssignment: nil,
   222  		},
   223  		Operation: model.AssignFormation,
   224  	}
   225  }
   226  
   227  func fixAssignmentMappingPairWithAssignmentAndRequestWithReverse(assignment, reverseAssignment *model.FormationAssignment, req, reverseReq *webhookclient.FormationAssignmentNotificationRequest) *formationassignment.AssignmentMappingPairWithOperation {
   228  	return &formationassignment.AssignmentMappingPairWithOperation{
   229  		AssignmentMappingPair: &formationassignment.AssignmentMappingPair{
   230  			Assignment: &formationassignment.FormationAssignmentRequestMapping{
   231  				Request:             req,
   232  				FormationAssignment: assignment,
   233  			},
   234  			ReverseAssignment: &formationassignment.FormationAssignmentRequestMapping{
   235  				Request:             reverseReq,
   236  				FormationAssignment: reverseAssignment,
   237  			},
   238  		},
   239  		Operation: model.AssignFormation,
   240  	}
   241  }
   242  
   243  func fixExtendedFormationAssignmentNotificationReq(reqWebhook *webhookclient.FormationAssignmentNotificationRequest, fa *model.FormationAssignment) *webhookclient.FormationAssignmentNotificationRequestExt {
   244  	return &webhookclient.FormationAssignmentNotificationRequestExt{
   245  		FormationAssignmentNotificationRequest: reqWebhook,
   246  		Operation:                              assignOperation,
   247  		FormationAssignment:                    fa,
   248  		ReverseFormationAssignment:             &model.FormationAssignment{},
   249  		Formation:                              formation,
   250  		TargetSubtype:                          appSubtype,
   251  	}
   252  }
   253  
   254  func fixReverseFormationAssignment(assignment *model.FormationAssignment) *model.FormationAssignment {
   255  	return &model.FormationAssignment{
   256  		ID:          assignment.ID,
   257  		FormationID: assignment.FormationID,
   258  		TenantID:    assignment.TenantID,
   259  		Source:      assignment.Target,
   260  		SourceType:  assignment.TargetType,
   261  		Target:      assignment.Source,
   262  		TargetType:  assignment.SourceType,
   263  		State:       assignment.State,
   264  		Value:       assignment.Value,
   265  	}
   266  }
   267  
   268  func fixConvertFAFromModel(formationAssignment *model.FormationAssignment) *webhook.FormationAssignment {
   269  	return &webhook.FormationAssignment{
   270  		ID:          formationAssignment.ID,
   271  		FormationID: formationAssignment.FormationID,
   272  		TenantID:    formationAssignment.TenantID,
   273  		Source:      formationAssignment.Source,
   274  		SourceType:  formationAssignment.SourceType,
   275  		Target:      formationAssignment.Target,
   276  		TargetType:  formationAssignment.TargetType,
   277  		State:       formationAssignment.State,
   278  		Value:       string(formationAssignment.Value),
   279  	}
   280  }
   281  
   282  func fixFormationAssignmentsWithObjectTypeAndID(objectType model.FormationAssignmentType, objectID, appID, rtmID, rtmCtxID string) []*model.FormationAssignment {
   283  	return []*model.FormationAssignment{
   284  		{
   285  			ID:          "ID1",
   286  			FormationID: "ID",
   287  			TenantID:    TestTenantID,
   288  			Source:      objectID,
   289  			SourceType:  objectType,
   290  			Target:      appID,
   291  			TargetType:  model.FormationAssignmentTypeApplication,
   292  			State:       string(model.InitialAssignmentState),
   293  			Value:       nil,
   294  		},
   295  		{
   296  			ID:          "ID2",
   297  			FormationID: "ID",
   298  			TenantID:    TestTenantID,
   299  			Source:      appID,
   300  			SourceType:  model.FormationAssignmentTypeApplication,
   301  			Target:      objectID,
   302  			TargetType:  objectType,
   303  			State:       string(model.InitialAssignmentState),
   304  			Value:       nil,
   305  		},
   306  		{
   307  			ID:          "ID3",
   308  			FormationID: "ID",
   309  			TenantID:    TestTenantID,
   310  			Source:      objectID,
   311  			SourceType:  objectType,
   312  			Target:      rtmID,
   313  			TargetType:  model.FormationAssignmentTypeRuntime,
   314  			State:       string(model.InitialAssignmentState),
   315  			Value:       nil,
   316  		},
   317  		{
   318  			ID:          "ID4",
   319  			FormationID: "ID",
   320  			TenantID:    TestTenantID,
   321  			Source:      rtmID,
   322  			SourceType:  model.FormationAssignmentTypeRuntime,
   323  			Target:      objectID,
   324  			TargetType:  objectType,
   325  			State:       string(model.InitialAssignmentState),
   326  			Value:       nil,
   327  		},
   328  		{
   329  			ID:          "ID5",
   330  			FormationID: "ID",
   331  			TenantID:    TestTenantID,
   332  			Source:      objectID,
   333  			SourceType:  objectType,
   334  			Target:      rtmCtxID,
   335  			TargetType:  model.FormationAssignmentTypeRuntimeContext,
   336  			State:       string(model.InitialAssignmentState),
   337  			Value:       nil,
   338  		},
   339  		{
   340  			ID:          "ID6",
   341  			FormationID: "ID",
   342  			TenantID:    TestTenantID,
   343  			Source:      rtmCtxID,
   344  			SourceType:  model.FormationAssignmentTypeRuntimeContext,
   345  			Target:      objectID,
   346  			TargetType:  objectType,
   347  			State:       string(model.InitialAssignmentState),
   348  			Value:       nil,
   349  		},
   350  		// Self formation assignments
   351  		{
   352  			ID:          "ID7",
   353  			FormationID: "ID",
   354  			TenantID:    TestTenantID,
   355  			Source:      objectID,
   356  			SourceType:  objectType,
   357  			Target:      objectID,
   358  			TargetType:  objectType,
   359  			State:       string(model.ReadyAssignmentState),
   360  			Value:       nil,
   361  		},
   362  	}
   363  }
   364  
   365  func fixFormationAssignmentsForSelf(appID, rtmID, rtmCtxID string) []*model.FormationAssignment {
   366  	return []*model.FormationAssignment{
   367  		{
   368  			ID:          "ID8",
   369  			FormationID: "ID",
   370  			TenantID:    TestTenantID,
   371  			Source:      appID,
   372  			SourceType:  model.FormationAssignmentTypeApplication,
   373  			Target:      appID,
   374  			TargetType:  model.FormationAssignmentTypeApplication,
   375  			State:       string(model.ReadyAssignmentState),
   376  			Value:       nil,
   377  		},
   378  		{
   379  			ID:          "ID9",
   380  			FormationID: "ID",
   381  			TenantID:    TestTenantID,
   382  			Source:      rtmID,
   383  			SourceType:  model.FormationAssignmentTypeRuntime,
   384  			Target:      rtmID,
   385  			TargetType:  model.FormationAssignmentTypeRuntime,
   386  			State:       string(model.ReadyAssignmentState),
   387  			Value:       nil,
   388  		},
   389  		{
   390  			ID:          "ID10",
   391  			FormationID: "ID",
   392  			TenantID:    TestTenantID,
   393  			Source:      rtmCtxID,
   394  			SourceType:  model.FormationAssignmentTypeRuntimeContext,
   395  			Target:      rtmCtxID,
   396  			TargetType:  model.FormationAssignmentTypeRuntimeContext,
   397  			State:       string(model.ReadyAssignmentState),
   398  			Value:       nil,
   399  		},
   400  	}
   401  }
   402  
   403  func fixFormationAssignmentsForRtmCtxWithAppAndRtmCtx(objectType model.FormationAssignmentType, objectID, appID, rtmCtxID string) []*model.FormationAssignment {
   404  	return []*model.FormationAssignment{
   405  		{
   406  			ID:          "ID1",
   407  			FormationID: "ID",
   408  			TenantID:    TestTenantID,
   409  			Source:      objectID,
   410  			SourceType:  objectType,
   411  			Target:      appID,
   412  			TargetType:  model.FormationAssignmentTypeApplication,
   413  			State:       string(model.InitialAssignmentState),
   414  			Value:       nil,
   415  		},
   416  		{
   417  			ID:          "ID2",
   418  			FormationID: "ID",
   419  			TenantID:    TestTenantID,
   420  			Source:      appID,
   421  			SourceType:  model.FormationAssignmentTypeApplication,
   422  			Target:      objectID,
   423  			TargetType:  objectType,
   424  			State:       string(model.InitialAssignmentState),
   425  			Value:       nil,
   426  		},
   427  		{
   428  			ID:          "ID3",
   429  			FormationID: "ID",
   430  			TenantID:    TestTenantID,
   431  			Source:      objectID,
   432  			SourceType:  objectType,
   433  			Target:      rtmCtxID,
   434  			TargetType:  model.FormationAssignmentTypeRuntimeContext,
   435  			State:       string(model.InitialAssignmentState),
   436  			Value:       nil,
   437  		},
   438  		{
   439  			ID:          "ID4",
   440  			FormationID: "ID",
   441  			TenantID:    TestTenantID,
   442  			Source:      rtmCtxID,
   443  			SourceType:  model.FormationAssignmentTypeRuntimeContext,
   444  			Target:      objectID,
   445  			TargetType:  objectType,
   446  			State:       string(model.InitialAssignmentState),
   447  			Value:       nil,
   448  		},
   449  		{
   450  			ID:          "ID5",
   451  			FormationID: "ID",
   452  			TenantID:    TestTenantID,
   453  			Source:      objectID,
   454  			SourceType:  objectType,
   455  			Target:      objectID,
   456  			TargetType:  objectType,
   457  			State:       string(model.ReadyAssignmentState),
   458  			Value:       nil,
   459  		},
   460  	}
   461  }
   462  
   463  func fixNotificationRequestAndReverseRequest(objectID, object2ID string, participants []string, assignment, assignmentReverse *model.FormationAssignment, webhookType, reverseWebhookType string, hasReverseWebhook bool) ([]*webhookclient.FormationAssignmentNotificationRequest, *automock.TemplateInput, *automock.TemplateInput) {
   464  	var request *webhookclient.FormationAssignmentNotificationRequest
   465  	var requestReverse *webhookclient.FormationAssignmentNotificationRequest
   466  
   467  	templateInput := &automock.TemplateInput{}
   468  	templateInputReverse := &automock.TemplateInput{}
   469  
   470  	webhook := graphql.Webhook{}
   471  	webhookReverse := graphql.Webhook{}
   472  	switch webhookType {
   473  	case "application":
   474  		webhook.ApplicationID = &objectID
   475  	case "runtime":
   476  		webhook.RuntimeID = &objectID
   477  	}
   478  
   479  	templateInput.Mock.On("GetParticipantsIDs").Return(participants).Times(1)
   480  	templateInput.Mock.On("SetAssignment", assignment).Times(2)
   481  	templateInput.Mock.On("SetReverseAssignment", assignmentReverse).Times(2)
   482  
   483  	request = &webhookclient.FormationAssignmentNotificationRequest{Webhook: webhook, Object: templateInput}
   484  
   485  	if hasReverseWebhook {
   486  		switch reverseWebhookType {
   487  		case "application":
   488  			webhookReverse.ApplicationID = &object2ID
   489  		case "runtime":
   490  			webhookReverse.RuntimeID = &object2ID
   491  		}
   492  
   493  		templateInputReverse.Mock.On("GetParticipantsIDs").Return(participants).Times(1)
   494  		templateInputReverse.Mock.On("SetAssignment", assignmentReverse).Times(2)
   495  		templateInputReverse.Mock.On("SetReverseAssignment", assignment).Times(2)
   496  
   497  		requestReverse = &webhookclient.FormationAssignmentNotificationRequest{Webhook: webhookReverse, Object: templateInputReverse}
   498  	} else {
   499  		requestReverse = nil
   500  	}
   501  
   502  	return []*webhookclient.FormationAssignmentNotificationRequest{request, requestReverse}, templateInput, templateInputReverse
   503  }
   504  
   505  func fixNotificationStatusReturnedDetails(resourceType model.ResourceType, resourceSubtype string, fa, reverseFa *model.FormationAssignment, location formationconstraint.JoinPointLocation) *formationconstraint.NotificationStatusReturnedOperationDetails {
   506  	return &formationconstraint.NotificationStatusReturnedOperationDetails{
   507  		ResourceType:               resourceType,
   508  		ResourceSubtype:            resourceSubtype,
   509  		Location:                   location,
   510  		Operation:                  assignOperation,
   511  		FormationAssignment:        fa,
   512  		ReverseFormationAssignment: reverseFa,
   513  		Formation:                  formation,
   514  	}
   515  }
   516  
   517  func fixUUIDService() *automock.UIDService {
   518  	uidSvc := &automock.UIDService{}
   519  	uidSvc.On("Generate").Return(TestID)
   520  	return uidSvc
   521  }
   522  
   523  func unusedFormationAssignmentRepository() *automock.FormationAssignmentRepository {
   524  	return &automock.FormationAssignmentRepository{}
   525  }
   526  
   527  func unusedUIDService() *automock.UIDService {
   528  	return &automock.UIDService{}
   529  }
   530  
   531  func unusedRuntimeRepository() *automock.RuntimeRepository {
   532  	return &automock.RuntimeRepository{}
   533  }
   534  
   535  func unusedRuntimeContextRepository() *automock.RuntimeContextRepository {
   536  	return &automock.RuntimeContextRepository{}
   537  }
   538  
   539  func unusedWebhookDataInputBuilder() *databuilderautomock.DataInputBuilder {
   540  	return &databuilderautomock.DataInputBuilder{}
   541  }
   542  
   543  func unusedWebhookRepo() *automock.WebhookRepository {
   544  	return &automock.WebhookRepository{}
   545  }
   546  
   547  func unusedFormationRepo() *automock.FormationRepository {
   548  	return &automock.FormationRepository{}
   549  }
   550  
   551  func unusedTenantRepo() *automock.TenantRepository {
   552  	return &automock.TenantRepository{}
   553  }
   554  
   555  func unusedNotificationBuilder() *automock.NotificationBuilder {
   556  	return &automock.NotificationBuilder{}
   557  }
   558  
   559  func convertFormationAssignmentFromModel(formationAssignment *model.FormationAssignment) *webhook.FormationAssignment {
   560  	config := string(formationAssignment.Value)
   561  	if config == "" || formationAssignment.State == string(model.CreateErrorAssignmentState) || formationAssignment.State == string(model.DeleteErrorAssignmentState) {
   562  		config = "\"\""
   563  	}
   564  	return &webhook.FormationAssignment{
   565  		ID:          formationAssignment.ID,
   566  		FormationID: formationAssignment.FormationID,
   567  		TenantID:    formationAssignment.TenantID,
   568  		Source:      formationAssignment.Source,
   569  		SourceType:  formationAssignment.SourceType,
   570  		Target:      formationAssignment.Target,
   571  		TargetType:  formationAssignment.TargetType,
   572  		State:       formationAssignment.State,
   573  		Value:       config,
   574  	}
   575  }