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

     1  package api_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/kyma-incubator/compass/components/director/pkg/pagination"
     9  	"github.com/stretchr/testify/mock"
    10  
    11  	dataloader "github.com/kyma-incubator/compass/components/director/internal/dataloaders"
    12  
    13  	"github.com/kyma-incubator/compass/components/director/pkg/str"
    14  
    15  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
    16  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
    17  
    18  	"github.com/kyma-incubator/compass/components/director/internal/domain/api"
    19  	"github.com/kyma-incubator/compass/components/director/internal/domain/api/automock"
    20  	"github.com/kyma-incubator/compass/components/director/internal/model"
    21  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    22  	persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock"
    23  	"github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest"
    24  	"github.com/pkg/errors"
    25  	"github.com/stretchr/testify/assert"
    26  	"github.com/stretchr/testify/require"
    27  )
    28  
    29  func TestResolver_AddAPIToBundle(t *testing.T) {
    30  	// GIVEN
    31  	testErr := errors.New("Test error")
    32  
    33  	id := "bar"
    34  
    35  	modelAPI, spec, bundleRef := fixFullAPIDefinitionModelWithAppID("test")
    36  	modelBndl := &model.Bundle{
    37  		ApplicationID: str.Ptr(appID),
    38  		BaseEntity: &model.BaseEntity{
    39  			ID: bundleID,
    40  		},
    41  	}
    42  	gqlAPI := fixFullGQLAPIDefinition("test")
    43  	gqlAPIInput := fixGQLAPIDefinitionInput("name", "foo", "bar")
    44  	modelAPIInput, specInput := fixModelAPIDefinitionInput("name", "foo", "bar")
    45  	txGen := txtest.NewTransactionContextGenerator(testErr)
    46  
    47  	testCases := []struct {
    48  		Name                   string
    49  		TransactionerFn        func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
    50  		ServiceFn              func() *automock.APIService
    51  		BndlServiceFn          func() *automock.BundleService
    52  		BndlReferenceServiceFn func() *automock.BundleReferenceService
    53  		SpecServiceFn          func() *automock.SpecService
    54  		ConverterFn            func() *automock.APIConverter
    55  		AppServiceFn           func() *automock.ApplicationService
    56  		ExpectedAPI            *graphql.APIDefinition
    57  		ExpectedErr            error
    58  	}{
    59  		{
    60  			Name:            "Success",
    61  			TransactionerFn: txGen.ThatSucceeds,
    62  			ServiceFn: func() *automock.APIService {
    63  				svc := &automock.APIService{}
    64  				svc.On("CreateInBundle", txtest.CtxWithDBMatcher(), resource.Application, appID, bundleID, *modelAPIInput, specInput).Return(id, nil).Once()
    65  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
    66  				return svc
    67  			},
    68  			BndlServiceFn: func() *automock.BundleService {
    69  				appSvc := &automock.BundleService{}
    70  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(modelBndl, nil)
    71  				return appSvc
    72  			},
    73  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
    74  				svc := &automock.BundleReferenceService{}
    75  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &gqlAPI.ID, str.Ptr(bundleID)).Return(&bundleRef, nil).Once()
    76  				return svc
    77  			},
    78  			SpecServiceFn: func() *automock.SpecService {
    79  				svc := &automock.SpecService{}
    80  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
    81  				return svc
    82  			},
    83  			ConverterFn: func() *automock.APIConverter {
    84  				conv := &automock.APIConverter{}
    85  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
    86  				conv.On("ToGraphQL", &modelAPI, &spec, &bundleRef).Return(gqlAPI, nil).Once()
    87  				return conv
    88  			},
    89  			AppServiceFn: func() *automock.ApplicationService {
    90  				svc := &automock.ApplicationService{}
    91  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(nil).Once()
    92  
    93  				return svc
    94  			},
    95  			ExpectedAPI: gqlAPI,
    96  			ExpectedErr: nil,
    97  		},
    98  		{
    99  			Name:            "Returns error when starting transaction",
   100  			TransactionerFn: txGen.ThatFailsOnBegin,
   101  			ServiceFn: func() *automock.APIService {
   102  				return &automock.APIService{}
   103  			},
   104  			BndlServiceFn: func() *automock.BundleService {
   105  				return &automock.BundleService{}
   106  			},
   107  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   108  				return &automock.BundleReferenceService{}
   109  			},
   110  			ConverterFn: func() *automock.APIConverter {
   111  				return &automock.APIConverter{}
   112  			},
   113  			SpecServiceFn: func() *automock.SpecService {
   114  				return &automock.SpecService{}
   115  			},
   116  			AppServiceFn: func() *automock.ApplicationService {
   117  				svc := &automock.ApplicationService{}
   118  				svc.AssertNotCalled(t, "UpdateBaseURL")
   119  
   120  				return svc
   121  			},
   122  			ExpectedAPI: nil,
   123  			ExpectedErr: testErr,
   124  		},
   125  		{
   126  			Name:            "Returns error when bundle not exist",
   127  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   128  			ServiceFn: func() *automock.APIService {
   129  				return &automock.APIService{}
   130  			},
   131  			BndlServiceFn: func() *automock.BundleService {
   132  				appSvc := &automock.BundleService{}
   133  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(nil, apperrors.NewNotFoundError(resource.Bundle, bundleID))
   134  				return appSvc
   135  			},
   136  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   137  				return &automock.BundleReferenceService{}
   138  			},
   139  			ConverterFn: func() *automock.APIConverter {
   140  				conv := &automock.APIConverter{}
   141  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
   142  				return conv
   143  			},
   144  			SpecServiceFn: func() *automock.SpecService {
   145  				return &automock.SpecService{}
   146  			},
   147  			AppServiceFn: func() *automock.ApplicationService {
   148  				svc := &automock.ApplicationService{}
   149  				svc.AssertNotCalled(t, "UpdateBaseURL")
   150  
   151  				return svc
   152  			},
   153  			ExpectedAPI: nil,
   154  			ExpectedErr: errors.New("cannot add API to not existing bundle"),
   155  		},
   156  		{
   157  			Name:            "Returns error when bundle existence check failed",
   158  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   159  			ServiceFn: func() *automock.APIService {
   160  				svc := &automock.APIService{}
   161  				return svc
   162  			},
   163  			BndlServiceFn: func() *automock.BundleService {
   164  				appSvc := &automock.BundleService{}
   165  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(nil, testErr)
   166  				return appSvc
   167  			},
   168  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   169  				return &automock.BundleReferenceService{}
   170  			},
   171  			ConverterFn: func() *automock.APIConverter {
   172  				conv := &automock.APIConverter{}
   173  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
   174  				return conv
   175  			},
   176  			SpecServiceFn: func() *automock.SpecService {
   177  				return &automock.SpecService{}
   178  			},
   179  			AppServiceFn: func() *automock.ApplicationService {
   180  				svc := &automock.ApplicationService{}
   181  				svc.AssertNotCalled(t, "UpdateBaseURL")
   182  
   183  				return svc
   184  			},
   185  			ExpectedAPI: nil,
   186  			ExpectedErr: testErr,
   187  		},
   188  		{
   189  			Name:            "Returns error when API creation failed",
   190  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   191  			ServiceFn: func() *automock.APIService {
   192  				svc := &automock.APIService{}
   193  				svc.On("CreateInBundle", txtest.CtxWithDBMatcher(), resource.Application, appID, bundleID, *modelAPIInput, specInput).Return("", testErr).Once()
   194  				return svc
   195  			},
   196  			BndlServiceFn: func() *automock.BundleService {
   197  				appSvc := &automock.BundleService{}
   198  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(modelBndl, nil)
   199  				return appSvc
   200  			},
   201  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   202  				return &automock.BundleReferenceService{}
   203  			},
   204  			ConverterFn: func() *automock.APIConverter {
   205  				conv := &automock.APIConverter{}
   206  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
   207  				return conv
   208  			},
   209  			SpecServiceFn: func() *automock.SpecService {
   210  				return &automock.SpecService{}
   211  			},
   212  			AppServiceFn: func() *automock.ApplicationService {
   213  				svc := &automock.ApplicationService{}
   214  				svc.AssertNotCalled(t, "UpdateBaseURL")
   215  
   216  				return svc
   217  			},
   218  			ExpectedAPI: nil,
   219  			ExpectedErr: testErr,
   220  		},
   221  		{
   222  			Name:            "Returns error when API retrieval failed",
   223  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   224  			ServiceFn: func() *automock.APIService {
   225  				svc := &automock.APIService{}
   226  				svc.On("CreateInBundle", txtest.CtxWithDBMatcher(), resource.Application, appID, bundleID, *modelAPIInput, specInput).Return(id, nil).Once()
   227  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(nil, testErr).Once()
   228  				return svc
   229  			},
   230  			BndlServiceFn: func() *automock.BundleService {
   231  				appSvc := &automock.BundleService{}
   232  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(modelBndl, nil)
   233  				return appSvc
   234  			},
   235  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   236  				return &automock.BundleReferenceService{}
   237  			},
   238  			ConverterFn: func() *automock.APIConverter {
   239  				conv := &automock.APIConverter{}
   240  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
   241  				return conv
   242  			},
   243  			SpecServiceFn: func() *automock.SpecService {
   244  				return &automock.SpecService{}
   245  			},
   246  			AppServiceFn: func() *automock.ApplicationService {
   247  				svc := &automock.ApplicationService{}
   248  				svc.AssertNotCalled(t, "UpdateBaseURL")
   249  
   250  				return svc
   251  			},
   252  			ExpectedAPI: nil,
   253  			ExpectedErr: testErr,
   254  		},
   255  
   256  		{
   257  			Name:            "Returns error when UpdateBaseURL fails",
   258  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   259  			ServiceFn: func() *automock.APIService {
   260  				svc := &automock.APIService{}
   261  				svc.On("CreateInBundle", txtest.CtxWithDBMatcher(), resource.Application, appID, bundleID, *modelAPIInput, specInput).Return(id, nil).Once()
   262  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
   263  				return svc
   264  			},
   265  			BndlServiceFn: func() *automock.BundleService {
   266  				appSvc := &automock.BundleService{}
   267  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(modelBndl, nil)
   268  				return appSvc
   269  			},
   270  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   271  				return &automock.BundleReferenceService{}
   272  			},
   273  			ConverterFn: func() *automock.APIConverter {
   274  				conv := &automock.APIConverter{}
   275  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
   276  				return conv
   277  			},
   278  			SpecServiceFn: func() *automock.SpecService {
   279  				svc := &automock.SpecService{}
   280  				svc.AssertNotCalled(t, "GetByReferenceObjectID")
   281  				return svc
   282  			},
   283  			AppServiceFn: func() *automock.ApplicationService {
   284  				svc := &automock.ApplicationService{}
   285  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(testErr).Once()
   286  
   287  				return svc
   288  			},
   289  			ExpectedAPI: nil,
   290  			ExpectedErr: testErr,
   291  		},
   292  		{
   293  			Name:            "Returns error when Spec retrieval failed",
   294  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   295  			ServiceFn: func() *automock.APIService {
   296  				svc := &automock.APIService{}
   297  				svc.On("CreateInBundle", txtest.CtxWithDBMatcher(), resource.Application, appID, bundleID, *modelAPIInput, specInput).Return(id, nil).Once()
   298  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
   299  				return svc
   300  			},
   301  			BndlServiceFn: func() *automock.BundleService {
   302  				appSvc := &automock.BundleService{}
   303  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(modelBndl, nil)
   304  				return appSvc
   305  			},
   306  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   307  				return &automock.BundleReferenceService{}
   308  			},
   309  			ConverterFn: func() *automock.APIConverter {
   310  				conv := &automock.APIConverter{}
   311  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
   312  				return conv
   313  			},
   314  			SpecServiceFn: func() *automock.SpecService {
   315  				svc := &automock.SpecService{}
   316  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(nil, testErr).Once()
   317  				return svc
   318  			},
   319  			AppServiceFn: func() *automock.ApplicationService {
   320  				svc := &automock.ApplicationService{}
   321  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(nil).Once()
   322  
   323  				return svc
   324  			},
   325  			ExpectedAPI: nil,
   326  			ExpectedErr: testErr,
   327  		},
   328  		{
   329  			Name:            "Returns error when BundleReference retrieval failed",
   330  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   331  			ServiceFn: func() *automock.APIService {
   332  				svc := &automock.APIService{}
   333  				svc.On("CreateInBundle", txtest.CtxWithDBMatcher(), resource.Application, appID, bundleID, *modelAPIInput, specInput).Return(id, nil).Once()
   334  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
   335  				return svc
   336  			},
   337  			BndlServiceFn: func() *automock.BundleService {
   338  				appSvc := &automock.BundleService{}
   339  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(modelBndl, nil)
   340  				return appSvc
   341  			},
   342  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   343  				svc := &automock.BundleReferenceService{}
   344  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &gqlAPI.ID, str.Ptr(bundleID)).Return(nil, testErr).Once()
   345  				return svc
   346  			},
   347  			SpecServiceFn: func() *automock.SpecService {
   348  				svc := &automock.SpecService{}
   349  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
   350  				return svc
   351  			},
   352  			ConverterFn: func() *automock.APIConverter {
   353  				conv := &automock.APIConverter{}
   354  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
   355  				return conv
   356  			},
   357  			AppServiceFn: func() *automock.ApplicationService {
   358  				svc := &automock.ApplicationService{}
   359  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(nil).Once()
   360  
   361  				return svc
   362  			},
   363  			ExpectedAPI: nil,
   364  			ExpectedErr: testErr,
   365  		},
   366  		{
   367  			Name:            "Returns error when converting to graphql",
   368  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   369  			ServiceFn: func() *automock.APIService {
   370  				svc := &automock.APIService{}
   371  				svc.On("CreateInBundle", txtest.CtxWithDBMatcher(), resource.Application, appID, bundleID, *modelAPIInput, specInput).Return(id, nil).Once()
   372  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
   373  				return svc
   374  			},
   375  			BndlServiceFn: func() *automock.BundleService {
   376  				appSvc := &automock.BundleService{}
   377  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(modelBndl, nil)
   378  				return appSvc
   379  			},
   380  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   381  				svc := &automock.BundleReferenceService{}
   382  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &gqlAPI.ID, str.Ptr(bundleID)).Return(&bundleRef, nil).Once()
   383  				return svc
   384  			},
   385  			SpecServiceFn: func() *automock.SpecService {
   386  				svc := &automock.SpecService{}
   387  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
   388  				return svc
   389  			},
   390  			ConverterFn: func() *automock.APIConverter {
   391  				conv := &automock.APIConverter{}
   392  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
   393  				conv.On("ToGraphQL", &modelAPI, &spec, &bundleRef).Return(gqlAPI, testErr).Once()
   394  				return conv
   395  			},
   396  			AppServiceFn: func() *automock.ApplicationService {
   397  				svc := &automock.ApplicationService{}
   398  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(nil).Once()
   399  
   400  				return svc
   401  			},
   402  			ExpectedAPI: nil,
   403  			ExpectedErr: testErr,
   404  		},
   405  		{
   406  			Name:            "Returns error when commit transaction failed",
   407  			TransactionerFn: txGen.ThatFailsOnCommit,
   408  			ServiceFn: func() *automock.APIService {
   409  				svc := &automock.APIService{}
   410  				svc.On("CreateInBundle", txtest.CtxWithDBMatcher(), resource.Application, appID, bundleID, *modelAPIInput, specInput).Return(id, nil).Once()
   411  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
   412  				return svc
   413  			},
   414  			BndlServiceFn: func() *automock.BundleService {
   415  				appSvc := &automock.BundleService{}
   416  				appSvc.On("Get", txtest.CtxWithDBMatcher(), bundleID).Return(modelBndl, nil)
   417  				return appSvc
   418  			},
   419  			BndlReferenceServiceFn: func() *automock.BundleReferenceService {
   420  				svc := &automock.BundleReferenceService{}
   421  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &gqlAPI.ID, str.Ptr(bundleID)).Return(&bundleRef, nil).Once()
   422  				return svc
   423  			},
   424  			ConverterFn: func() *automock.APIConverter {
   425  				conv := &automock.APIConverter{}
   426  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
   427  				conv.On("ToGraphQL", &modelAPI, &spec, &bundleRef).Return(gqlAPI, nil).Once()
   428  				return conv
   429  			},
   430  			SpecServiceFn: func() *automock.SpecService {
   431  				svc := &automock.SpecService{}
   432  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
   433  				return svc
   434  			},
   435  			AppServiceFn: func() *automock.ApplicationService {
   436  				svc := &automock.ApplicationService{}
   437  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(nil).Once()
   438  
   439  				return svc
   440  			},
   441  			ExpectedAPI: nil,
   442  			ExpectedErr: testErr,
   443  		},
   444  	}
   445  
   446  	for _, testCase := range testCases {
   447  		t.Run(testCase.Name, func(t *testing.T) {
   448  			// GIVEN
   449  			persist, transact := testCase.TransactionerFn()
   450  			svc := testCase.ServiceFn()
   451  			converter := testCase.ConverterFn()
   452  			bndlSvc := testCase.BndlServiceFn()
   453  			bndlRefSvc := testCase.BndlReferenceServiceFn()
   454  			specSvc := testCase.SpecServiceFn()
   455  			appSvc := testCase.AppServiceFn()
   456  
   457  			resolver := api.NewResolver(transact, svc, nil, bndlSvc, bndlRefSvc, converter, nil, specSvc, nil, appSvc)
   458  
   459  			// WHEN
   460  			result, err := resolver.AddAPIDefinitionToBundle(context.TODO(), bundleID, *gqlAPIInput)
   461  
   462  			// THEN
   463  			assert.Equal(t, testCase.ExpectedAPI, result)
   464  			if testCase.ExpectedErr != nil {
   465  				require.Error(t, err)
   466  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
   467  			} else {
   468  				require.Nil(t, err)
   469  			}
   470  
   471  			persist.AssertExpectations(t)
   472  			transact.AssertExpectations(t)
   473  			svc.AssertExpectations(t)
   474  			bndlSvc.AssertExpectations(t)
   475  			bndlRefSvc.AssertExpectations(t)
   476  			specSvc.AssertExpectations(t)
   477  			converter.AssertExpectations(t)
   478  			appSvc.AssertExpectations(t)
   479  		})
   480  	}
   481  }
   482  
   483  func TestResolver_DeleteAPI(t *testing.T) {
   484  	// GIVEN
   485  	testErr := errors.New("Test error")
   486  
   487  	id := "bar"
   488  	var nilBundleID *string
   489  
   490  	modelAPIDefinition, spec, bundleRef := fixFullAPIDefinitionModelWithAppID("test")
   491  	gqlAPIDefinition := fixFullGQLAPIDefinition("test")
   492  
   493  	txGen := txtest.NewTransactionContextGenerator(testErr)
   494  
   495  	testCases := []struct {
   496  		Name               string
   497  		TransactionerFn    func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   498  		ServiceFn          func() *automock.APIService
   499  		ConverterFn        func() *automock.APIConverter
   500  		SpecServiceFn      func() *automock.SpecService
   501  		BundleRefServiceFn func() *automock.BundleReferenceService
   502  		ExpectedAPI        *graphql.APIDefinition
   503  		ExpectedErr        error
   504  	}{
   505  		{
   506  			Name:            "Success",
   507  			TransactionerFn: txGen.ThatSucceeds,
   508  			ServiceFn: func() *automock.APIService {
   509  				svc := &automock.APIService{}
   510  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   511  				svc.On("Delete", txtest.CtxWithDBMatcher(), resource.Application, id).Return(nil).Once()
   512  				return svc
   513  			},
   514  			ConverterFn: func() *automock.APIConverter {
   515  				conv := &automock.APIConverter{}
   516  				conv.On("ToGraphQL", &modelAPIDefinition, &spec, &bundleRef).Return(gqlAPIDefinition, nil).Once()
   517  				return conv
   518  			},
   519  			SpecServiceFn: func() *automock.SpecService {
   520  				svc := &automock.SpecService{}
   521  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&spec, nil).Once()
   522  				return svc
   523  			},
   524  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   525  				svc := &automock.BundleReferenceService{}
   526  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPIDefinition.ID, nilBundleID).Return(&bundleRef, nil).Once()
   527  				return svc
   528  			},
   529  			ExpectedAPI: gqlAPIDefinition,
   530  			ExpectedErr: nil,
   531  		},
   532  		{
   533  			Name:            "Return error when starting transaction fails",
   534  			TransactionerFn: txGen.ThatFailsOnBegin,
   535  			ServiceFn: func() *automock.APIService {
   536  				return &automock.APIService{}
   537  			},
   538  			ConverterFn: func() *automock.APIConverter {
   539  				return &automock.APIConverter{}
   540  			},
   541  			SpecServiceFn: func() *automock.SpecService {
   542  				return &automock.SpecService{}
   543  			},
   544  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   545  				return &automock.BundleReferenceService{}
   546  			},
   547  			ExpectedAPI: nil,
   548  			ExpectedErr: testErr,
   549  		},
   550  		{
   551  			Name:            "Returns error when API retrieval failed",
   552  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   553  			ServiceFn: func() *automock.APIService {
   554  				svc := &automock.APIService{}
   555  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(nil, testErr).Once()
   556  				return svc
   557  			},
   558  			ConverterFn: func() *automock.APIConverter {
   559  				return &automock.APIConverter{}
   560  			},
   561  			SpecServiceFn: func() *automock.SpecService {
   562  				return &automock.SpecService{}
   563  			},
   564  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   565  				return &automock.BundleReferenceService{}
   566  			},
   567  			ExpectedAPI: nil,
   568  			ExpectedErr: testErr,
   569  		},
   570  		{
   571  			Name:            "Returns error when Spec retrieval failed",
   572  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   573  			ServiceFn: func() *automock.APIService {
   574  				svc := &automock.APIService{}
   575  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   576  				return svc
   577  			},
   578  			ConverterFn: func() *automock.APIConverter {
   579  				return &automock.APIConverter{}
   580  			},
   581  			SpecServiceFn: func() *automock.SpecService {
   582  				svc := &automock.SpecService{}
   583  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(nil, testErr).Once()
   584  				return svc
   585  			},
   586  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   587  				return &automock.BundleReferenceService{}
   588  			},
   589  			ExpectedAPI: nil,
   590  			ExpectedErr: testErr,
   591  		},
   592  		{
   593  			Name:            "Returns error when BundleReference retrieval failed",
   594  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   595  			ServiceFn: func() *automock.APIService {
   596  				svc := &automock.APIService{}
   597  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   598  				return svc
   599  			},
   600  			ConverterFn: func() *automock.APIConverter {
   601  				return &automock.APIConverter{}
   602  			},
   603  			SpecServiceFn: func() *automock.SpecService {
   604  				svc := &automock.SpecService{}
   605  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&spec, nil).Once()
   606  				return svc
   607  			},
   608  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   609  				svc := &automock.BundleReferenceService{}
   610  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPIDefinition.ID, nilBundleID).Return(nil, testErr).Once()
   611  				return svc
   612  			},
   613  			ExpectedAPI: nil,
   614  			ExpectedErr: testErr,
   615  		},
   616  		{
   617  			Name:            "Returns error when API conversion failed",
   618  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   619  			ServiceFn: func() *automock.APIService {
   620  				svc := &automock.APIService{}
   621  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   622  				return svc
   623  			},
   624  			ConverterFn: func() *automock.APIConverter {
   625  				conv := &automock.APIConverter{}
   626  				conv.On("ToGraphQL", &modelAPIDefinition, &spec, &bundleRef).Return(nil, testErr).Once()
   627  				return conv
   628  			},
   629  			SpecServiceFn: func() *automock.SpecService {
   630  				svc := &automock.SpecService{}
   631  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&spec, nil).Once()
   632  				return svc
   633  			},
   634  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   635  				svc := &automock.BundleReferenceService{}
   636  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPIDefinition.ID, nilBundleID).Return(&bundleRef, nil).Once()
   637  				return svc
   638  			},
   639  			ExpectedAPI: nil,
   640  			ExpectedErr: testErr,
   641  		},
   642  		{
   643  			Name:            "Returns error when API deletion failed",
   644  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   645  			ServiceFn: func() *automock.APIService {
   646  				svc := &automock.APIService{}
   647  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   648  				svc.On("Delete", txtest.CtxWithDBMatcher(), resource.Application, id).Return(testErr).Once()
   649  				return svc
   650  			},
   651  			ConverterFn: func() *automock.APIConverter {
   652  				conv := &automock.APIConverter{}
   653  				conv.On("ToGraphQL", &modelAPIDefinition, &spec, &bundleRef).Return(gqlAPIDefinition, nil).Once()
   654  				return conv
   655  			},
   656  			SpecServiceFn: func() *automock.SpecService {
   657  				svc := &automock.SpecService{}
   658  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&spec, nil).Once()
   659  				return svc
   660  			},
   661  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   662  				svc := &automock.BundleReferenceService{}
   663  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPIDefinition.ID, nilBundleID).Return(&bundleRef, nil).Once()
   664  				return svc
   665  			},
   666  			ExpectedAPI: nil,
   667  			ExpectedErr: testErr,
   668  		},
   669  		{
   670  			Name:            "Return error when commit transaction fails",
   671  			TransactionerFn: txGen.ThatFailsOnCommit,
   672  			ServiceFn: func() *automock.APIService {
   673  				svc := &automock.APIService{}
   674  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   675  				svc.On("Delete", txtest.CtxWithDBMatcher(), resource.Application, id).Return(nil).Once()
   676  				return svc
   677  			},
   678  			ConverterFn: func() *automock.APIConverter {
   679  				conv := &automock.APIConverter{}
   680  				conv.On("ToGraphQL", &modelAPIDefinition, &spec, &bundleRef).Return(gqlAPIDefinition, nil).Once()
   681  				return conv
   682  			},
   683  			SpecServiceFn: func() *automock.SpecService {
   684  				svc := &automock.SpecService{}
   685  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&spec, nil).Once()
   686  				return svc
   687  			},
   688  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   689  				svc := &automock.BundleReferenceService{}
   690  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPIDefinition.ID, nilBundleID).Return(&bundleRef, nil).Once()
   691  				return svc
   692  			},
   693  			ExpectedAPI: nil,
   694  			ExpectedErr: testErr,
   695  		},
   696  	}
   697  
   698  	for _, testCase := range testCases {
   699  		t.Run(testCase.Name, func(t *testing.T) {
   700  			// GIVEN
   701  			persist, transact := testCase.TransactionerFn()
   702  			svc := testCase.ServiceFn()
   703  			specService := testCase.SpecServiceFn()
   704  			converter := testCase.ConverterFn()
   705  			bundleRefService := testCase.BundleRefServiceFn()
   706  
   707  			resolver := api.NewResolver(transact, svc, nil, nil, bundleRefService, converter, nil, specService, nil, nil)
   708  
   709  			// WHEN
   710  			result, err := resolver.DeleteAPIDefinition(context.TODO(), id)
   711  
   712  			// THEN
   713  			assert.Equal(t, testCase.ExpectedAPI, result)
   714  			if testCase.ExpectedErr != nil {
   715  				require.Error(t, err)
   716  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
   717  			} else {
   718  				require.Nil(t, err)
   719  			}
   720  
   721  			svc.AssertExpectations(t)
   722  			specService.AssertExpectations(t)
   723  			converter.AssertExpectations(t)
   724  			bundleRefService.AssertExpectations(t)
   725  			transact.AssertExpectations(t)
   726  			persist.AssertExpectations(t)
   727  		})
   728  	}
   729  }
   730  
   731  func TestResolver_UpdateAPI(t *testing.T) {
   732  	// GIVEN
   733  	testErr := errors.New("Test error")
   734  
   735  	id := "bar"
   736  	var nilBundleID *string
   737  	gqlAPIDefinitionInput := fixGQLAPIDefinitionInput(id, "foo", "bar")
   738  	modelAPIDefinitionInput, modelSpecInput := fixModelAPIDefinitionInput(id, "foo", "bar")
   739  	gqlAPIDefinition := fixFullGQLAPIDefinition("test")
   740  	modelAPIDefinition, modelSpec, modelBundleRef := fixFullAPIDefinitionModelWithAppID("test")
   741  
   742  	txGen := txtest.NewTransactionContextGenerator(testErr)
   743  
   744  	testCases := []struct {
   745  		Name                  string
   746  		TransactionerFn       func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   747  		ServiceFn             func() *automock.APIService
   748  		ConverterFn           func() *automock.APIConverter
   749  		SpecServiceFn         func() *automock.SpecService
   750  		BundleRefServiceFn    func() *automock.BundleReferenceService
   751  		InputWebhookID        string
   752  		InputAPI              graphql.APIDefinitionInput
   753  		ExpectedAPIDefinition *graphql.APIDefinition
   754  		ExpectedErr           error
   755  	}{
   756  		{
   757  			Name:            "Success",
   758  			TransactionerFn: txGen.ThatSucceeds,
   759  			ServiceFn: func() *automock.APIService {
   760  				svc := &automock.APIService{}
   761  				svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
   762  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   763  				return svc
   764  			},
   765  			ConverterFn: func() *automock.APIConverter {
   766  				conv := &automock.APIConverter{}
   767  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
   768  				conv.On("ToGraphQL", &modelAPIDefinition, &modelSpec, &modelBundleRef).Return(gqlAPIDefinition, nil).Once()
   769  				return conv
   770  			},
   771  			SpecServiceFn: func() *automock.SpecService {
   772  				svc := &automock.SpecService{}
   773  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&modelSpec, nil).Once()
   774  				return svc
   775  			},
   776  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   777  				svc := &automock.BundleReferenceService{}
   778  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPIDefinition.ID, nilBundleID).Return(&modelBundleRef, nil).Once()
   779  				return svc
   780  			},
   781  			InputWebhookID:        id,
   782  			InputAPI:              *gqlAPIDefinitionInput,
   783  			ExpectedAPIDefinition: gqlAPIDefinition,
   784  			ExpectedErr:           nil,
   785  		},
   786  		{
   787  			Name:            "Returns error when starting transaction failed",
   788  			TransactionerFn: txGen.ThatFailsOnBegin,
   789  			ServiceFn: func() *automock.APIService {
   790  				return &automock.APIService{}
   791  			},
   792  			ConverterFn: func() *automock.APIConverter {
   793  				return &automock.APIConverter{}
   794  			},
   795  			SpecServiceFn: func() *automock.SpecService {
   796  				return &automock.SpecService{}
   797  			},
   798  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   799  				return &automock.BundleReferenceService{}
   800  			},
   801  			InputWebhookID:        id,
   802  			InputAPI:              *gqlAPIDefinitionInput,
   803  			ExpectedAPIDefinition: nil,
   804  			ExpectedErr:           testErr,
   805  		},
   806  		{
   807  			Name:            "Returns error when converting input to GraphQL fails",
   808  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   809  			ServiceFn: func() *automock.APIService {
   810  				return &automock.APIService{}
   811  			},
   812  			ConverterFn: func() *automock.APIConverter {
   813  				conv := &automock.APIConverter{}
   814  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(nil, nil, testErr).Once()
   815  				return conv
   816  			},
   817  			SpecServiceFn: func() *automock.SpecService {
   818  				return &automock.SpecService{}
   819  			},
   820  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   821  				return &automock.BundleReferenceService{}
   822  			},
   823  			InputWebhookID:        id,
   824  			InputAPI:              *gqlAPIDefinitionInput,
   825  			ExpectedAPIDefinition: nil,
   826  			ExpectedErr:           testErr,
   827  		},
   828  		{
   829  			Name:            "Returns error when API update failed",
   830  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   831  			ServiceFn: func() *automock.APIService {
   832  				svc := &automock.APIService{}
   833  				svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, *modelAPIDefinitionInput, modelSpecInput).Return(testErr).Once()
   834  				return svc
   835  			},
   836  			ConverterFn: func() *automock.APIConverter {
   837  				conv := &automock.APIConverter{}
   838  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
   839  				return conv
   840  			},
   841  			SpecServiceFn: func() *automock.SpecService {
   842  				return &automock.SpecService{}
   843  			},
   844  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   845  				return &automock.BundleReferenceService{}
   846  			},
   847  			InputWebhookID:        id,
   848  			InputAPI:              *gqlAPIDefinitionInput,
   849  			ExpectedAPIDefinition: nil,
   850  			ExpectedErr:           testErr,
   851  		},
   852  		{
   853  			Name:            "Returns error when API retrieval failed",
   854  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   855  			ServiceFn: func() *automock.APIService {
   856  				svc := &automock.APIService{}
   857  				svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
   858  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(nil, testErr).Once()
   859  				return svc
   860  			},
   861  			ConverterFn: func() *automock.APIConverter {
   862  				conv := &automock.APIConverter{}
   863  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
   864  				return conv
   865  			},
   866  			SpecServiceFn: func() *automock.SpecService {
   867  				return &automock.SpecService{}
   868  			},
   869  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   870  				return &automock.BundleReferenceService{}
   871  			},
   872  			InputWebhookID:        id,
   873  			InputAPI:              *gqlAPIDefinitionInput,
   874  			ExpectedAPIDefinition: nil,
   875  			ExpectedErr:           testErr,
   876  		},
   877  		{
   878  			Name:            "Returns error when Spec retrieval failed",
   879  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   880  			ServiceFn: func() *automock.APIService {
   881  				svc := &automock.APIService{}
   882  				svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
   883  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   884  				return svc
   885  			},
   886  			ConverterFn: func() *automock.APIConverter {
   887  				conv := &automock.APIConverter{}
   888  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
   889  				return conv
   890  			},
   891  			SpecServiceFn: func() *automock.SpecService {
   892  				svc := &automock.SpecService{}
   893  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(nil, testErr).Once()
   894  				return svc
   895  			},
   896  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   897  				return &automock.BundleReferenceService{}
   898  			},
   899  			InputWebhookID:        id,
   900  			InputAPI:              *gqlAPIDefinitionInput,
   901  			ExpectedAPIDefinition: nil,
   902  			ExpectedErr:           testErr,
   903  		},
   904  		{
   905  			Name:            "Returns error when BundleReference retrieval failed",
   906  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   907  			ServiceFn: func() *automock.APIService {
   908  				svc := &automock.APIService{}
   909  				svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
   910  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   911  				return svc
   912  			},
   913  			ConverterFn: func() *automock.APIConverter {
   914  				conv := &automock.APIConverter{}
   915  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
   916  				return conv
   917  			},
   918  			SpecServiceFn: func() *automock.SpecService {
   919  				svc := &automock.SpecService{}
   920  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&modelSpec, nil).Once()
   921  				return svc
   922  			},
   923  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   924  				svc := &automock.BundleReferenceService{}
   925  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPIDefinition.ID, nilBundleID).Return(nil, testErr).Once()
   926  				return svc
   927  			},
   928  			InputWebhookID:        id,
   929  			InputAPI:              *gqlAPIDefinitionInput,
   930  			ExpectedAPIDefinition: nil,
   931  			ExpectedErr:           testErr,
   932  		},
   933  		{
   934  			Name:            "Returns error when converting to GraphQL failed",
   935  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   936  			ServiceFn: func() *automock.APIService {
   937  				svc := &automock.APIService{}
   938  				svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
   939  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   940  				return svc
   941  			},
   942  			ConverterFn: func() *automock.APIConverter {
   943  				conv := &automock.APIConverter{}
   944  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
   945  				conv.On("ToGraphQL", &modelAPIDefinition, &modelSpec, &modelBundleRef).Return(nil, testErr).Once()
   946  				return conv
   947  			},
   948  			SpecServiceFn: func() *automock.SpecService {
   949  				svc := &automock.SpecService{}
   950  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&modelSpec, nil).Once()
   951  				return svc
   952  			},
   953  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   954  				svc := &automock.BundleReferenceService{}
   955  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPIDefinition.ID, nilBundleID).Return(&modelBundleRef, nil).Once()
   956  				return svc
   957  			},
   958  			InputWebhookID:        id,
   959  			InputAPI:              *gqlAPIDefinitionInput,
   960  			ExpectedAPIDefinition: nil,
   961  			ExpectedErr:           testErr,
   962  		},
   963  		{
   964  			Name:            "Returns error when commit transaction failed",
   965  			TransactionerFn: txGen.ThatFailsOnCommit,
   966  			ServiceFn: func() *automock.APIService {
   967  				svc := &automock.APIService{}
   968  				svc.On("Update", txtest.CtxWithDBMatcher(), resource.Application, id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
   969  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
   970  				return svc
   971  			},
   972  			ConverterFn: func() *automock.APIConverter {
   973  				conv := &automock.APIConverter{}
   974  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
   975  				conv.On("ToGraphQL", &modelAPIDefinition, &modelSpec, &modelBundleRef).Return(gqlAPIDefinition, nil).Once()
   976  				return conv
   977  			},
   978  			SpecServiceFn: func() *automock.SpecService {
   979  				svc := &automock.SpecService{}
   980  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&modelSpec, nil).Once()
   981  				return svc
   982  			},
   983  			BundleRefServiceFn: func() *automock.BundleReferenceService {
   984  				svc := &automock.BundleReferenceService{}
   985  				svc.On("GetForBundle", txtest.CtxWithDBMatcher(), model.BundleAPIReference, &modelAPIDefinition.ID, nilBundleID).Return(&modelBundleRef, nil).Once()
   986  				return svc
   987  			},
   988  			InputWebhookID:        id,
   989  			InputAPI:              *gqlAPIDefinitionInput,
   990  			ExpectedAPIDefinition: nil,
   991  			ExpectedErr:           testErr,
   992  		},
   993  	}
   994  
   995  	for _, testCase := range testCases {
   996  		t.Run(testCase.Name, func(t *testing.T) {
   997  			// GIVEN
   998  			persist, transact := testCase.TransactionerFn()
   999  			svc := testCase.ServiceFn()
  1000  			converter := testCase.ConverterFn()
  1001  			specService := testCase.SpecServiceFn()
  1002  			bundleRefService := testCase.BundleRefServiceFn()
  1003  
  1004  			resolver := api.NewResolver(transact, svc, nil, nil, bundleRefService, converter, nil, specService, nil, nil)
  1005  
  1006  			// WHEN
  1007  			result, err := resolver.UpdateAPIDefinition(context.TODO(), id, *gqlAPIDefinitionInput)
  1008  
  1009  			// THEN
  1010  			assert.Equal(t, testCase.ExpectedAPIDefinition, result)
  1011  			if testCase.ExpectedErr != nil {
  1012  				require.Error(t, err)
  1013  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1014  			} else {
  1015  				require.Nil(t, err)
  1016  			}
  1017  
  1018  			persist.AssertExpectations(t)
  1019  			transact.AssertExpectations(t)
  1020  			svc.AssertExpectations(t)
  1021  			specService.AssertExpectations(t)
  1022  			bundleRefService.AssertExpectations(t)
  1023  			converter.AssertExpectations(t)
  1024  		})
  1025  	}
  1026  }
  1027  
  1028  func TestResolver_RefetchAPISpec(t *testing.T) {
  1029  	// GIVEN
  1030  	testErr := errors.New("test error")
  1031  
  1032  	apiID := "apiID"
  1033  	specID := "specID"
  1034  
  1035  	dataBytes := "data"
  1036  	modelSpec := &model.Spec{
  1037  		ID:   specID,
  1038  		Data: &dataBytes,
  1039  	}
  1040  
  1041  	clob := graphql.CLOB(dataBytes)
  1042  	gqlAPISpec := &graphql.APISpec{
  1043  		Data: &clob,
  1044  	}
  1045  
  1046  	txGen := txtest.NewTransactionContextGenerator(testErr)
  1047  
  1048  	testCases := []struct {
  1049  		Name            string
  1050  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  1051  		ServiceFn       func() *automock.SpecService
  1052  		ConvFn          func() *automock.SpecConverter
  1053  		ExpectedAPISpec *graphql.APISpec
  1054  		ExpectedErr     error
  1055  	}{
  1056  		{
  1057  			Name:            "Success",
  1058  			TransactionerFn: txGen.ThatSucceeds,
  1059  			ServiceFn: func() *automock.SpecService {
  1060  				svc := &automock.SpecService{}
  1061  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, apiID).Return(modelSpec, nil).Once()
  1062  				svc.On("RefetchSpec", txtest.CtxWithDBMatcher(), specID, model.APISpecReference).Return(modelSpec, nil).Once()
  1063  				return svc
  1064  			},
  1065  			ConvFn: func() *automock.SpecConverter {
  1066  				conv := &automock.SpecConverter{}
  1067  				conv.On("ToGraphQLAPISpec", modelSpec).Return(gqlAPISpec, nil).Once()
  1068  				return conv
  1069  			},
  1070  			ExpectedAPISpec: gqlAPISpec,
  1071  			ExpectedErr:     nil,
  1072  		},
  1073  		{
  1074  			Name:            "Returns error when starting transaction",
  1075  			TransactionerFn: txGen.ThatFailsOnBegin,
  1076  			ServiceFn: func() *automock.SpecService {
  1077  				return &automock.SpecService{}
  1078  			},
  1079  			ConvFn: func() *automock.SpecConverter {
  1080  				return &automock.SpecConverter{}
  1081  			},
  1082  			ExpectedAPISpec: nil,
  1083  			ExpectedErr:     testErr,
  1084  		},
  1085  		{
  1086  			Name:            "Returns error when getting spec failed",
  1087  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1088  			ServiceFn: func() *automock.SpecService {
  1089  				svc := &automock.SpecService{}
  1090  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, apiID).Return(nil, testErr).Once()
  1091  				return svc
  1092  			},
  1093  			ConvFn: func() *automock.SpecConverter {
  1094  				return &automock.SpecConverter{}
  1095  			},
  1096  			ExpectedAPISpec: nil,
  1097  			ExpectedErr:     testErr,
  1098  		},
  1099  		{
  1100  			Name:            "Returns error when spec not found",
  1101  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1102  			ServiceFn: func() *automock.SpecService {
  1103  				svc := &automock.SpecService{}
  1104  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, apiID).Return(nil, nil).Once()
  1105  				return svc
  1106  			},
  1107  			ConvFn: func() *automock.SpecConverter {
  1108  				return &automock.SpecConverter{}
  1109  			},
  1110  			ExpectedAPISpec: nil,
  1111  			ExpectedErr:     errors.Errorf("spec for API with id %q not found", apiID),
  1112  		},
  1113  		{
  1114  			Name:            "Returns error when refetching api spec failed",
  1115  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1116  			ServiceFn: func() *automock.SpecService {
  1117  				svc := &automock.SpecService{}
  1118  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, apiID).Return(modelSpec, nil).Once()
  1119  				svc.On("RefetchSpec", txtest.CtxWithDBMatcher(), specID, model.APISpecReference).Return(nil, testErr).Once()
  1120  				return svc
  1121  			},
  1122  			ConvFn: func() *automock.SpecConverter {
  1123  				return &automock.SpecConverter{}
  1124  			},
  1125  			ExpectedAPISpec: nil,
  1126  			ExpectedErr:     testErr,
  1127  		},
  1128  		{
  1129  			Name:            "Returns error converting to GraphQL fails",
  1130  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1131  			ServiceFn: func() *automock.SpecService {
  1132  				svc := &automock.SpecService{}
  1133  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, apiID).Return(modelSpec, nil).Once()
  1134  				svc.On("RefetchSpec", txtest.CtxWithDBMatcher(), specID, model.APISpecReference).Return(modelSpec, nil).Once()
  1135  				return svc
  1136  			},
  1137  			ConvFn: func() *automock.SpecConverter {
  1138  				conv := &automock.SpecConverter{}
  1139  				conv.On("ToGraphQLAPISpec", modelSpec).Return(nil, testErr).Once()
  1140  				return conv
  1141  			},
  1142  			ExpectedAPISpec: nil,
  1143  			ExpectedErr:     testErr,
  1144  		},
  1145  		{
  1146  			Name:            "Returns error when commit transaction failed",
  1147  			TransactionerFn: txGen.ThatFailsOnCommit,
  1148  			ServiceFn: func() *automock.SpecService {
  1149  				svc := &automock.SpecService{}
  1150  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, apiID).Return(modelSpec, nil).Once()
  1151  				svc.On("RefetchSpec", txtest.CtxWithDBMatcher(), specID, model.APISpecReference).Return(modelSpec, nil).Once()
  1152  				return svc
  1153  			},
  1154  			ConvFn: func() *automock.SpecConverter {
  1155  				conv := &automock.SpecConverter{}
  1156  				conv.On("ToGraphQLAPISpec", modelSpec).Return(gqlAPISpec, nil).Once()
  1157  				return conv
  1158  			},
  1159  			ExpectedAPISpec: nil,
  1160  			ExpectedErr:     testErr,
  1161  		},
  1162  	}
  1163  
  1164  	for _, testCase := range testCases {
  1165  		t.Run(testCase.Name, func(t *testing.T) {
  1166  			// GIVEN
  1167  			svc := testCase.ServiceFn()
  1168  			conv := testCase.ConvFn()
  1169  			persist, transact := testCase.TransactionerFn()
  1170  			resolver := api.NewResolver(transact, nil, nil, nil, nil, nil, nil, svc, conv, nil)
  1171  
  1172  			// WHEN
  1173  			result, err := resolver.RefetchAPISpec(context.TODO(), apiID)
  1174  
  1175  			// then
  1176  			assert.Equal(t, testCase.ExpectedAPISpec, result)
  1177  			if testCase.ExpectedErr != nil {
  1178  				require.Error(t, err)
  1179  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1180  			} else {
  1181  				require.Nil(t, err)
  1182  			}
  1183  
  1184  			persist.AssertExpectations(t)
  1185  			transact.AssertExpectations(t)
  1186  			svc.AssertExpectations(t)
  1187  			conv.AssertExpectations(t)
  1188  		})
  1189  	}
  1190  }
  1191  
  1192  func TestResolver_FetchRequest(t *testing.T) {
  1193  	// GIVEN
  1194  	testErr := errors.New("Test error")
  1195  
  1196  	firstSpecID := "specID"
  1197  	secondSpecID := "specID2"
  1198  	specIDs := []string{firstSpecID, secondSpecID}
  1199  	firstFRID := "frID"
  1200  	secondFRID := "frID2"
  1201  	frURL := "foo.bar"
  1202  	timestamp := time.Now()
  1203  
  1204  	frFirstSpec := fixModelFetchRequest(firstFRID, frURL, timestamp)
  1205  	frSecondSpec := fixModelFetchRequest(secondFRID, frURL, timestamp)
  1206  	fetchRequests := []*model.FetchRequest{frFirstSpec, frSecondSpec}
  1207  
  1208  	gqlFRFirstSpec := fixGQLFetchRequest(frURL, timestamp)
  1209  	gqlFRSecondSpec := fixGQLFetchRequest(frURL, timestamp)
  1210  	gqlFetchRequests := []*graphql.FetchRequest{gqlFRFirstSpec, gqlFRSecondSpec}
  1211  
  1212  	txGen := txtest.NewTransactionContextGenerator(testErr)
  1213  
  1214  	testCases := []struct {
  1215  		Name            string
  1216  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  1217  		ServiceFn       func() *automock.APIService
  1218  		ConverterFn     func() *automock.FetchRequestConverter
  1219  		ExpectedResult  []*graphql.FetchRequest
  1220  		ExpectedErr     []error
  1221  	}{
  1222  		{
  1223  			Name:            "Success",
  1224  			TransactionerFn: txGen.ThatSucceeds,
  1225  			ServiceFn: func() *automock.APIService {
  1226  				svc := &automock.APIService{}
  1227  				svc.On("ListFetchRequests", txtest.CtxWithDBMatcher(), specIDs).Return(fetchRequests, nil).Once()
  1228  				return svc
  1229  			},
  1230  			ConverterFn: func() *automock.FetchRequestConverter {
  1231  				conv := &automock.FetchRequestConverter{}
  1232  				conv.On("ToGraphQL", frFirstSpec).Return(gqlFRFirstSpec, nil).Once()
  1233  				conv.On("ToGraphQL", frSecondSpec).Return(gqlFRSecondSpec, nil).Once()
  1234  				return conv
  1235  			},
  1236  			ExpectedResult: gqlFetchRequests,
  1237  			ExpectedErr:    nil,
  1238  		},
  1239  		{
  1240  			Name:            "Returns error when starting transaction failed",
  1241  			TransactionerFn: txGen.ThatFailsOnBegin,
  1242  			ServiceFn: func() *automock.APIService {
  1243  				svc := &automock.APIService{}
  1244  				return svc
  1245  			},
  1246  			ConverterFn: func() *automock.FetchRequestConverter {
  1247  				conv := &automock.FetchRequestConverter{}
  1248  				return conv
  1249  			},
  1250  			ExpectedResult: nil,
  1251  			ExpectedErr:    []error{testErr},
  1252  		},
  1253  		{
  1254  			Name:            "FetchRequest doesn't exist",
  1255  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1256  			ServiceFn: func() *automock.APIService {
  1257  				svc := &automock.APIService{}
  1258  				svc.On("ListFetchRequests", txtest.CtxWithDBMatcher(), specIDs).Return(nil, nil).Once()
  1259  				return svc
  1260  			},
  1261  			ConverterFn: func() *automock.FetchRequestConverter {
  1262  				conv := &automock.FetchRequestConverter{}
  1263  				return conv
  1264  			},
  1265  			ExpectedResult: nil,
  1266  			ExpectedErr:    nil,
  1267  		},
  1268  		{
  1269  			Name:            "Error when listing API FetchRequests",
  1270  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1271  			ServiceFn: func() *automock.APIService {
  1272  				svc := &automock.APIService{}
  1273  				svc.On("ListFetchRequests", txtest.CtxWithDBMatcher(), specIDs).Return(nil, testErr).Once()
  1274  				return svc
  1275  			},
  1276  			ConverterFn: func() *automock.FetchRequestConverter {
  1277  				conv := &automock.FetchRequestConverter{}
  1278  				return conv
  1279  			},
  1280  			ExpectedResult: nil,
  1281  			ExpectedErr:    []error{testErr},
  1282  		},
  1283  		{
  1284  			Name:            "Error when converting FetchRequest to graphql",
  1285  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1286  			ServiceFn: func() *automock.APIService {
  1287  				svc := &automock.APIService{}
  1288  				svc.On("ListFetchRequests", txtest.CtxWithDBMatcher(), specIDs).Return(fetchRequests, nil).Once()
  1289  				return svc
  1290  			},
  1291  			ConverterFn: func() *automock.FetchRequestConverter {
  1292  				conv := &automock.FetchRequestConverter{}
  1293  				conv.On("ToGraphQL", frFirstSpec).Return(nil, testErr).Once()
  1294  				return conv
  1295  			},
  1296  			ExpectedResult: nil,
  1297  			ExpectedErr:    []error{testErr},
  1298  		},
  1299  		{
  1300  			Name:            "Returns error when commit transaction fails",
  1301  			TransactionerFn: txGen.ThatFailsOnCommit,
  1302  			ServiceFn: func() *automock.APIService {
  1303  				svc := &automock.APIService{}
  1304  				svc.On("ListFetchRequests", txtest.CtxWithDBMatcher(), specIDs).Return(fetchRequests, nil).Once()
  1305  				return svc
  1306  			},
  1307  			ConverterFn: func() *automock.FetchRequestConverter {
  1308  				conv := &automock.FetchRequestConverter{}
  1309  				conv.On("ToGraphQL", frFirstSpec).Return(gqlFRFirstSpec, nil).Once()
  1310  				conv.On("ToGraphQL", frSecondSpec).Return(gqlFRSecondSpec, nil).Once()
  1311  				return conv
  1312  			},
  1313  			ExpectedResult: nil,
  1314  			ExpectedErr:    []error{testErr},
  1315  		},
  1316  	}
  1317  
  1318  	for _, testCase := range testCases {
  1319  		t.Run(testCase.Name, func(t *testing.T) {
  1320  			persist, transact := testCase.TransactionerFn()
  1321  			svc := testCase.ServiceFn()
  1322  			converter := testCase.ConverterFn()
  1323  
  1324  			firstFRParams := dataloader.ParamFetchRequestAPIDef{ID: firstSpecID, Ctx: context.TODO()}
  1325  			secondFRParams := dataloader.ParamFetchRequestAPIDef{ID: secondSpecID, Ctx: context.TODO()}
  1326  			keys := []dataloader.ParamFetchRequestAPIDef{firstFRParams, secondFRParams}
  1327  			resolver := api.NewResolver(transact, svc, nil, nil, nil, nil, converter, nil, nil, nil)
  1328  
  1329  			// WHEN
  1330  			result, err := resolver.FetchRequestAPIDefDataLoader(keys)
  1331  
  1332  			// then
  1333  			assert.Equal(t, testCase.ExpectedResult, result)
  1334  			assert.Equal(t, testCase.ExpectedErr, err)
  1335  
  1336  			svc.AssertExpectations(t)
  1337  			converter.AssertExpectations(t)
  1338  			persist.AssertExpectations(t)
  1339  			transact.AssertExpectations(t)
  1340  		})
  1341  	}
  1342  
  1343  	t.Run("Returns error when there are no Specs", func(t *testing.T) {
  1344  		resolver := api.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
  1345  		// WHEN
  1346  		_, err := resolver.FetchRequestAPIDefDataLoader([]dataloader.ParamFetchRequestAPIDef{})
  1347  		// THEN
  1348  		require.Error(t, err[0])
  1349  		assert.EqualError(t, err[0], apperrors.NewInternalError("No APIDef specs found").Error())
  1350  	})
  1351  
  1352  	t.Run("Returns error when Specification ID is empty", func(t *testing.T) {
  1353  		params := dataloader.ParamFetchRequestAPIDef{ID: "", Ctx: context.TODO()}
  1354  		keys := []dataloader.ParamFetchRequestAPIDef{params}
  1355  
  1356  		resolver := api.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
  1357  		// WHEN
  1358  		_, err := resolver.FetchRequestAPIDefDataLoader(keys)
  1359  		// THEN
  1360  		require.Error(t, err[0])
  1361  		assert.EqualError(t, err[0], apperrors.NewInternalError("Cannot fetch FetchRequest. APIDefinition Spec ID is empty").Error())
  1362  	})
  1363  }
  1364  
  1365  func TestResolver_APIDefinitionsForApplication(t *testing.T) {
  1366  	// GIVEN
  1367  	testErr := errors.New("Test error")
  1368  
  1369  	pageSize := 100
  1370  	cursor := ""
  1371  	gqlCursor := graphql.PageCursor(cursor)
  1372  
  1373  	modelAPI, spec, _ := fixFullAPIDefinitionModel(apiDefID, "test")
  1374  	gqlAPI := fixFullGQLAPIDefinition("test")
  1375  
  1376  	modelPage := &model.APIDefinitionPage{
  1377  		Data: []*model.APIDefinition{&modelAPI},
  1378  		PageInfo: &pagination.Page{
  1379  			StartCursor: "",
  1380  			EndCursor:   "",
  1381  			HasNextPage: false,
  1382  		},
  1383  		TotalCount: 1,
  1384  	}
  1385  	gqlPage := &graphql.APIDefinitionPage{
  1386  		Data: []*graphql.APIDefinition{gqlAPI},
  1387  		PageInfo: &graphql.PageInfo{
  1388  			StartCursor: "",
  1389  			EndCursor:   "",
  1390  			HasNextPage: false,
  1391  		},
  1392  		TotalCount: 1,
  1393  	}
  1394  	var bundleRef *model.BundleReference
  1395  	txGen := txtest.NewTransactionContextGenerator(testErr)
  1396  
  1397  	testCases := []struct {
  1398  		Name            string
  1399  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  1400  		ServiceFn       func() *automock.APIService
  1401  		SpecServiceFn   func() *automock.SpecService
  1402  		ConverterFn     func() *automock.APIConverter
  1403  		PageSize        *int
  1404  		ExpectedAPI     *graphql.APIDefinitionPage
  1405  		ExpectedErr     error
  1406  	}{
  1407  		{
  1408  			Name:            "Success",
  1409  			TransactionerFn: txGen.ThatSucceeds,
  1410  			ServiceFn: func() *automock.APIService {
  1411  				svc := &automock.APIService{}
  1412  				svc.On("ListByApplicationIDPage", txtest.CtxWithDBMatcher(), appID, pageSize, cursor).Return(modelPage, nil).Once()
  1413  				return svc
  1414  			},
  1415  			SpecServiceFn: func() *automock.SpecService {
  1416  				svc := &automock.SpecService{}
  1417  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
  1418  				return svc
  1419  			},
  1420  			ConverterFn: func() *automock.APIConverter {
  1421  				conv := &automock.APIConverter{}
  1422  				conv.On("ToGraphQL", &modelAPI, &spec, bundleRef).Return(gqlAPI, nil).Once()
  1423  				return conv
  1424  			},
  1425  			PageSize:    &pageSize,
  1426  			ExpectedAPI: gqlPage,
  1427  		},
  1428  		{
  1429  			Name:            "Error when page size is missing",
  1430  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1431  			ServiceFn: func() *automock.APIService {
  1432  				svc := &automock.APIService{}
  1433  				return svc
  1434  			},
  1435  			SpecServiceFn: func() *automock.SpecService {
  1436  				svc := &automock.SpecService{}
  1437  				return svc
  1438  			},
  1439  			ConverterFn: func() *automock.APIConverter {
  1440  				conv := &automock.APIConverter{}
  1441  				return conv
  1442  			},
  1443  			ExpectedErr: errors.New("missing required parameter 'first'"),
  1444  		},
  1445  		{
  1446  			Name:            "Error when starting transaction fails",
  1447  			TransactionerFn: txGen.ThatFailsOnBegin,
  1448  			ServiceFn: func() *automock.APIService {
  1449  				svc := &automock.APIService{}
  1450  				return svc
  1451  			},
  1452  			SpecServiceFn: func() *automock.SpecService {
  1453  				svc := &automock.SpecService{}
  1454  				return svc
  1455  			},
  1456  			ConverterFn: func() *automock.APIConverter {
  1457  				conv := &automock.APIConverter{}
  1458  				return conv
  1459  			},
  1460  			ExpectedErr: testErr,
  1461  		},
  1462  		{
  1463  			Name:            "Error when listing page fails",
  1464  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1465  			ServiceFn: func() *automock.APIService {
  1466  				svc := &automock.APIService{}
  1467  				svc.On("ListByApplicationIDPage", txtest.CtxWithDBMatcher(), appID, pageSize, cursor).Return(nil, testErr).Once()
  1468  				return svc
  1469  			},
  1470  			SpecServiceFn: func() *automock.SpecService {
  1471  				svc := &automock.SpecService{}
  1472  				return svc
  1473  			},
  1474  			ConverterFn: func() *automock.APIConverter {
  1475  				conv := &automock.APIConverter{}
  1476  				return conv
  1477  			},
  1478  			PageSize:    &pageSize,
  1479  			ExpectedErr: testErr,
  1480  		},
  1481  		{
  1482  			Name:            "Error when getting spec fails",
  1483  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1484  			ServiceFn: func() *automock.APIService {
  1485  				svc := &automock.APIService{}
  1486  				svc.On("ListByApplicationIDPage", txtest.CtxWithDBMatcher(), appID, pageSize, cursor).Return(modelPage, nil).Once()
  1487  				return svc
  1488  			},
  1489  			SpecServiceFn: func() *automock.SpecService {
  1490  				svc := &automock.SpecService{}
  1491  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(nil, testErr).Once()
  1492  				return svc
  1493  			},
  1494  			ConverterFn: func() *automock.APIConverter {
  1495  				conv := &automock.APIConverter{}
  1496  				return conv
  1497  			},
  1498  			PageSize:    &pageSize,
  1499  			ExpectedErr: testErr,
  1500  		},
  1501  		{
  1502  			Name:            "Error when graphql conversion fails",
  1503  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1504  			ServiceFn: func() *automock.APIService {
  1505  				svc := &automock.APIService{}
  1506  				svc.On("ListByApplicationIDPage", txtest.CtxWithDBMatcher(), appID, pageSize, cursor).Return(modelPage, nil).Once()
  1507  				return svc
  1508  			},
  1509  			SpecServiceFn: func() *automock.SpecService {
  1510  				svc := &automock.SpecService{}
  1511  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
  1512  				return svc
  1513  			},
  1514  			ConverterFn: func() *automock.APIConverter {
  1515  				conv := &automock.APIConverter{}
  1516  				conv.On("ToGraphQL", &modelAPI, &spec, bundleRef).Return(nil, testErr).Once()
  1517  				return conv
  1518  			},
  1519  			PageSize:    &pageSize,
  1520  			ExpectedErr: testErr,
  1521  		},
  1522  		{
  1523  			Name:            "Error when committing transaction fails",
  1524  			TransactionerFn: txGen.ThatFailsOnCommit,
  1525  			ServiceFn: func() *automock.APIService {
  1526  				svc := &automock.APIService{}
  1527  				svc.On("ListByApplicationIDPage", txtest.CtxWithDBMatcher(), appID, pageSize, cursor).Return(modelPage, nil).Once()
  1528  				return svc
  1529  			},
  1530  			SpecServiceFn: func() *automock.SpecService {
  1531  				svc := &automock.SpecService{}
  1532  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
  1533  				return svc
  1534  			},
  1535  			ConverterFn: func() *automock.APIConverter {
  1536  				conv := &automock.APIConverter{}
  1537  				conv.On("ToGraphQL", &modelAPI, &spec, bundleRef).Return(gqlAPI, nil).Once()
  1538  				return conv
  1539  			},
  1540  			PageSize:    &pageSize,
  1541  			ExpectedErr: testErr,
  1542  		},
  1543  	}
  1544  
  1545  	for _, testCase := range testCases {
  1546  		t.Run(testCase.Name, func(t *testing.T) {
  1547  			// GIVEN
  1548  			persist, transact := testCase.TransactionerFn()
  1549  			svc := testCase.ServiceFn()
  1550  			converter := testCase.ConverterFn()
  1551  			specSvc := testCase.SpecServiceFn()
  1552  			defer mock.AssertExpectationsForObjects(t, persist, transact, svc, specSvc, converter)
  1553  
  1554  			resolver := api.NewResolver(transact, svc, nil, nil, nil, converter, nil, specSvc, nil, nil)
  1555  
  1556  			// WHEN
  1557  			result, err := resolver.APIDefinitionsForApplication(context.TODO(), appID, testCase.PageSize, &gqlCursor)
  1558  
  1559  			// THEN
  1560  			assert.Equal(t, testCase.ExpectedAPI, result)
  1561  			if testCase.ExpectedErr != nil {
  1562  				require.Error(t, err)
  1563  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1564  			} else {
  1565  				require.Nil(t, err)
  1566  			}
  1567  		})
  1568  	}
  1569  }
  1570  
  1571  func TestResolver_AddAPIDefinitionToApplication(t *testing.T) {
  1572  	// GIVEN
  1573  	testErr := errors.New("Test error")
  1574  
  1575  	id := "bar"
  1576  
  1577  	modelAPI, spec, _ := fixFullAPIDefinitionModelWithAppID("test")
  1578  	var bundleRef *model.BundleReference
  1579  
  1580  	gqlAPI := fixFullGQLAPIDefinition("test")
  1581  	gqlAPIInput := fixGQLAPIDefinitionInput("name", "foo", "bar")
  1582  	modelAPIInput, specInput := fixModelAPIDefinitionInput("name", "foo", "bar")
  1583  	txGen := txtest.NewTransactionContextGenerator(testErr)
  1584  
  1585  	testCases := []struct {
  1586  		Name            string
  1587  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  1588  		ServiceFn       func() *automock.APIService
  1589  		SpecServiceFn   func() *automock.SpecService
  1590  		ConverterFn     func() *automock.APIConverter
  1591  		AppServiceFn    func() *automock.ApplicationService
  1592  		ExpectedAPI     *graphql.APIDefinition
  1593  		ExpectedErr     error
  1594  	}{
  1595  		{
  1596  			Name:            "Success",
  1597  			TransactionerFn: txGen.ThatSucceeds,
  1598  			ServiceFn: func() *automock.APIService {
  1599  				svc := &automock.APIService{}
  1600  				svc.On("CreateInApplication", txtest.CtxWithDBMatcher(), appID, *modelAPIInput, specInput).Return(id, nil).Once()
  1601  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
  1602  				return svc
  1603  			},
  1604  			SpecServiceFn: func() *automock.SpecService {
  1605  				svc := &automock.SpecService{}
  1606  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
  1607  				return svc
  1608  			},
  1609  			ConverterFn: func() *automock.APIConverter {
  1610  				conv := &automock.APIConverter{}
  1611  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
  1612  				conv.On("ToGraphQL", &modelAPI, &spec, bundleRef).Return(gqlAPI, nil).Once()
  1613  				return conv
  1614  			},
  1615  			AppServiceFn: func() *automock.ApplicationService {
  1616  				svc := &automock.ApplicationService{}
  1617  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(nil).Once()
  1618  
  1619  				return svc
  1620  			},
  1621  			ExpectedAPI: gqlAPI,
  1622  			ExpectedErr: nil,
  1623  		},
  1624  		{
  1625  			Name:            "Error when starting transaction",
  1626  			TransactionerFn: txGen.ThatFailsOnBegin,
  1627  			ServiceFn: func() *automock.APIService {
  1628  				svc := &automock.APIService{}
  1629  				return svc
  1630  			},
  1631  			SpecServiceFn: func() *automock.SpecService {
  1632  				svc := &automock.SpecService{}
  1633  				return svc
  1634  			},
  1635  			ConverterFn: func() *automock.APIConverter {
  1636  				conv := &automock.APIConverter{}
  1637  				return conv
  1638  			},
  1639  			AppServiceFn: func() *automock.ApplicationService {
  1640  				svc := &automock.ApplicationService{}
  1641  
  1642  				return svc
  1643  			},
  1644  			ExpectedErr: testErr,
  1645  		},
  1646  		{
  1647  			Name:            "Error when converting into model fails",
  1648  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1649  			ServiceFn: func() *automock.APIService {
  1650  				svc := &automock.APIService{}
  1651  				return svc
  1652  			},
  1653  			SpecServiceFn: func() *automock.SpecService {
  1654  				svc := &automock.SpecService{}
  1655  				return svc
  1656  			},
  1657  			ConverterFn: func() *automock.APIConverter {
  1658  				conv := &automock.APIConverter{}
  1659  				conv.On("InputFromGraphQL", gqlAPIInput).Return(nil, nil, testErr).Once()
  1660  				return conv
  1661  			},
  1662  			AppServiceFn: func() *automock.ApplicationService {
  1663  				svc := &automock.ApplicationService{}
  1664  
  1665  				return svc
  1666  			},
  1667  			ExpectedErr: testErr,
  1668  		},
  1669  		{
  1670  			Name:            "Error when creating API fails",
  1671  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1672  			ServiceFn: func() *automock.APIService {
  1673  				svc := &automock.APIService{}
  1674  				svc.On("CreateInApplication", txtest.CtxWithDBMatcher(), appID, *modelAPIInput, specInput).Return("", testErr).Once()
  1675  				return svc
  1676  			},
  1677  			SpecServiceFn: func() *automock.SpecService {
  1678  				svc := &automock.SpecService{}
  1679  				return svc
  1680  			},
  1681  			ConverterFn: func() *automock.APIConverter {
  1682  				conv := &automock.APIConverter{}
  1683  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
  1684  				return conv
  1685  			},
  1686  			AppServiceFn: func() *automock.ApplicationService {
  1687  				svc := &automock.ApplicationService{}
  1688  				return svc
  1689  			},
  1690  			ExpectedErr: testErr,
  1691  		},
  1692  		{
  1693  			Name:            "Error when getting the API fails",
  1694  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1695  			ServiceFn: func() *automock.APIService {
  1696  				svc := &automock.APIService{}
  1697  				svc.On("CreateInApplication", txtest.CtxWithDBMatcher(), appID, *modelAPIInput, specInput).Return(id, nil).Once()
  1698  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(nil, testErr).Once()
  1699  				return svc
  1700  			},
  1701  			SpecServiceFn: func() *automock.SpecService {
  1702  				svc := &automock.SpecService{}
  1703  				return svc
  1704  			},
  1705  			ConverterFn: func() *automock.APIConverter {
  1706  				conv := &automock.APIConverter{}
  1707  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
  1708  				return conv
  1709  			},
  1710  			AppServiceFn: func() *automock.ApplicationService {
  1711  				svc := &automock.ApplicationService{}
  1712  				return svc
  1713  			},
  1714  			ExpectedErr: testErr,
  1715  		},
  1716  		{
  1717  			Name:            "Error when updating the Application's baseURL fails",
  1718  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1719  			ServiceFn: func() *automock.APIService {
  1720  				svc := &automock.APIService{}
  1721  				svc.On("CreateInApplication", txtest.CtxWithDBMatcher(), appID, *modelAPIInput, specInput).Return(id, nil).Once()
  1722  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
  1723  				return svc
  1724  			},
  1725  			SpecServiceFn: func() *automock.SpecService {
  1726  				svc := &automock.SpecService{}
  1727  				return svc
  1728  			},
  1729  			ConverterFn: func() *automock.APIConverter {
  1730  				conv := &automock.APIConverter{}
  1731  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
  1732  				return conv
  1733  			},
  1734  			AppServiceFn: func() *automock.ApplicationService {
  1735  				svc := &automock.ApplicationService{}
  1736  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(testErr).Once()
  1737  
  1738  				return svc
  1739  			},
  1740  			ExpectedErr: testErr,
  1741  		},
  1742  		{
  1743  			Name:            "Error when getting the spec fails",
  1744  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1745  			ServiceFn: func() *automock.APIService {
  1746  				svc := &automock.APIService{}
  1747  				svc.On("CreateInApplication", txtest.CtxWithDBMatcher(), appID, *modelAPIInput, specInput).Return(id, nil).Once()
  1748  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
  1749  				return svc
  1750  			},
  1751  			SpecServiceFn: func() *automock.SpecService {
  1752  				svc := &automock.SpecService{}
  1753  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(nil, testErr).Once()
  1754  				return svc
  1755  			},
  1756  			ConverterFn: func() *automock.APIConverter {
  1757  				conv := &automock.APIConverter{}
  1758  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
  1759  				return conv
  1760  			},
  1761  			AppServiceFn: func() *automock.ApplicationService {
  1762  				svc := &automock.ApplicationService{}
  1763  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(nil).Once()
  1764  
  1765  				return svc
  1766  			},
  1767  			ExpectedErr: testErr,
  1768  		},
  1769  		{
  1770  			Name:            "Fail when converting to graphQL fails",
  1771  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1772  			ServiceFn: func() *automock.APIService {
  1773  				svc := &automock.APIService{}
  1774  				svc.On("CreateInApplication", txtest.CtxWithDBMatcher(), appID, *modelAPIInput, specInput).Return(id, nil).Once()
  1775  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
  1776  				return svc
  1777  			},
  1778  			SpecServiceFn: func() *automock.SpecService {
  1779  				svc := &automock.SpecService{}
  1780  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
  1781  				return svc
  1782  			},
  1783  			ConverterFn: func() *automock.APIConverter {
  1784  				conv := &automock.APIConverter{}
  1785  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
  1786  				conv.On("ToGraphQL", &modelAPI, &spec, bundleRef).Return(nil, testErr).Once()
  1787  				return conv
  1788  			},
  1789  			AppServiceFn: func() *automock.ApplicationService {
  1790  				svc := &automock.ApplicationService{}
  1791  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(nil).Once()
  1792  
  1793  				return svc
  1794  			},
  1795  			ExpectedErr: testErr,
  1796  		},
  1797  		{
  1798  			Name:            "Error when committing fails",
  1799  			TransactionerFn: txGen.ThatFailsOnCommit,
  1800  			ServiceFn: func() *automock.APIService {
  1801  				svc := &automock.APIService{}
  1802  				svc.On("CreateInApplication", txtest.CtxWithDBMatcher(), appID, *modelAPIInput, specInput).Return(id, nil).Once()
  1803  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPI, nil).Once()
  1804  				return svc
  1805  			},
  1806  			SpecServiceFn: func() *automock.SpecService {
  1807  				svc := &automock.SpecService{}
  1808  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, gqlAPI.ID).Return(&spec, nil).Once()
  1809  				return svc
  1810  			},
  1811  			ConverterFn: func() *automock.APIConverter {
  1812  				conv := &automock.APIConverter{}
  1813  				conv.On("InputFromGraphQL", gqlAPIInput).Return(modelAPIInput, specInput, nil).Once()
  1814  				conv.On("ToGraphQL", &modelAPI, &spec, bundleRef).Return(gqlAPI, nil).Once()
  1815  				return conv
  1816  			},
  1817  			AppServiceFn: func() *automock.ApplicationService {
  1818  				svc := &automock.ApplicationService{}
  1819  				svc.On("UpdateBaseURL", txtest.CtxWithDBMatcher(), appID, targetURL).Return(nil).Once()
  1820  
  1821  				return svc
  1822  			},
  1823  			ExpectedErr: testErr,
  1824  		},
  1825  	}
  1826  
  1827  	for _, testCase := range testCases {
  1828  		t.Run(testCase.Name, func(t *testing.T) {
  1829  			// GIVEN
  1830  			persist, transact := testCase.TransactionerFn()
  1831  			svc := testCase.ServiceFn()
  1832  			converter := testCase.ConverterFn()
  1833  			specSvc := testCase.SpecServiceFn()
  1834  			appSvc := testCase.AppServiceFn()
  1835  			defer mock.AssertExpectationsForObjects(t, persist, transact, svc, specSvc, converter, appSvc)
  1836  
  1837  			resolver := api.NewResolver(transact, svc, nil, nil, nil, converter, nil, specSvc, nil, appSvc)
  1838  
  1839  			// WHEN
  1840  			result, err := resolver.AddAPIDefinitionToApplication(context.TODO(), appID, *gqlAPIInput)
  1841  
  1842  			// THEN
  1843  			assert.Equal(t, testCase.ExpectedAPI, result)
  1844  			if testCase.ExpectedErr != nil {
  1845  				require.Error(t, err)
  1846  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1847  			} else {
  1848  				require.Nil(t, err)
  1849  			}
  1850  		})
  1851  	}
  1852  }
  1853  
  1854  func TestResolver_UpdateAPIDefinitionForApplication(t *testing.T) {
  1855  	// GIVEN
  1856  	testErr := errors.New("Test error")
  1857  
  1858  	id := "bar"
  1859  	gqlAPIDefinitionInput := fixGQLAPIDefinitionInput(id, "foo", "bar")
  1860  	modelAPIDefinitionInput, modelSpecInput := fixModelAPIDefinitionInput(id, "foo", "bar")
  1861  	gqlAPIDefinition := fixFullGQLAPIDefinition("test")
  1862  	modelAPIDefinition, modelSpec, _ := fixFullAPIDefinitionModel(apiDefID, "test")
  1863  	var bundleRef *model.BundleReference
  1864  
  1865  	txGen := txtest.NewTransactionContextGenerator(testErr)
  1866  
  1867  	testCases := []struct {
  1868  		Name                  string
  1869  		TransactionerFn       func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  1870  		ServiceFn             func() *automock.APIService
  1871  		ConverterFn           func() *automock.APIConverter
  1872  		SpecServiceFn         func() *automock.SpecService
  1873  		InputAPI              graphql.APIDefinitionInput
  1874  		ExpectedAPIDefinition *graphql.APIDefinition
  1875  		ExpectedErr           error
  1876  	}{
  1877  		{
  1878  			Name:            "Success",
  1879  			TransactionerFn: txGen.ThatSucceeds,
  1880  			ServiceFn: func() *automock.APIService {
  1881  				svc := &automock.APIService{}
  1882  				svc.On("UpdateForApplication", txtest.CtxWithDBMatcher(), id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
  1883  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
  1884  				return svc
  1885  			},
  1886  			ConverterFn: func() *automock.APIConverter {
  1887  				conv := &automock.APIConverter{}
  1888  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
  1889  				conv.On("ToGraphQL", &modelAPIDefinition, &modelSpec, bundleRef).Return(gqlAPIDefinition, nil).Once()
  1890  				return conv
  1891  			},
  1892  			SpecServiceFn: func() *automock.SpecService {
  1893  				svc := &automock.SpecService{}
  1894  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&modelSpec, nil).Once()
  1895  				return svc
  1896  			},
  1897  			InputAPI:              *gqlAPIDefinitionInput,
  1898  			ExpectedAPIDefinition: gqlAPIDefinition,
  1899  			ExpectedErr:           nil,
  1900  		},
  1901  		{
  1902  			Name:            "Error when starting transaction fails",
  1903  			TransactionerFn: txGen.ThatFailsOnBegin,
  1904  			ServiceFn: func() *automock.APIService {
  1905  				svc := &automock.APIService{}
  1906  				return svc
  1907  			},
  1908  			ConverterFn: func() *automock.APIConverter {
  1909  				conv := &automock.APIConverter{}
  1910  				return conv
  1911  			},
  1912  			SpecServiceFn: func() *automock.SpecService {
  1913  				svc := &automock.SpecService{}
  1914  				return svc
  1915  			},
  1916  			InputAPI:    *gqlAPIDefinitionInput,
  1917  			ExpectedErr: testErr,
  1918  		},
  1919  		{
  1920  			Name:            "Error when converting input from graphQL fails",
  1921  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1922  			ServiceFn: func() *automock.APIService {
  1923  				svc := &automock.APIService{}
  1924  				return svc
  1925  			},
  1926  			ConverterFn: func() *automock.APIConverter {
  1927  				conv := &automock.APIConverter{}
  1928  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(nil, nil, testErr).Once()
  1929  				return conv
  1930  			},
  1931  			SpecServiceFn: func() *automock.SpecService {
  1932  				svc := &automock.SpecService{}
  1933  				return svc
  1934  			},
  1935  			InputAPI:    *gqlAPIDefinitionInput,
  1936  			ExpectedErr: testErr,
  1937  		},
  1938  		{
  1939  			Name:            "Error when  updating API fails",
  1940  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1941  			ServiceFn: func() *automock.APIService {
  1942  				svc := &automock.APIService{}
  1943  				svc.On("UpdateForApplication", txtest.CtxWithDBMatcher(), id, *modelAPIDefinitionInput, modelSpecInput).Return(testErr).Once()
  1944  				return svc
  1945  			},
  1946  			ConverterFn: func() *automock.APIConverter {
  1947  				conv := &automock.APIConverter{}
  1948  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
  1949  				return conv
  1950  			},
  1951  			SpecServiceFn: func() *automock.SpecService {
  1952  				svc := &automock.SpecService{}
  1953  				return svc
  1954  			},
  1955  			InputAPI:    *gqlAPIDefinitionInput,
  1956  			ExpectedErr: testErr,
  1957  		},
  1958  		{
  1959  			Name:            "Error when getting API fails",
  1960  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1961  			ServiceFn: func() *automock.APIService {
  1962  				svc := &automock.APIService{}
  1963  				svc.On("UpdateForApplication", txtest.CtxWithDBMatcher(), id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
  1964  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(nil, testErr).Once()
  1965  				return svc
  1966  			},
  1967  			ConverterFn: func() *automock.APIConverter {
  1968  				conv := &automock.APIConverter{}
  1969  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
  1970  				return conv
  1971  			},
  1972  			SpecServiceFn: func() *automock.SpecService {
  1973  				svc := &automock.SpecService{}
  1974  				return svc
  1975  			},
  1976  			InputAPI:    *gqlAPIDefinitionInput,
  1977  			ExpectedErr: testErr,
  1978  		},
  1979  		{
  1980  			Name:            "Error when getting Spec fails",
  1981  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1982  			ServiceFn: func() *automock.APIService {
  1983  				svc := &automock.APIService{}
  1984  				svc.On("UpdateForApplication", txtest.CtxWithDBMatcher(), id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
  1985  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
  1986  				return svc
  1987  			},
  1988  			ConverterFn: func() *automock.APIConverter {
  1989  				conv := &automock.APIConverter{}
  1990  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
  1991  				return conv
  1992  			},
  1993  			SpecServiceFn: func() *automock.SpecService {
  1994  				svc := &automock.SpecService{}
  1995  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(nil, testErr).Once()
  1996  				return svc
  1997  			},
  1998  			InputAPI:    *gqlAPIDefinitionInput,
  1999  			ExpectedErr: testErr,
  2000  		},
  2001  		{
  2002  			Name:            "Error when converting to graphQL fails",
  2003  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  2004  			ServiceFn: func() *automock.APIService {
  2005  				svc := &automock.APIService{}
  2006  				svc.On("UpdateForApplication", txtest.CtxWithDBMatcher(), id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
  2007  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
  2008  				return svc
  2009  			},
  2010  			ConverterFn: func() *automock.APIConverter {
  2011  				conv := &automock.APIConverter{}
  2012  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
  2013  				conv.On("ToGraphQL", &modelAPIDefinition, &modelSpec, bundleRef).Return(nil, testErr).Once()
  2014  				return conv
  2015  			},
  2016  			SpecServiceFn: func() *automock.SpecService {
  2017  				svc := &automock.SpecService{}
  2018  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&modelSpec, nil).Once()
  2019  				return svc
  2020  			},
  2021  			InputAPI:    *gqlAPIDefinitionInput,
  2022  			ExpectedErr: testErr,
  2023  		},
  2024  		{
  2025  			Name:            "Error when committing transaction fails",
  2026  			TransactionerFn: txGen.ThatFailsOnCommit,
  2027  			ServiceFn: func() *automock.APIService {
  2028  				svc := &automock.APIService{}
  2029  				svc.On("UpdateForApplication", txtest.CtxWithDBMatcher(), id, *modelAPIDefinitionInput, modelSpecInput).Return(nil).Once()
  2030  				svc.On("Get", txtest.CtxWithDBMatcher(), id).Return(&modelAPIDefinition, nil).Once()
  2031  				return svc
  2032  			},
  2033  			ConverterFn: func() *automock.APIConverter {
  2034  				conv := &automock.APIConverter{}
  2035  				conv.On("InputFromGraphQL", gqlAPIDefinitionInput).Return(modelAPIDefinitionInput, modelSpecInput, nil).Once()
  2036  				conv.On("ToGraphQL", &modelAPIDefinition, &modelSpec, bundleRef).Return(gqlAPIDefinition, nil).Once()
  2037  				return conv
  2038  			},
  2039  			SpecServiceFn: func() *automock.SpecService {
  2040  				svc := &automock.SpecService{}
  2041  				svc.On("GetByReferenceObjectID", txtest.CtxWithDBMatcher(), resource.Application, model.APISpecReference, modelAPIDefinition.ID).Return(&modelSpec, nil).Once()
  2042  				return svc
  2043  			},
  2044  			InputAPI:    *gqlAPIDefinitionInput,
  2045  			ExpectedErr: testErr,
  2046  		},
  2047  	}
  2048  
  2049  	for _, testCase := range testCases {
  2050  		t.Run(testCase.Name, func(t *testing.T) {
  2051  			// GIVEN
  2052  			persist, transact := testCase.TransactionerFn()
  2053  			svc := testCase.ServiceFn()
  2054  			converter := testCase.ConverterFn()
  2055  			specService := testCase.SpecServiceFn()
  2056  			defer mock.AssertExpectationsForObjects(t, persist, transact, svc, specService, converter)
  2057  
  2058  			resolver := api.NewResolver(transact, svc, nil, nil, nil, converter, nil, specService, nil, nil)
  2059  
  2060  			// WHEN
  2061  			result, err := resolver.UpdateAPIDefinitionForApplication(context.TODO(), id, *gqlAPIDefinitionInput)
  2062  
  2063  			// THEN
  2064  			if testCase.ExpectedErr != nil {
  2065  				require.Error(t, err)
  2066  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  2067  			} else {
  2068  				require.Nil(t, err)
  2069  				assert.Equal(t, testCase.ExpectedAPIDefinition, result)
  2070  			}
  2071  		})
  2072  	}
  2073  }