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

     1  package formation_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/kyma-incubator/compass/components/director/internal/domain/formation"
     8  	"github.com/kyma-incubator/compass/components/director/internal/domain/formation/automock"
     9  	"github.com/kyma-incubator/compass/components/director/internal/domain/formationassignment"
    10  	"github.com/kyma-incubator/compass/components/director/internal/domain/labeldef"
    11  	"github.com/kyma-incubator/compass/components/director/internal/model"
    12  	"github.com/kyma-incubator/compass/components/director/pkg/formationconstraint"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/mock"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  var (
    19  	preDetails  = fixDetailsForNotificationStatusReturned("formationType", model.DeleteFormation, formationconstraint.PreNotificationStatusReturned, &modelFormation)
    20  	postDetails = fixDetailsForNotificationStatusReturned("formationType", model.DeleteFormation, formationconstraint.PostNotificationStatusReturned, &modelFormation)
    21  )
    22  
    23  func TestUpdateWithConstraints(t *testing.T) {
    24  	ctx := context.Background()
    25  
    26  	testCases := []struct {
    27  		Name               string
    28  		FormationRepoFn    func() *automock.FormationRepository
    29  		NotificationsSvcFn func() *automock.NotificationsService
    30  		ConstraintEngineFn func() *automock.ConstraintEngine
    31  		InputFormation     *model.Formation
    32  		FormationOperation model.FormationOperation
    33  		ExpectedErrMessage string
    34  	}{
    35  		{
    36  			Name: "Success",
    37  			FormationRepoFn: func() *automock.FormationRepository {
    38  				repo := &automock.FormationRepository{}
    39  				repo.On("Update", ctx, &modelFormation).Return(nil).Once()
    40  				return repo
    41  			},
    42  			NotificationsSvcFn: func() *automock.NotificationsService {
    43  				notificationsSvc := &automock.NotificationsService{}
    44  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
    45  				return notificationsSvc
    46  			},
    47  			ConstraintEngineFn: func() *automock.ConstraintEngine {
    48  				engine := &automock.ConstraintEngine{}
    49  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
    50  				engine.On("EnforceConstraints", ctx, formationconstraint.PostNotificationStatusReturned, postDetails, postDetails.Formation.FormationTemplateID).Return(nil).Once()
    51  				return engine
    52  			},
    53  			InputFormation:     &modelFormation,
    54  			FormationOperation: model.DeleteFormation,
    55  		},
    56  		{
    57  			Name: "Returns error when enforcing post constraints fails",
    58  			FormationRepoFn: func() *automock.FormationRepository {
    59  				repo := &automock.FormationRepository{}
    60  				repo.On("Update", ctx, &modelFormation).Return(nil).Once()
    61  				return repo
    62  			},
    63  			NotificationsSvcFn: func() *automock.NotificationsService {
    64  				notificationsSvc := &automock.NotificationsService{}
    65  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
    66  				return notificationsSvc
    67  			},
    68  			ConstraintEngineFn: func() *automock.ConstraintEngine {
    69  				engine := &automock.ConstraintEngine{}
    70  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
    71  				engine.On("EnforceConstraints", ctx, formationconstraint.PostNotificationStatusReturned, postDetails, postDetails.Formation.FormationTemplateID).Return(testErr).Once()
    72  				return engine
    73  			},
    74  			InputFormation:     &modelFormation,
    75  			FormationOperation: model.DeleteFormation,
    76  			ExpectedErrMessage: testErr.Error(),
    77  		},
    78  		{
    79  			Name: "Returns error when update fails",
    80  			FormationRepoFn: func() *automock.FormationRepository {
    81  				repo := &automock.FormationRepository{}
    82  				repo.On("Update", ctx, &modelFormation).Return(testErr).Once()
    83  				return repo
    84  			},
    85  			NotificationsSvcFn: func() *automock.NotificationsService {
    86  				notificationsSvc := &automock.NotificationsService{}
    87  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
    88  				return notificationsSvc
    89  			},
    90  			ConstraintEngineFn: func() *automock.ConstraintEngine {
    91  				engine := &automock.ConstraintEngine{}
    92  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
    93  				return engine
    94  			},
    95  			InputFormation:     &modelFormation,
    96  			FormationOperation: model.DeleteFormation,
    97  			ExpectedErrMessage: testErr.Error(),
    98  		},
    99  		{
   100  			Name: "Returns error when enforcing pre constraints fails",
   101  			NotificationsSvcFn: func() *automock.NotificationsService {
   102  				notificationsSvc := &automock.NotificationsService{}
   103  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   104  				return notificationsSvc
   105  			},
   106  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   107  				engine := &automock.ConstraintEngine{}
   108  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(testErr).Once()
   109  				return engine
   110  			},
   111  			InputFormation:     &modelFormation,
   112  			FormationOperation: model.DeleteFormation,
   113  			ExpectedErrMessage: testErr.Error(),
   114  		},
   115  		{
   116  			Name: "Returns error when enforcing pre constraints fails",
   117  			NotificationsSvcFn: func() *automock.NotificationsService {
   118  				notificationsSvc := &automock.NotificationsService{}
   119  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(nil, testErr).Once()
   120  				return notificationsSvc
   121  			},
   122  			InputFormation:     &modelFormation,
   123  			FormationOperation: model.DeleteFormation,
   124  			ExpectedErrMessage: testErr.Error(),
   125  		},
   126  	}
   127  
   128  	for _, testCase := range testCases {
   129  		t.Run(testCase.Name, func(t *testing.T) {
   130  			// GIVEN
   131  			formationRepo := &automock.FormationRepository{}
   132  			if testCase.FormationRepoFn != nil {
   133  				formationRepo = testCase.FormationRepoFn()
   134  			}
   135  			notificationsSvc := &automock.NotificationsService{}
   136  			if testCase.NotificationsSvcFn != nil {
   137  				notificationsSvc = testCase.NotificationsSvcFn()
   138  			}
   139  			engine := &automock.ConstraintEngine{}
   140  			if testCase.ConstraintEngineFn != nil {
   141  				engine = testCase.ConstraintEngineFn()
   142  			}
   143  
   144  			svc := formation.NewFormationStatusService(formationRepo, nil, nil, notificationsSvc, engine)
   145  
   146  			// WHEN
   147  			err := svc.UpdateWithConstraints(ctx, testCase.InputFormation, testCase.FormationOperation)
   148  
   149  			// THEN
   150  			if testCase.ExpectedErrMessage == "" {
   151  				require.NoError(t, err)
   152  			} else {
   153  				require.Error(t, err)
   154  				require.Contains(t, err.Error(), testCase.ExpectedErrMessage)
   155  			}
   156  
   157  			mock.AssertExpectationsForObjects(t, formationRepo, notificationsSvc, engine)
   158  		})
   159  	}
   160  }
   161  
   162  func TestSetFormationToErrorStateWithConstraints(t *testing.T) {
   163  	ctx := context.Background()
   164  
   165  	testCases := []struct {
   166  		Name               string
   167  		FormationRepoFn    func() *automock.FormationRepository
   168  		NotificationsSvcFn func() *automock.NotificationsService
   169  		ConstraintEngineFn func() *automock.ConstraintEngine
   170  		InputFormation     *model.Formation
   171  		FormationOperation model.FormationOperation
   172  		ExpectedErrMessage string
   173  	}{
   174  		{
   175  			Name: "Success",
   176  			FormationRepoFn: func() *automock.FormationRepository {
   177  				repo := &automock.FormationRepository{}
   178  				repo.On("Update", ctx, &modelFormation).Return(nil).Once()
   179  				return repo
   180  			},
   181  			NotificationsSvcFn: func() *automock.NotificationsService {
   182  				notificationsSvc := &automock.NotificationsService{}
   183  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   184  				return notificationsSvc
   185  			},
   186  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   187  				engine := &automock.ConstraintEngine{}
   188  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
   189  				engine.On("EnforceConstraints", ctx, formationconstraint.PostNotificationStatusReturned, postDetails, postDetails.Formation.FormationTemplateID).Return(nil).Once()
   190  				return engine
   191  			},
   192  			InputFormation:     &modelFormation,
   193  			FormationOperation: model.DeleteFormation,
   194  		},
   195  		{
   196  			Name: "Returns error when update fails",
   197  			FormationRepoFn: func() *automock.FormationRepository {
   198  				repo := &automock.FormationRepository{}
   199  				repo.On("Update", ctx, &modelFormation).Return(nil).Once()
   200  				return repo
   201  			},
   202  			NotificationsSvcFn: func() *automock.NotificationsService {
   203  				notificationsSvc := &automock.NotificationsService{}
   204  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   205  				return notificationsSvc
   206  			},
   207  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   208  				engine := &automock.ConstraintEngine{}
   209  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
   210  				engine.On("EnforceConstraints", ctx, formationconstraint.PostNotificationStatusReturned, postDetails, postDetails.Formation.FormationTemplateID).Return(testErr).Once()
   211  				return engine
   212  			},
   213  			InputFormation:     &modelFormation,
   214  			FormationOperation: model.DeleteFormation,
   215  			ExpectedErrMessage: testErr.Error(),
   216  		},
   217  	}
   218  
   219  	for _, testCase := range testCases {
   220  		t.Run(testCase.Name, func(t *testing.T) {
   221  			// GIVEN
   222  			formationRepo := &automock.FormationRepository{}
   223  			if testCase.FormationRepoFn != nil {
   224  				formationRepo = testCase.FormationRepoFn()
   225  			}
   226  			notificationsSvc := &automock.NotificationsService{}
   227  			if testCase.NotificationsSvcFn != nil {
   228  				notificationsSvc = testCase.NotificationsSvcFn()
   229  			}
   230  			engine := &automock.ConstraintEngine{}
   231  			if testCase.ConstraintEngineFn != nil {
   232  				engine = testCase.ConstraintEngineFn()
   233  			}
   234  
   235  			svc := formation.NewFormationStatusService(formationRepo, nil, nil, notificationsSvc, engine)
   236  
   237  			// WHEN
   238  			err := svc.SetFormationToErrorStateWithConstraints(ctx, testCase.InputFormation, ErrMsg, formationassignment.TechnicalError, model.CreateErrorFormationState, testCase.FormationOperation)
   239  
   240  			// THEN
   241  			if testCase.ExpectedErrMessage == "" {
   242  				require.NoError(t, err)
   243  			} else {
   244  				require.Error(t, err)
   245  				require.Contains(t, err.Error(), testCase.ExpectedErrMessage)
   246  			}
   247  
   248  			mock.AssertExpectationsForObjects(t, formationRepo, notificationsSvc, engine)
   249  		})
   250  	}
   251  }
   252  
   253  func TestDeleteFormationEntityAndScenariosWithConstraints(t *testing.T) {
   254  	ctx := context.Background()
   255  
   256  	testSchema, err := labeldef.NewSchemaForFormations([]string{testScenario, testFormationName})
   257  	assert.NoError(t, err)
   258  	testSchemaLblDef := fixScenariosLabelDefinition(TntInternalID, testSchema)
   259  
   260  	newSchema, err := labeldef.NewSchemaForFormations([]string{testScenario})
   261  	assert.NoError(t, err)
   262  	newSchemaLblDef := fixScenariosLabelDefinition(TntInternalID, newSchema)
   263  
   264  	nilSchemaLblDef := fixScenariosLabelDefinition(TntInternalID, testSchema)
   265  	nilSchemaLblDef.Schema = nil
   266  
   267  	testCases := []struct {
   268  		Name                 string
   269  		FormationRepoFn      func() *automock.FormationRepository
   270  		LabelDefRepositoryFn func() *automock.LabelDefRepository
   271  		LabelDefServiceFn    func() *automock.LabelDefService
   272  		NotificationsSvcFn   func() *automock.NotificationsService
   273  		ConstraintEngineFn   func() *automock.ConstraintEngine
   274  		InputFormation       *model.Formation
   275  		FormationOperation   model.FormationOperation
   276  		ExpectedErrMessage   string
   277  	}{
   278  		{
   279  			Name: "Success",
   280  			FormationRepoFn: func() *automock.FormationRepository {
   281  				repo := &automock.FormationRepository{}
   282  				repo.On("DeleteByName", ctx, TntInternalID, modelFormation.Name).Return(nil).Once()
   283  				return repo
   284  			},
   285  			LabelDefRepositoryFn: func() *automock.LabelDefRepository {
   286  				labelDefRepo := &automock.LabelDefRepository{}
   287  				labelDefRepo.On("GetByKey", ctx, TntInternalID, model.ScenariosKey).Return(&testSchemaLblDef, nil).Once()
   288  				labelDefRepo.On("UpdateWithVersion", ctx, newSchemaLblDef).Return(nil).Once()
   289  				return labelDefRepo
   290  			},
   291  			LabelDefServiceFn: func() *automock.LabelDefService {
   292  				labelDefService := &automock.LabelDefService{}
   293  				labelDefService.On("ValidateExistingLabelsAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(nil).Once()
   294  				labelDefService.On("ValidateAutomaticScenarioAssignmentAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(nil).Once()
   295  				return labelDefService
   296  			},
   297  			NotificationsSvcFn: func() *automock.NotificationsService {
   298  				notificationsSvc := &automock.NotificationsService{}
   299  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   300  				return notificationsSvc
   301  			},
   302  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   303  				engine := &automock.ConstraintEngine{}
   304  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
   305  				engine.On("EnforceConstraints", ctx, formationconstraint.PostNotificationStatusReturned, postDetails, postDetails.Formation.FormationTemplateID).Return(nil).Once()
   306  				return engine
   307  			},
   308  			InputFormation:     &modelFormation,
   309  			FormationOperation: model.DeleteFormation,
   310  		},
   311  		{
   312  			Name: "Returns error when enforcing post constraints fails",
   313  			FormationRepoFn: func() *automock.FormationRepository {
   314  				repo := &automock.FormationRepository{}
   315  				repo.On("DeleteByName", ctx, TntInternalID, modelFormation.Name).Return(nil).Once()
   316  				return repo
   317  			},
   318  			LabelDefRepositoryFn: func() *automock.LabelDefRepository {
   319  				labelDefRepo := &automock.LabelDefRepository{}
   320  				labelDefRepo.On("GetByKey", ctx, TntInternalID, model.ScenariosKey).Return(&testSchemaLblDef, nil).Once()
   321  				labelDefRepo.On("UpdateWithVersion", ctx, newSchemaLblDef).Return(nil).Once()
   322  				return labelDefRepo
   323  			},
   324  			LabelDefServiceFn: func() *automock.LabelDefService {
   325  				labelDefService := &automock.LabelDefService{}
   326  				labelDefService.On("ValidateExistingLabelsAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(nil).Once()
   327  				labelDefService.On("ValidateAutomaticScenarioAssignmentAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(nil).Once()
   328  				return labelDefService
   329  			},
   330  			NotificationsSvcFn: func() *automock.NotificationsService {
   331  				notificationsSvc := &automock.NotificationsService{}
   332  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   333  				return notificationsSvc
   334  			},
   335  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   336  				engine := &automock.ConstraintEngine{}
   337  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
   338  				engine.On("EnforceConstraints", ctx, formationconstraint.PostNotificationStatusReturned, postDetails, postDetails.Formation.FormationTemplateID).Return(testErr).Once()
   339  				return engine
   340  			},
   341  			InputFormation:     &modelFormation,
   342  			FormationOperation: model.DeleteFormation,
   343  			ExpectedErrMessage: testErr.Error(),
   344  		},
   345  		{
   346  			Name: "Returns error when delete fails",
   347  			FormationRepoFn: func() *automock.FormationRepository {
   348  				repo := &automock.FormationRepository{}
   349  				repo.On("DeleteByName", ctx, TntInternalID, modelFormation.Name).Return(testErr).Once()
   350  				return repo
   351  			},
   352  			LabelDefRepositoryFn: func() *automock.LabelDefRepository {
   353  				labelDefRepo := &automock.LabelDefRepository{}
   354  				labelDefRepo.On("GetByKey", ctx, TntInternalID, model.ScenariosKey).Return(&testSchemaLblDef, nil).Once()
   355  				labelDefRepo.On("UpdateWithVersion", ctx, newSchemaLblDef).Return(nil).Once()
   356  				return labelDefRepo
   357  			},
   358  			LabelDefServiceFn: func() *automock.LabelDefService {
   359  				labelDefService := &automock.LabelDefService{}
   360  				labelDefService.On("ValidateExistingLabelsAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(nil).Once()
   361  				labelDefService.On("ValidateAutomaticScenarioAssignmentAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(nil).Once()
   362  				return labelDefService
   363  			},
   364  			NotificationsSvcFn: func() *automock.NotificationsService {
   365  				notificationsSvc := &automock.NotificationsService{}
   366  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   367  				return notificationsSvc
   368  			},
   369  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   370  				engine := &automock.ConstraintEngine{}
   371  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
   372  				return engine
   373  			},
   374  			InputFormation:     &modelFormation,
   375  			FormationOperation: model.DeleteFormation,
   376  			ExpectedErrMessage: testErr.Error(),
   377  		},
   378  		{
   379  			Name: "Returns error when update label def fails",
   380  			LabelDefRepositoryFn: func() *automock.LabelDefRepository {
   381  				labelDefRepo := &automock.LabelDefRepository{}
   382  				labelDefRepo.On("GetByKey", ctx, TntInternalID, model.ScenariosKey).Return(&testSchemaLblDef, nil).Once()
   383  				labelDefRepo.On("UpdateWithVersion", ctx, newSchemaLblDef).Return(testErr).Once()
   384  				return labelDefRepo
   385  			},
   386  			LabelDefServiceFn: func() *automock.LabelDefService {
   387  				labelDefService := &automock.LabelDefService{}
   388  				labelDefService.On("ValidateExistingLabelsAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(nil).Once()
   389  				labelDefService.On("ValidateAutomaticScenarioAssignmentAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(nil).Once()
   390  				return labelDefService
   391  			},
   392  			NotificationsSvcFn: func() *automock.NotificationsService {
   393  				notificationsSvc := &automock.NotificationsService{}
   394  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   395  				return notificationsSvc
   396  			},
   397  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   398  				engine := &automock.ConstraintEngine{}
   399  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
   400  				return engine
   401  			},
   402  			InputFormation:     &modelFormation,
   403  			FormationOperation: model.DeleteFormation,
   404  			ExpectedErrMessage: testErr.Error(),
   405  		},
   406  		{
   407  			Name: "Returns error when validate asa against schema fails",
   408  			LabelDefRepositoryFn: func() *automock.LabelDefRepository {
   409  				labelDefRepo := &automock.LabelDefRepository{}
   410  				labelDefRepo.On("GetByKey", ctx, TntInternalID, model.ScenariosKey).Return(&testSchemaLblDef, nil).Once()
   411  				return labelDefRepo
   412  			},
   413  			LabelDefServiceFn: func() *automock.LabelDefService {
   414  				labelDefService := &automock.LabelDefService{}
   415  				labelDefService.On("ValidateExistingLabelsAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(nil).Once()
   416  				labelDefService.On("ValidateAutomaticScenarioAssignmentAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(testErr).Once()
   417  				return labelDefService
   418  			},
   419  			NotificationsSvcFn: func() *automock.NotificationsService {
   420  				notificationsSvc := &automock.NotificationsService{}
   421  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   422  				return notificationsSvc
   423  			},
   424  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   425  				engine := &automock.ConstraintEngine{}
   426  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
   427  				return engine
   428  			},
   429  			InputFormation:     &modelFormation,
   430  			FormationOperation: model.DeleteFormation,
   431  			ExpectedErrMessage: testErr.Error(),
   432  		},
   433  		{
   434  			Name: "Returns error when validate existing labels against schema fails",
   435  			LabelDefRepositoryFn: func() *automock.LabelDefRepository {
   436  				labelDefRepo := &automock.LabelDefRepository{}
   437  				labelDefRepo.On("GetByKey", ctx, TntInternalID, model.ScenariosKey).Return(&testSchemaLblDef, nil).Once()
   438  				return labelDefRepo
   439  			},
   440  			LabelDefServiceFn: func() *automock.LabelDefService {
   441  				labelDefService := &automock.LabelDefService{}
   442  				labelDefService.On("ValidateExistingLabelsAgainstSchema", ctx, newSchema, TntInternalID, model.ScenariosKey).Return(testErr).Once()
   443  				return labelDefService
   444  			},
   445  			NotificationsSvcFn: func() *automock.NotificationsService {
   446  				notificationsSvc := &automock.NotificationsService{}
   447  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   448  				return notificationsSvc
   449  			},
   450  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   451  				engine := &automock.ConstraintEngine{}
   452  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
   453  				return engine
   454  			},
   455  			InputFormation:     &modelFormation,
   456  			FormationOperation: model.DeleteFormation,
   457  			ExpectedErrMessage: testErr.Error(),
   458  		},
   459  		{
   460  			Name: "Returns error when getting label def fails",
   461  			LabelDefRepositoryFn: func() *automock.LabelDefRepository {
   462  				labelDefRepo := &automock.LabelDefRepository{}
   463  				labelDefRepo.On("GetByKey", ctx, TntInternalID, model.ScenariosKey).Return(nil, testErr).Once()
   464  				return labelDefRepo
   465  			},
   466  			NotificationsSvcFn: func() *automock.NotificationsService {
   467  				notificationsSvc := &automock.NotificationsService{}
   468  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   469  				return notificationsSvc
   470  			},
   471  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   472  				engine := &automock.ConstraintEngine{}
   473  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(nil).Once()
   474  				return engine
   475  			},
   476  			InputFormation:     &modelFormation,
   477  			FormationOperation: model.DeleteFormation,
   478  			ExpectedErrMessage: testErr.Error(),
   479  		},
   480  		{
   481  			Name: "Returns error when enforcing pre constraints fails",
   482  			NotificationsSvcFn: func() *automock.NotificationsService {
   483  				notificationsSvc := &automock.NotificationsService{}
   484  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(preDetails, nil).Once()
   485  				return notificationsSvc
   486  			},
   487  			ConstraintEngineFn: func() *automock.ConstraintEngine {
   488  				engine := &automock.ConstraintEngine{}
   489  				engine.On("EnforceConstraints", ctx, formationconstraint.PreNotificationStatusReturned, preDetails, preDetails.Formation.FormationTemplateID).Return(testErr).Once()
   490  				return engine
   491  			},
   492  			InputFormation:     &modelFormation,
   493  			FormationOperation: model.DeleteFormation,
   494  			ExpectedErrMessage: testErr.Error(),
   495  		},
   496  		{
   497  			Name: "Returns error when enforcing pre constraints fails",
   498  			NotificationsSvcFn: func() *automock.NotificationsService {
   499  				notificationsSvc := &automock.NotificationsService{}
   500  				notificationsSvc.On("PrepareDetailsForNotificationStatusReturned", ctx, &modelFormation, model.DeleteFormation).Return(nil, testErr).Once()
   501  				return notificationsSvc
   502  			},
   503  			InputFormation:     &modelFormation,
   504  			FormationOperation: model.DeleteFormation,
   505  			ExpectedErrMessage: testErr.Error(),
   506  		},
   507  	}
   508  
   509  	for _, testCase := range testCases {
   510  		t.Run(testCase.Name, func(t *testing.T) {
   511  			// GIVEN
   512  			formationRepo := &automock.FormationRepository{}
   513  			if testCase.FormationRepoFn != nil {
   514  				formationRepo = testCase.FormationRepoFn()
   515  			}
   516  			labelDefRepo := &automock.LabelDefRepository{}
   517  			if testCase.LabelDefRepositoryFn != nil {
   518  				labelDefRepo = testCase.LabelDefRepositoryFn()
   519  			}
   520  			labelDefSvc := &automock.LabelDefService{}
   521  			if testCase.LabelDefServiceFn != nil {
   522  				labelDefSvc = testCase.LabelDefServiceFn()
   523  			}
   524  			notificationsSvc := &automock.NotificationsService{}
   525  			if testCase.NotificationsSvcFn != nil {
   526  				notificationsSvc = testCase.NotificationsSvcFn()
   527  			}
   528  			engine := &automock.ConstraintEngine{}
   529  			if testCase.ConstraintEngineFn != nil {
   530  				engine = testCase.ConstraintEngineFn()
   531  			}
   532  
   533  			svc := formation.NewFormationStatusService(formationRepo, labelDefRepo, labelDefSvc, notificationsSvc, engine)
   534  
   535  			// WHEN
   536  			err := svc.DeleteFormationEntityAndScenariosWithConstraints(ctx, TntInternalID, testCase.InputFormation)
   537  
   538  			// THEN
   539  			if testCase.ExpectedErrMessage == "" {
   540  				require.NoError(t, err)
   541  			} else {
   542  				require.Error(t, err)
   543  				require.Contains(t, err.Error(), testCase.ExpectedErrMessage)
   544  			}
   545  
   546  			mock.AssertExpectationsForObjects(t, formationRepo, notificationsSvc, engine, labelDefRepo, labelDefSvc)
   547  		})
   548  	}
   549  }