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

     1  package formationconstraint_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/kyma-incubator/compass/components/director/internal/domain/formationconstraint"
     8  	"github.com/kyma-incubator/compass/components/director/internal/domain/formationconstraint/automock"
     9  	"github.com/kyma-incubator/compass/components/director/internal/model"
    10  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
    11  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    12  	persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock"
    13  	"github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest"
    14  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
    15  	"github.com/pkg/errors"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/mock"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestResolver_FormationConstraints(t *testing.T) {
    22  	// GIVEN
    23  	ctx := context.TODO()
    24  
    25  	testErr := errors.New("test error")
    26  
    27  	txGen := txtest.NewTransactionContextGenerator(testErr)
    28  
    29  	formationConstraints := []*model.FormationConstraint{
    30  		{Name: "test"},
    31  		{Name: "test2"},
    32  	}
    33  
    34  	formationConstraintsGql := []*graphql.FormationConstraint{
    35  		{Name: "test"},
    36  		{Name: "test2"},
    37  	}
    38  
    39  	testCases := []struct {
    40  		Name                         string
    41  		TxFn                         func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
    42  		FormationConstraintConverter func() *automock.FormationConstraintConverter
    43  		FormationConstraintService   func() *automock.FormationConstraintService
    44  		ExpectedOutput               []*graphql.FormationConstraint
    45  		ExpectedError                error
    46  	}{
    47  		{
    48  			Name: "Success",
    49  			TxFn: txGen.ThatSucceeds,
    50  			FormationConstraintService: func() *automock.FormationConstraintService {
    51  				svc := &automock.FormationConstraintService{}
    52  				svc.On("List", txtest.CtxWithDBMatcher()).Return(formationConstraints, nil)
    53  
    54  				return svc
    55  			},
    56  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
    57  				converter := &automock.FormationConstraintConverter{}
    58  				converter.On("MultipleToGraphQL", formationConstraints).Return(formationConstraintsGql)
    59  
    60  				return converter
    61  			},
    62  			ExpectedOutput: formationConstraintsGql,
    63  			ExpectedError:  nil,
    64  		},
    65  		{
    66  			Name: "Error when listing from service fails",
    67  			TxFn: txGen.ThatDoesntExpectCommit,
    68  			FormationConstraintService: func() *automock.FormationConstraintService {
    69  				svc := &automock.FormationConstraintService{}
    70  				svc.On("List", txtest.CtxWithDBMatcher()).Return(nil, testErr)
    71  
    72  				return svc
    73  			},
    74  			FormationConstraintConverter: UnusedFormationConstraintConverter,
    75  			ExpectedOutput:               nil,
    76  			ExpectedError:                testErr,
    77  		},
    78  		{
    79  			Name: "Returns error when failing on the committing of a transaction",
    80  			TxFn: txGen.ThatFailsOnCommit,
    81  			FormationConstraintService: func() *automock.FormationConstraintService {
    82  				svc := &automock.FormationConstraintService{}
    83  				svc.On("List", txtest.CtxWithDBMatcher()).Return(formationConstraints, nil)
    84  
    85  				return svc
    86  			},
    87  			FormationConstraintConverter: UnusedFormationConstraintConverter,
    88  			ExpectedOutput:               nil,
    89  			ExpectedError:                testErr,
    90  		},
    91  		{
    92  			Name:                         "Returns error when failing on the beginning of a transaction",
    93  			TxFn:                         txGen.ThatFailsOnBegin,
    94  			FormationConstraintService:   UnusedFormationConstraintService,
    95  			FormationConstraintConverter: UnusedFormationConstraintConverter,
    96  			ExpectedOutput:               nil,
    97  			ExpectedError:                testErr,
    98  		},
    99  	}
   100  
   101  	for _, testCase := range testCases {
   102  		t.Run(testCase.Name, func(t *testing.T) {
   103  			persist, transact := testCase.TxFn()
   104  			formationConstraintSvc := testCase.FormationConstraintService()
   105  			formationConstraintConverter := testCase.FormationConstraintConverter()
   106  
   107  			resolver := formationconstraint.NewResolver(transact, formationConstraintConverter, formationConstraintSvc)
   108  
   109  			// WHEN
   110  			result, err := resolver.FormationConstraints(ctx)
   111  
   112  			// THEN
   113  			if testCase.ExpectedError != nil {
   114  				require.Error(t, err)
   115  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
   116  			} else {
   117  				assert.NoError(t, err)
   118  			}
   119  			assert.Equal(t, testCase.ExpectedOutput, result)
   120  
   121  			mock.AssertExpectationsForObjects(t, persist, formationConstraintSvc, formationConstraintConverter)
   122  		})
   123  	}
   124  }
   125  
   126  func TestResolver_FormationConstraintsByFormationType(t *testing.T) {
   127  	// GIVEN
   128  	ctx := context.TODO()
   129  
   130  	testErr := errors.New("test error")
   131  
   132  	txGen := txtest.NewTransactionContextGenerator(testErr)
   133  
   134  	formationConstraints := []*model.FormationConstraint{
   135  		{Name: "test"},
   136  		{Name: "test2"},
   137  	}
   138  
   139  	formationConstraintsGql := []*graphql.FormationConstraint{
   140  		{Name: "test"},
   141  		{Name: "test2"},
   142  	}
   143  
   144  	testCases := []struct {
   145  		Name                         string
   146  		TxFn                         func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   147  		FormationConstraintConverter func() *automock.FormationConstraintConverter
   148  		FormationConstraintService   func() *automock.FormationConstraintService
   149  		ExpectedOutput               []*graphql.FormationConstraint
   150  		ExpectedError                error
   151  	}{
   152  		{
   153  			Name: "Success",
   154  			TxFn: txGen.ThatSucceeds,
   155  			FormationConstraintService: func() *automock.FormationConstraintService {
   156  				svc := &automock.FormationConstraintService{}
   157  				svc.On("ListByFormationTemplateID", txtest.CtxWithDBMatcher(), formationTemplateID).Return(formationConstraints, nil)
   158  
   159  				return svc
   160  			},
   161  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   162  				converter := &automock.FormationConstraintConverter{}
   163  				converter.On("MultipleToGraphQL", formationConstraints).Return(formationConstraintsGql)
   164  
   165  				return converter
   166  			},
   167  			ExpectedOutput: formationConstraintsGql,
   168  			ExpectedError:  nil,
   169  		},
   170  		{
   171  			Name: "Error when listing from service fails",
   172  			TxFn: txGen.ThatDoesntExpectCommit,
   173  			FormationConstraintService: func() *automock.FormationConstraintService {
   174  				svc := &automock.FormationConstraintService{}
   175  				svc.On("ListByFormationTemplateID", txtest.CtxWithDBMatcher(), formationTemplateID).Return(nil, testErr)
   176  
   177  				return svc
   178  			},
   179  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   180  			ExpectedOutput:               nil,
   181  			ExpectedError:                testErr,
   182  		},
   183  		{
   184  			Name: "Returns error when failing on the committing of a transaction",
   185  			TxFn: txGen.ThatFailsOnCommit,
   186  			FormationConstraintService: func() *automock.FormationConstraintService {
   187  				svc := &automock.FormationConstraintService{}
   188  				svc.On("ListByFormationTemplateID", txtest.CtxWithDBMatcher(), formationTemplateID).Return(formationConstraints, nil)
   189  
   190  				return svc
   191  			},
   192  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   193  			ExpectedOutput:               nil,
   194  			ExpectedError:                testErr,
   195  		},
   196  		{
   197  			Name:                         "Returns error when failing on the beginning of a transaction",
   198  			TxFn:                         txGen.ThatFailsOnBegin,
   199  			FormationConstraintService:   UnusedFormationConstraintService,
   200  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   201  			ExpectedOutput:               nil,
   202  			ExpectedError:                testErr,
   203  		},
   204  	}
   205  
   206  	for _, testCase := range testCases {
   207  		t.Run(testCase.Name, func(t *testing.T) {
   208  			persist, transact := testCase.TxFn()
   209  			formationConstraintSvc := testCase.FormationConstraintService()
   210  			formationConstraintConverter := testCase.FormationConstraintConverter()
   211  
   212  			resolver := formationconstraint.NewResolver(transact, formationConstraintConverter, formationConstraintSvc)
   213  
   214  			// WHEN
   215  			result, err := resolver.FormationConstraintsByFormationType(ctx, formationTemplateID)
   216  
   217  			// THEN
   218  			if testCase.ExpectedError != nil {
   219  				require.Error(t, err)
   220  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
   221  			} else {
   222  				assert.NoError(t, err)
   223  			}
   224  			assert.Equal(t, testCase.ExpectedOutput, result)
   225  
   226  			mock.AssertExpectationsForObjects(t, persist, formationConstraintSvc, formationConstraintConverter)
   227  		})
   228  	}
   229  }
   230  
   231  func TestResolver_FormationConstraint(t *testing.T) {
   232  	// GIVEN
   233  	ctx := context.TODO()
   234  
   235  	testErr := errors.New("test error")
   236  
   237  	txGen := txtest.NewTransactionContextGenerator(testErr)
   238  
   239  	testCases := []struct {
   240  		Name                         string
   241  		TxFn                         func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   242  		FormationConstraintConverter func() *automock.FormationConstraintConverter
   243  		FormationConstraintService   func() *automock.FormationConstraintService
   244  		ExpectedOutput               *graphql.FormationConstraint
   245  		ExpectedError                error
   246  	}{
   247  		{
   248  			Name: "Success",
   249  			TxFn: txGen.ThatSucceeds,
   250  			FormationConstraintService: func() *automock.FormationConstraintService {
   251  				svc := &automock.FormationConstraintService{}
   252  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil)
   253  
   254  				return svc
   255  			},
   256  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   257  				converter := &automock.FormationConstraintConverter{}
   258  				converter.On("ToGraphQL", formationConstraintModel).Return(gqlFormationConstraint, nil)
   259  
   260  				return converter
   261  			},
   262  			ExpectedOutput: gqlFormationConstraint,
   263  			ExpectedError:  nil,
   264  		},
   265  		{
   266  			Name: "Error when getting from service fails",
   267  			TxFn: txGen.ThatDoesntExpectCommit,
   268  			FormationConstraintService: func() *automock.FormationConstraintService {
   269  				svc := &automock.FormationConstraintService{}
   270  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testErr)
   271  
   272  				return svc
   273  			},
   274  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   275  			ExpectedOutput:               nil,
   276  			ExpectedError:                testErr,
   277  		},
   278  		{
   279  			Name: "Returns nil when formation constraint not found",
   280  			TxFn: txGen.ThatSucceeds,
   281  			FormationConstraintService: func() *automock.FormationConstraintService {
   282  				svc := &automock.FormationConstraintService{}
   283  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, apperrors.NewNotFoundError(resource.FormationTemplate, testID))
   284  
   285  				return svc
   286  			},
   287  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   288  			ExpectedOutput:               nil,
   289  			ExpectedError:                nil,
   290  		},
   291  		{
   292  			Name: "Returns error when failing on the committing of a transaction",
   293  			TxFn: txGen.ThatFailsOnCommit,
   294  			FormationConstraintService: func() *automock.FormationConstraintService {
   295  				svc := &automock.FormationConstraintService{}
   296  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil)
   297  
   298  				return svc
   299  			},
   300  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   301  			ExpectedOutput:               nil,
   302  			ExpectedError:                testErr,
   303  		},
   304  		{
   305  			Name:                         "Returns error when failing on the beginning of a transaction",
   306  			TxFn:                         txGen.ThatFailsOnBegin,
   307  			FormationConstraintService:   UnusedFormationConstraintService,
   308  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   309  			ExpectedOutput:               nil,
   310  			ExpectedError:                testErr,
   311  		},
   312  	}
   313  
   314  	for _, testCase := range testCases {
   315  		t.Run(testCase.Name, func(t *testing.T) {
   316  			persist, transact := testCase.TxFn()
   317  			formationConstraintSvc := testCase.FormationConstraintService()
   318  			formationConstraintConverter := testCase.FormationConstraintConverter()
   319  
   320  			resolver := formationconstraint.NewResolver(transact, formationConstraintConverter, formationConstraintSvc)
   321  
   322  			// WHEN
   323  			result, err := resolver.FormationConstraint(ctx, testID)
   324  
   325  			// THEN
   326  			if testCase.ExpectedError != nil {
   327  				require.Error(t, err)
   328  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
   329  			} else {
   330  				assert.NoError(t, err)
   331  			}
   332  			assert.Equal(t, testCase.ExpectedOutput, result)
   333  
   334  			mock.AssertExpectationsForObjects(t, persist, formationConstraintSvc, formationConstraintConverter)
   335  		})
   336  	}
   337  }
   338  
   339  func TestResolver_CreateFormationConstraint(t *testing.T) {
   340  	// GIVEN
   341  	ctx := context.TODO()
   342  
   343  	testErr := errors.New("test error")
   344  
   345  	txGen := txtest.NewTransactionContextGenerator(testErr)
   346  
   347  	testCases := []struct {
   348  		Name                         string
   349  		Input                        graphql.FormationConstraintInput
   350  		TxFn                         func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   351  		FormationConstraintConverter func() *automock.FormationConstraintConverter
   352  		FormationConstraintService   func() *automock.FormationConstraintService
   353  		ExpectedOutput               *graphql.FormationConstraint
   354  		ExpectedError                error
   355  	}{
   356  		{
   357  			Name:  "Success",
   358  			TxFn:  txGen.ThatSucceeds,
   359  			Input: formationConstraintInput,
   360  			FormationConstraintService: func() *automock.FormationConstraintService {
   361  				svc := &automock.FormationConstraintService{}
   362  				svc.On("Create", txtest.CtxWithDBMatcher(), formationConstraintModelInput).Return(testID, nil)
   363  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil)
   364  
   365  				return svc
   366  			},
   367  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   368  				converter := &automock.FormationConstraintConverter{}
   369  				converter.On("FromInputGraphQL", &formationConstraintInput).Return(formationConstraintModelInput, nil)
   370  				converter.On("ToGraphQL", formationConstraintModel).Return(gqlFormationConstraint, nil)
   371  
   372  				return converter
   373  			},
   374  			ExpectedOutput: gqlFormationConstraint,
   375  			ExpectedError:  nil,
   376  		},
   377  		{
   378  			Name:  "Error when creating call to service fails",
   379  			Input: formationConstraintInput,
   380  			TxFn:  txGen.ThatDoesntExpectCommit,
   381  			FormationConstraintService: func() *automock.FormationConstraintService {
   382  				svc := &automock.FormationConstraintService{}
   383  				svc.On("Create", txtest.CtxWithDBMatcher(), formationConstraintModelInput).Return("", testErr)
   384  
   385  				return svc
   386  			},
   387  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   388  				converter := &automock.FormationConstraintConverter{}
   389  				converter.On("FromInputGraphQL", &formationConstraintInput).Return(formationConstraintModelInput, nil)
   390  
   391  				return converter
   392  			},
   393  			ExpectedOutput: nil,
   394  			ExpectedError:  testErr,
   395  		},
   396  		{
   397  			Name:  "Error when get call to service fails",
   398  			Input: formationConstraintInput,
   399  			TxFn:  txGen.ThatDoesntExpectCommit,
   400  			FormationConstraintService: func() *automock.FormationConstraintService {
   401  				svc := &automock.FormationConstraintService{}
   402  				svc.On("Create", txtest.CtxWithDBMatcher(), formationConstraintModelInput).Return(testID, nil)
   403  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testErr)
   404  
   405  				return svc
   406  			},
   407  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   408  				converter := &automock.FormationConstraintConverter{}
   409  				converter.On("FromInputGraphQL", &formationConstraintInput).Return(formationConstraintModelInput, nil)
   410  
   411  				return converter
   412  			},
   413  			ExpectedOutput: nil,
   414  			ExpectedError:  testErr,
   415  		},
   416  		{
   417  			Name:  "Returns error when failing on the committing of a transaction",
   418  			TxFn:  txGen.ThatFailsOnCommit,
   419  			Input: formationConstraintInput,
   420  			FormationConstraintService: func() *automock.FormationConstraintService {
   421  				svc := &automock.FormationConstraintService{}
   422  				svc.On("Create", txtest.CtxWithDBMatcher(), formationConstraintModelInput).Return(testID, nil)
   423  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil)
   424  
   425  				return svc
   426  			},
   427  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   428  				converter := &automock.FormationConstraintConverter{}
   429  				converter.On("FromInputGraphQL", &formationConstraintInput).Return(formationConstraintModelInput, nil)
   430  
   431  				return converter
   432  			},
   433  			ExpectedOutput: nil,
   434  			ExpectedError:  testErr,
   435  		},
   436  		{
   437  			Name:                         "Returns error when input validation fails",
   438  			Input:                        graphql.FormationConstraintInput{},
   439  			TxFn:                         txGen.ThatDoesntExpectCommit,
   440  			FormationConstraintService:   UnusedFormationConstraintService,
   441  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   442  			ExpectedOutput:               nil,
   443  			ExpectedError:                errors.New("cannot be blank"),
   444  		},
   445  		{
   446  			Name:                         "Returns error when failing on the beginning of a transaction",
   447  			Input:                        formationConstraintInput,
   448  			TxFn:                         txGen.ThatFailsOnBegin,
   449  			FormationConstraintService:   UnusedFormationConstraintService,
   450  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   451  			ExpectedOutput:               nil,
   452  			ExpectedError:                testErr,
   453  		},
   454  	}
   455  
   456  	for _, testCase := range testCases {
   457  		t.Run(testCase.Name, func(t *testing.T) {
   458  			persist, transact := testCase.TxFn()
   459  			formationConstraintSvc := testCase.FormationConstraintService()
   460  			formationConstraintConverter := testCase.FormationConstraintConverter()
   461  
   462  			resolver := formationconstraint.NewResolver(transact, formationConstraintConverter, formationConstraintSvc)
   463  
   464  			// WHEN
   465  			result, err := resolver.CreateFormationConstraint(ctx, testCase.Input)
   466  
   467  			// THEN
   468  			if testCase.ExpectedError != nil {
   469  				require.Error(t, err)
   470  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
   471  			} else {
   472  				assert.NoError(t, err)
   473  			}
   474  			assert.Equal(t, testCase.ExpectedOutput, result)
   475  
   476  			mock.AssertExpectationsForObjects(t, persist, formationConstraintSvc, formationConstraintConverter)
   477  		})
   478  	}
   479  }
   480  
   481  func TestResolver_DeleteFormationTemplate(t *testing.T) {
   482  	// GIVEN
   483  	ctx := context.TODO()
   484  
   485  	testErr := errors.New("test error")
   486  
   487  	txGen := txtest.NewTransactionContextGenerator(testErr)
   488  
   489  	testCases := []struct {
   490  		Name                         string
   491  		TxFn                         func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   492  		FormationConstraintConverter func() *automock.FormationConstraintConverter
   493  		FormationConstraintService   func() *automock.FormationConstraintService
   494  		ExpectedOutput               *graphql.FormationConstraint
   495  		ExpectedError                error
   496  	}{
   497  		{
   498  			Name: "Success",
   499  			TxFn: txGen.ThatSucceeds,
   500  			FormationConstraintService: func() *automock.FormationConstraintService {
   501  				svc := &automock.FormationConstraintService{}
   502  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil)
   503  				svc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(nil)
   504  
   505  				return svc
   506  			},
   507  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   508  				converter := &automock.FormationConstraintConverter{}
   509  				converter.On("ToGraphQL", formationConstraintModel).Return(gqlFormationConstraint, nil)
   510  
   511  				return converter
   512  			},
   513  			ExpectedOutput: gqlFormationConstraint,
   514  			ExpectedError:  nil,
   515  		},
   516  		{
   517  			Name: "Error when get call in service fails",
   518  			TxFn: txGen.ThatDoesntExpectCommit,
   519  			FormationConstraintService: func() *automock.FormationConstraintService {
   520  				svc := &automock.FormationConstraintService{}
   521  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testErr)
   522  
   523  				return svc
   524  			},
   525  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   526  			ExpectedOutput:               nil,
   527  			ExpectedError:                testErr,
   528  		},
   529  		{
   530  			Name: "Error when delete call in service fails",
   531  			TxFn: txGen.ThatDoesntExpectCommit,
   532  			FormationConstraintService: func() *automock.FormationConstraintService {
   533  				svc := &automock.FormationConstraintService{}
   534  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil)
   535  				svc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(testErr)
   536  
   537  				return svc
   538  			},
   539  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   540  			ExpectedOutput:               nil,
   541  			ExpectedError:                testErr,
   542  		},
   543  		{
   544  			Name: "Returns error when failing on the committing of a transaction",
   545  			TxFn: txGen.ThatFailsOnCommit,
   546  			FormationConstraintService: func() *automock.FormationConstraintService {
   547  				svc := &automock.FormationConstraintService{}
   548  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil)
   549  				svc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(nil)
   550  
   551  				return svc
   552  			},
   553  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   554  			ExpectedOutput:               nil,
   555  			ExpectedError:                testErr,
   556  		},
   557  		{
   558  			Name:                         "Returns error when failing on the beginning of a transaction",
   559  			TxFn:                         txGen.ThatFailsOnBegin,
   560  			FormationConstraintService:   UnusedFormationConstraintService,
   561  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   562  			ExpectedOutput:               nil,
   563  			ExpectedError:                testErr,
   564  		},
   565  	}
   566  
   567  	for _, testCase := range testCases {
   568  		t.Run(testCase.Name, func(t *testing.T) {
   569  			persist, transact := testCase.TxFn()
   570  			formationConstraintSvc := testCase.FormationConstraintService()
   571  			formationConstraintConverter := testCase.FormationConstraintConverter()
   572  
   573  			resolver := formationconstraint.NewResolver(transact, formationConstraintConverter, formationConstraintSvc)
   574  
   575  			// WHEN
   576  			result, err := resolver.DeleteFormationConstraint(ctx, testID)
   577  
   578  			// THEN
   579  			if testCase.ExpectedError != nil {
   580  				require.Error(t, err)
   581  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
   582  			} else {
   583  				assert.NoError(t, err)
   584  			}
   585  			assert.Equal(t, testCase.ExpectedOutput, result)
   586  
   587  			mock.AssertExpectationsForObjects(t, persist, formationConstraintSvc, formationConstraintConverter)
   588  		})
   589  	}
   590  }
   591  
   592  func TestResolver_UpdateFormationConstraint(t *testing.T) {
   593  	// GIVEN
   594  	ctx := context.TODO()
   595  
   596  	testErr := errors.New("test error")
   597  
   598  	txGen := txtest.NewTransactionContextGenerator(testErr)
   599  
   600  	testCases := []struct {
   601  		Name                         string
   602  		Input                        graphql.FormationConstraintUpdateInput
   603  		TxFn                         func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   604  		FormationConstraintConverter func() *automock.FormationConstraintConverter
   605  		FormationConstraintService   func() *automock.FormationConstraintService
   606  		ExpectedOutput               *graphql.FormationConstraint
   607  		ExpectedError                error
   608  	}{
   609  		{
   610  			Name:  "Success",
   611  			Input: formationConstraintUpdateInput,
   612  			TxFn:  txGen.ThatSucceeds,
   613  			FormationConstraintService: func() *automock.FormationConstraintService {
   614  				svc := &automock.FormationConstraintService{}
   615  				svc.On("Update", txtest.CtxWithDBMatcher(), testID, formationConstraintModelInput).Return(nil).Once()
   616  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil).Once()
   617  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModelUpdated, nil).Once()
   618  
   619  				return svc
   620  			},
   621  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   622  				converter := &automock.FormationConstraintConverter{}
   623  				converter.On("FromInputGraphQL", &formationConstraintInputUpdated).Return(formationConstraintModelInput)
   624  				converter.On("ToGraphQL", formationConstraintModelUpdated).Return(gqlFormationConstraintUpdated)
   625  
   626  				return converter
   627  			},
   628  			ExpectedOutput: gqlFormationConstraintUpdated,
   629  			ExpectedError:  nil,
   630  		},
   631  		{
   632  			Name:  "Error when getting constraint",
   633  			Input: formationConstraintUpdateInput,
   634  			TxFn:  txGen.ThatDoesntExpectCommit,
   635  			FormationConstraintService: func() *automock.FormationConstraintService {
   636  				svc := &automock.FormationConstraintService{}
   637  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testErr).Once()
   638  
   639  				return svc
   640  			},
   641  			ExpectedOutput: nil,
   642  			ExpectedError:  testErr,
   643  		},
   644  		{
   645  			Name:  "Error when updating constraint",
   646  			Input: formationConstraintUpdateInput,
   647  			TxFn:  txGen.ThatDoesntExpectCommit,
   648  			FormationConstraintService: func() *automock.FormationConstraintService {
   649  				svc := &automock.FormationConstraintService{}
   650  				svc.On("Update", txtest.CtxWithDBMatcher(), testID, formationConstraintModelInput).Return(testErr).Once()
   651  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil).Once()
   652  
   653  				return svc
   654  			},
   655  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   656  				converter := &automock.FormationConstraintConverter{}
   657  				converter.On("FromInputGraphQL", &formationConstraintInputUpdated).Return(formationConstraintModelInput, nil)
   658  
   659  				return converter
   660  			},
   661  			ExpectedOutput: nil,
   662  			ExpectedError:  testErr,
   663  		},
   664  		{
   665  			Name:  "Error when getting updated constraint",
   666  			Input: formationConstraintUpdateInput,
   667  			TxFn:  txGen.ThatDoesntExpectCommit,
   668  			FormationConstraintService: func() *automock.FormationConstraintService {
   669  				svc := &automock.FormationConstraintService{}
   670  				svc.On("Update", txtest.CtxWithDBMatcher(), testID, formationConstraintModelInput).Return(nil).Once()
   671  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil).Once()
   672  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testErr).Once()
   673  
   674  				return svc
   675  			},
   676  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   677  				converter := &automock.FormationConstraintConverter{}
   678  				converter.On("FromInputGraphQL", &formationConstraintInputUpdated).Return(formationConstraintModelInput)
   679  
   680  				return converter
   681  			},
   682  			ExpectedError: testErr,
   683  		},
   684  		{
   685  			Name:  "Returns error when failing on the committing of a transaction",
   686  			Input: formationConstraintUpdateInput,
   687  			TxFn:  txGen.ThatFailsOnCommit,
   688  			FormationConstraintService: func() *automock.FormationConstraintService {
   689  				svc := &automock.FormationConstraintService{}
   690  				svc.On("Update", txtest.CtxWithDBMatcher(), testID, formationConstraintModelInput).Return(nil).Once()
   691  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil).Once()
   692  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModelUpdated, nil).Once()
   693  
   694  				return svc
   695  			},
   696  			FormationConstraintConverter: func() *automock.FormationConstraintConverter {
   697  				converter := &automock.FormationConstraintConverter{}
   698  				converter.On("FromInputGraphQL", &formationConstraintInputUpdated).Return(formationConstraintModelInput)
   699  
   700  				return converter
   701  			},
   702  			ExpectedOutput: nil,
   703  			ExpectedError:  testErr,
   704  		},
   705  		{
   706  			Name:  "Returns error when input validation fails",
   707  			Input: graphql.FormationConstraintUpdateInput{},
   708  			TxFn:  txGen.ThatDoesntExpectCommit,
   709  			FormationConstraintService: func() *automock.FormationConstraintService {
   710  				svc := &automock.FormationConstraintService{}
   711  				svc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(formationConstraintModel, nil).Once()
   712  
   713  				return svc
   714  			},
   715  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   716  			ExpectedOutput:               nil,
   717  			ExpectedError:                errors.New("cannot be blank"),
   718  		},
   719  		{
   720  			Name:                         "Returns error when failing on the beginning of a transaction",
   721  			TxFn:                         txGen.ThatFailsOnBegin,
   722  			Input:                        formationConstraintUpdateInput,
   723  			FormationConstraintService:   UnusedFormationConstraintService,
   724  			FormationConstraintConverter: UnusedFormationConstraintConverter,
   725  			ExpectedOutput:               nil,
   726  			ExpectedError:                testErr,
   727  		},
   728  	}
   729  
   730  	for _, testCase := range testCases {
   731  		t.Run(testCase.Name, func(t *testing.T) {
   732  			persist, transact := testCase.TxFn()
   733  
   734  			formationConstraintSvc := UnusedFormationConstraintService()
   735  			if testCase.FormationConstraintService != nil {
   736  				formationConstraintSvc = testCase.FormationConstraintService()
   737  			}
   738  			formationConstraintConverter := UnusedFormationConstraintConverter()
   739  			if testCase.FormationConstraintConverter != nil {
   740  				formationConstraintConverter = testCase.FormationConstraintConverter()
   741  			}
   742  
   743  			resolver := formationconstraint.NewResolver(transact, formationConstraintConverter, formationConstraintSvc)
   744  
   745  			// WHEN
   746  			result, err := resolver.UpdateFormationConstraint(ctx, testID, testCase.Input)
   747  
   748  			// THEN
   749  			if testCase.ExpectedError != nil {
   750  				require.Error(t, err)
   751  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
   752  			} else {
   753  				assert.NoError(t, err)
   754  			}
   755  			assert.Equal(t, testCase.ExpectedOutput, result)
   756  
   757  			mock.AssertExpectationsForObjects(t, persist, formationConstraintSvc, formationConstraintConverter)
   758  		})
   759  	}
   760  }