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

     1  package application_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/internal/domain/scenarioassignment"
    10  	"github.com/kyma-incubator/compass/components/director/pkg/consumer"
    11  	"github.com/kyma-incubator/compass/components/hydrator/pkg/oathkeeper"
    12  
    13  	pkgmodel "github.com/kyma-incubator/compass/components/director/pkg/model"
    14  
    15  	dataloader "github.com/kyma-incubator/compass/components/director/internal/dataloaders"
    16  	"github.com/kyma-incubator/compass/components/director/internal/tokens"
    17  
    18  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
    19  
    20  	"github.com/kyma-incubator/compass/components/director/pkg/str"
    21  
    22  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
    23  
    24  	"github.com/kyma-incubator/compass/components/director/internal/domain/tenant"
    25  	"github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest"
    26  
    27  	"github.com/google/uuid"
    28  	"github.com/kyma-incubator/compass/components/director/internal/domain/application"
    29  	"github.com/kyma-incubator/compass/components/director/internal/domain/application/automock"
    30  	"github.com/kyma-incubator/compass/components/director/internal/labelfilter"
    31  	"github.com/kyma-incubator/compass/components/director/internal/model"
    32  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    33  	persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock"
    34  	"github.com/pkg/errors"
    35  	"github.com/stretchr/testify/assert"
    36  	"github.com/stretchr/testify/mock"
    37  	"github.com/stretchr/testify/require"
    38  )
    39  
    40  var contextParam = txtest.CtxWithDBMatcher()
    41  
    42  func TestResolver_RegisterApplication(t *testing.T) {
    43  	// GIVEN
    44  	modelApplication := fixModelApplication("foo", "tenant-foo", "Foo", "Lorem ipsum")
    45  	gqlApplication := fixGQLApplication("foo", "Foo", "Lorem ipsum")
    46  	testErr := errors.New("Test error")
    47  
    48  	desc := "Lorem ipsum"
    49  	gqlInput := graphql.ApplicationRegisterInput{
    50  		Name:        "Foo",
    51  		Description: &desc,
    52  	}
    53  	modelInput := model.ApplicationRegisterInput{
    54  		Name:        "Foo",
    55  		Description: &desc,
    56  	}
    57  
    58  	modelInputWithLabel := model.ApplicationRegisterInput{
    59  		Name:        modelInput.Name,
    60  		Description: modelInput.Description,
    61  		Labels:      map[string]interface{}{"managed": "false"},
    62  	}
    63  	txGen := txtest.NewTransactionContextGenerator(testErr)
    64  
    65  	testCases := []struct {
    66  		Name                string
    67  		TransactionerFn     func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
    68  		ServiceFn           func() *automock.ApplicationService
    69  		ConverterFn         func() *automock.ApplicationConverter
    70  		Input               graphql.ApplicationRegisterInput
    71  		ExpectedApplication *graphql.Application
    72  		ExpectedErr         error
    73  	}{
    74  		{
    75  			Name:            "Success",
    76  			TransactionerFn: txGen.ThatDoesntStartTransaction,
    77  			ServiceFn: func() *automock.ApplicationService {
    78  				svc := &automock.ApplicationService{}
    79  				svc.On("Get", context.TODO(), "foo").Return(modelApplication, nil).Once()
    80  				svc.On("Create", context.TODO(), modelInputWithLabel).Return("foo", nil).Once()
    81  				return svc
    82  			},
    83  			ConverterFn: func() *automock.ApplicationConverter {
    84  				conv := &automock.ApplicationConverter{}
    85  				conv.On("CreateInputFromGraphQL", mock.Anything, gqlInput).Return(modelInput, nil).Once()
    86  				conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once()
    87  				return conv
    88  			},
    89  			Input:               gqlInput,
    90  			ExpectedApplication: gqlApplication,
    91  			ExpectedErr:         nil,
    92  		},
    93  		{
    94  			Name:            "Returns error when application creation failed",
    95  			TransactionerFn: txGen.ThatDoesntStartTransaction,
    96  			ServiceFn: func() *automock.ApplicationService {
    97  				svc := &automock.ApplicationService{}
    98  				svc.On("Create", context.TODO(), modelInputWithLabel).Return("", testErr).Once()
    99  				return svc
   100  			},
   101  			ConverterFn: func() *automock.ApplicationConverter {
   102  				conv := &automock.ApplicationConverter{}
   103  				conv.On("CreateInputFromGraphQL", mock.Anything, gqlInput).Return(modelInput, nil).Once()
   104  				return conv
   105  			},
   106  			Input:               gqlInput,
   107  			ExpectedApplication: nil,
   108  			ExpectedErr:         testErr,
   109  		},
   110  		{
   111  			Name:            "Returns error when application fetch failed",
   112  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   113  			ServiceFn: func() *automock.ApplicationService {
   114  				svc := &automock.ApplicationService{}
   115  				svc.On("Create", context.TODO(), modelInputWithLabel).Return("foo", nil).Once()
   116  				svc.On("Get", context.TODO(), "foo").Return(nil, testErr).Once()
   117  				return svc
   118  			},
   119  			ConverterFn: func() *automock.ApplicationConverter {
   120  				conv := &automock.ApplicationConverter{}
   121  				conv.On("CreateInputFromGraphQL", mock.Anything, gqlInput).Return(modelInput, nil).Once()
   122  				return conv
   123  			},
   124  			Input:               gqlInput,
   125  			ExpectedApplication: nil,
   126  			ExpectedErr:         testErr,
   127  		},
   128  	}
   129  
   130  	for _, testCase := range testCases {
   131  		t.Run(testCase.Name, func(t *testing.T) {
   132  			persistTx, transact := testCase.TransactionerFn()
   133  			svc := testCase.ServiceFn()
   134  			converter := testCase.ConverterFn()
   135  			resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
   136  			resolver.SetConverter(converter)
   137  
   138  			// WHEN
   139  			result, err := resolver.RegisterApplication(context.TODO(), testCase.Input)
   140  
   141  			// then
   142  			assert.Equal(t, testCase.ExpectedApplication, result)
   143  			assert.Equal(t, testCase.ExpectedErr, err)
   144  
   145  			svc.AssertExpectations(t)
   146  			converter.AssertExpectations(t)
   147  			transact.AssertExpectations(t)
   148  			persistTx.AssertExpectations(t)
   149  		})
   150  	}
   151  }
   152  
   153  func TestResolver_UpdateApplication(t *testing.T) {
   154  	// GIVEN
   155  	modelApplication := fixModelApplication("foo", "tenant-foo", "Foo", "Lorem ipsum")
   156  	gqlApplication := fixGQLApplication("foo", "Foo", "Lorem ipsum")
   157  	testErr := errors.New("Test error")
   158  
   159  	desc := "Lorem ipsum"
   160  	gqlInput := graphql.ApplicationUpdateInput{
   161  		Description: &desc,
   162  	}
   163  	modelInput := model.ApplicationUpdateInput{
   164  		Description: &desc,
   165  	}
   166  	applicationID := "foo"
   167  
   168  	txGen := txtest.NewTransactionContextGenerator(testErr)
   169  
   170  	testCases := []struct {
   171  		Name                string
   172  		TransactionerFn     func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   173  		ServiceFn           func() *automock.ApplicationService
   174  		ConverterFn         func() *automock.ApplicationConverter
   175  		ApplicationID       string
   176  		Input               graphql.ApplicationUpdateInput
   177  		ExpectedApplication *graphql.Application
   178  		ExpectedErr         error
   179  	}{
   180  		{
   181  			Name:            "Success",
   182  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   183  			ServiceFn: func() *automock.ApplicationService {
   184  				svc := &automock.ApplicationService{}
   185  				svc.On("Get", context.TODO(), "foo").Return(modelApplication, nil).Once()
   186  				svc.On("Update", context.TODO(), applicationID, modelInput).Return(nil).Once()
   187  				return svc
   188  			},
   189  			ConverterFn: func() *automock.ApplicationConverter {
   190  				conv := &automock.ApplicationConverter{}
   191  				conv.On("UpdateInputFromGraphQL", gqlInput).Return(modelInput).Once()
   192  				conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once()
   193  				return conv
   194  			},
   195  			ApplicationID:       applicationID,
   196  			Input:               gqlInput,
   197  			ExpectedApplication: gqlApplication,
   198  			ExpectedErr:         nil,
   199  		},
   200  		{
   201  			Name:            "Returns error when application update failed",
   202  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   203  			ServiceFn: func() *automock.ApplicationService {
   204  				svc := &automock.ApplicationService{}
   205  				svc.On("Update", context.TODO(), applicationID, modelInput).Return(testErr).Once()
   206  				return svc
   207  			},
   208  			ConverterFn: func() *automock.ApplicationConverter {
   209  				conv := &automock.ApplicationConverter{}
   210  				conv.On("UpdateInputFromGraphQL", gqlInput).Return(modelInput).Once()
   211  				return conv
   212  			},
   213  			ApplicationID:       applicationID,
   214  			Input:               gqlInput,
   215  			ExpectedApplication: nil,
   216  			ExpectedErr:         testErr,
   217  		},
   218  		{
   219  			Name:            "Returns error when application retrieval failed",
   220  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   221  			ServiceFn: func() *automock.ApplicationService {
   222  				svc := &automock.ApplicationService{}
   223  				svc.On("Update", context.TODO(), applicationID, modelInput).Return(nil).Once()
   224  				svc.On("Get", context.TODO(), "foo").Return(nil, testErr).Once()
   225  				return svc
   226  			},
   227  			ConverterFn: func() *automock.ApplicationConverter {
   228  				conv := &automock.ApplicationConverter{}
   229  				conv.On("UpdateInputFromGraphQL", gqlInput).Return(modelInput).Once()
   230  				return conv
   231  			},
   232  			ApplicationID:       applicationID,
   233  			Input:               gqlInput,
   234  			ExpectedApplication: nil,
   235  			ExpectedErr:         testErr,
   236  		},
   237  	}
   238  
   239  	for _, testCase := range testCases {
   240  		t.Run(testCase.Name, func(t *testing.T) {
   241  			persistTx, transact := testCase.TransactionerFn()
   242  			svc := testCase.ServiceFn()
   243  			converter := testCase.ConverterFn()
   244  
   245  			resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
   246  			resolver.SetConverter(converter)
   247  
   248  			// WHEN
   249  			result, err := resolver.UpdateApplication(context.TODO(), testCase.ApplicationID, testCase.Input)
   250  
   251  			// then
   252  			assert.Equal(t, testCase.ExpectedApplication, result)
   253  			assert.Equal(t, testCase.ExpectedErr, err)
   254  
   255  			svc.AssertExpectations(t)
   256  			converter.AssertExpectations(t)
   257  			transact.AssertExpectations(t)
   258  			persistTx.AssertExpectations(t)
   259  		})
   260  	}
   261  }
   262  
   263  func TestResolver_UnregisterApplication(t *testing.T) {
   264  	// GIVEN
   265  	appID := uuid.New()
   266  	modelApplication := fixModelApplication(appID.String(), "tenant-foo", "Foo", "Bar")
   267  	gqlApplication := fixGQLApplication(appID.String(), "Foo", "Bar")
   268  	testErr := errors.New("Test error")
   269  	testAuths := fixOAuths()
   270  	txGen := txtest.NewTransactionContextGenerator(testErr)
   271  
   272  	testCases := []struct {
   273  		Name                string
   274  		TransactionerFn     func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   275  		ServiceFn           func() *automock.ApplicationService
   276  		ConverterFn         func() *automock.ApplicationConverter
   277  		EventingSvcFn       func() *automock.EventingService
   278  		SysAuthServiceFn    func() *automock.SystemAuthService
   279  		OAuth20ServiceFn    func() *automock.OAuth20Service
   280  		InputID             string
   281  		ExpectedApplication *graphql.Application
   282  		ExpectedErr         error
   283  	}{
   284  		{
   285  			Name:            "Success",
   286  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   287  			ServiceFn: func() *automock.ApplicationService {
   288  				svc := &automock.ApplicationService{}
   289  				svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once()
   290  				svc.On("Delete", context.TODO(), appID.String()).Return(nil).Once()
   291  				return svc
   292  			},
   293  			ConverterFn: func() *automock.ApplicationConverter {
   294  				conv := &automock.ApplicationConverter{}
   295  				conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once()
   296  				return conv
   297  			},
   298  			EventingSvcFn: func() *automock.EventingService {
   299  				svc := &automock.EventingService{}
   300  				svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, nil).Once()
   301  				return svc
   302  			},
   303  			SysAuthServiceFn: func() *automock.SystemAuthService {
   304  				svc := &automock.SystemAuthService{}
   305  				svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil)
   306  				return svc
   307  			},
   308  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   309  				svc := &automock.OAuth20Service{}
   310  				svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(nil)
   311  				return svc
   312  			},
   313  			InputID:             appID.String(),
   314  			ExpectedApplication: gqlApplication,
   315  			ExpectedErr:         nil,
   316  		},
   317  		{
   318  			Name:            "Returns error when application deletion failed",
   319  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   320  			ServiceFn: func() *automock.ApplicationService {
   321  				svc := &automock.ApplicationService{}
   322  				svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once()
   323  				svc.On("Delete", context.TODO(), appID.String()).Return(testErr).Once()
   324  				return svc
   325  			},
   326  			ConverterFn: func() *automock.ApplicationConverter {
   327  				conv := &automock.ApplicationConverter{}
   328  				return conv
   329  			},
   330  			EventingSvcFn: func() *automock.EventingService {
   331  				svc := &automock.EventingService{}
   332  				svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, nil).Once()
   333  				return svc
   334  			},
   335  			SysAuthServiceFn: func() *automock.SystemAuthService {
   336  				svc := &automock.SystemAuthService{}
   337  				svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil)
   338  				return svc
   339  			},
   340  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   341  				svc := &automock.OAuth20Service{}
   342  				svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(nil)
   343  
   344  				return svc
   345  			},
   346  			InputID:             appID.String(),
   347  			ExpectedApplication: nil,
   348  			ExpectedErr:         testErr,
   349  		},
   350  		{
   351  			Name:            "Returns error when application retrieval failed",
   352  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   353  			ServiceFn: func() *automock.ApplicationService {
   354  				svc := &automock.ApplicationService{}
   355  				svc.On("Get", context.TODO(), appID.String()).Return(nil, testErr).Once()
   356  				return svc
   357  			},
   358  			ConverterFn: func() *automock.ApplicationConverter {
   359  				conv := &automock.ApplicationConverter{}
   360  				return conv
   361  			},
   362  			EventingSvcFn: func() *automock.EventingService {
   363  				svc := &automock.EventingService{}
   364  				return svc
   365  			},
   366  			SysAuthServiceFn: func() *automock.SystemAuthService {
   367  				svc := &automock.SystemAuthService{}
   368  				return svc
   369  			},
   370  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   371  				svc := &automock.OAuth20Service{}
   372  				return svc
   373  			},
   374  			InputID:             appID.String(),
   375  			ExpectedApplication: nil,
   376  			ExpectedErr:         testErr,
   377  		},
   378  		{
   379  			Name:            "Return error when listing all auths failed",
   380  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   381  			ServiceFn: func() *automock.ApplicationService {
   382  				svc := &automock.ApplicationService{}
   383  				svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once()
   384  				return svc
   385  			},
   386  			ConverterFn: func() *automock.ApplicationConverter {
   387  				conv := &automock.ApplicationConverter{}
   388  				return conv
   389  			},
   390  			EventingSvcFn: func() *automock.EventingService {
   391  				svc := &automock.EventingService{}
   392  				svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, nil).Once()
   393  				return svc
   394  			},
   395  			SysAuthServiceFn: func() *automock.SystemAuthService {
   396  				svc := &automock.SystemAuthService{}
   397  				svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(nil, testErr)
   398  				return svc
   399  			},
   400  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   401  				svc := &automock.OAuth20Service{}
   402  				return svc
   403  			},
   404  			InputID:             appID.String(),
   405  			ExpectedApplication: nil,
   406  			ExpectedErr:         testErr,
   407  		},
   408  		{
   409  			Name:            "Return error when removing oauth from hydra",
   410  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   411  			ServiceFn: func() *automock.ApplicationService {
   412  				svc := &automock.ApplicationService{}
   413  				svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once()
   414  				return svc
   415  			},
   416  			ConverterFn: func() *automock.ApplicationConverter {
   417  				conv := &automock.ApplicationConverter{}
   418  				return conv
   419  			},
   420  			EventingSvcFn: func() *automock.EventingService {
   421  				svc := &automock.EventingService{}
   422  				svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, nil).Once()
   423  				return svc
   424  			},
   425  			SysAuthServiceFn: func() *automock.SystemAuthService {
   426  				svc := &automock.SystemAuthService{}
   427  				svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil)
   428  				return svc
   429  			},
   430  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   431  				svc := &automock.OAuth20Service{}
   432  				svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(testErr)
   433  				return svc
   434  			},
   435  			InputID:             appID.String(),
   436  			ExpectedApplication: nil,
   437  			ExpectedErr:         testErr,
   438  		}, {
   439  			Name:            "Returns error when removing default eventing labels",
   440  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   441  			ServiceFn: func() *automock.ApplicationService {
   442  				svc := &automock.ApplicationService{}
   443  				svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once()
   444  				return svc
   445  			},
   446  			ConverterFn: func() *automock.ApplicationConverter {
   447  				conv := &automock.ApplicationConverter{}
   448  				return conv
   449  			},
   450  			EventingSvcFn: func() *automock.EventingService {
   451  				svc := &automock.EventingService{}
   452  				svc.On("CleanupAfterUnregisteringApplication", context.TODO(), appID).Return(nil, testErr).Once()
   453  				return svc
   454  			},
   455  			SysAuthServiceFn: func() *automock.SystemAuthService {
   456  				svc := &automock.SystemAuthService{}
   457  				return svc
   458  			},
   459  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   460  				svc := &automock.OAuth20Service{}
   461  				return svc
   462  			},
   463  			InputID:             appID.String(),
   464  			ExpectedApplication: nil,
   465  			ExpectedErr:         testErr,
   466  		},
   467  	}
   468  
   469  	for _, testCase := range testCases {
   470  		t.Run(testCase.Name, func(t *testing.T) {
   471  			svc := testCase.ServiceFn()
   472  			converter := testCase.ConverterFn()
   473  			eventingSvc := testCase.EventingSvcFn()
   474  			persistTx, transact := testCase.TransactionerFn()
   475  			sysAuthSvc := testCase.SysAuthServiceFn()
   476  			oAuth20Svc := testCase.OAuth20ServiceFn()
   477  			resolver := application.NewResolver(transact, svc, nil, oAuth20Svc, sysAuthSvc, nil, nil, nil, eventingSvc, nil, nil, nil, nil, nil, nil, "", "")
   478  			resolver.SetConverter(converter)
   479  
   480  			// WHEN
   481  			result, err := resolver.UnregisterApplication(context.TODO(), testCase.InputID)
   482  
   483  			// then
   484  			assert.Equal(t, testCase.ExpectedApplication, result)
   485  			if testCase.ExpectedErr != nil {
   486  				assert.EqualError(t, testCase.ExpectedErr, err.Error())
   487  			} else {
   488  				assert.NoError(t, err)
   489  			}
   490  
   491  			mock.AssertExpectationsForObjects(t, svc, converter, persistTx, transact, sysAuthSvc, oAuth20Svc, eventingSvc)
   492  		})
   493  	}
   494  }
   495  
   496  func TestResolver_UnpairApplication(t *testing.T) {
   497  	// GIVEN
   498  	appID := uuid.New()
   499  	modelApplication := fixModelApplication(appID.String(), "tenant-foo", "Foo", "Bar")
   500  	gqlApplication := fixGQLApplication(appID.String(), "Foo", "Bar")
   501  	testErr := errors.New("Test error")
   502  	testAuths := fixOAuths()
   503  	txGen := txtest.NewTransactionContextGenerator(testErr)
   504  
   505  	testCases := []struct {
   506  		Name                string
   507  		TransactionerFn     func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   508  		ServiceFn           func() *automock.ApplicationService
   509  		ConverterFn         func() *automock.ApplicationConverter
   510  		EventingSvcFn       func() *automock.EventingService
   511  		SysAuthServiceFn    func() *automock.SystemAuthService
   512  		OAuth20ServiceFn    func() *automock.OAuth20Service
   513  		InputID             string
   514  		ExpectedApplication *graphql.Application
   515  		ExpectedErr         error
   516  	}{
   517  		{
   518  			Name:            "Success",
   519  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   520  			ServiceFn: func() *automock.ApplicationService {
   521  				svc := &automock.ApplicationService{}
   522  				svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once()
   523  				svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once()
   524  				return svc
   525  			},
   526  			ConverterFn: func() *automock.ApplicationConverter {
   527  				conv := &automock.ApplicationConverter{}
   528  				conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once()
   529  				return conv
   530  			},
   531  			SysAuthServiceFn: func() *automock.SystemAuthService {
   532  				svc := &automock.SystemAuthService{}
   533  				svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil).Once()
   534  				svc.On("DeleteMultipleByIDForObject", context.TODO(), testAuths).Return(nil).Once()
   535  				return svc
   536  			},
   537  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   538  				svc := &automock.OAuth20Service{}
   539  				svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(nil).Once()
   540  				return svc
   541  			},
   542  			InputID:             appID.String(),
   543  			ExpectedApplication: gqlApplication,
   544  			ExpectedErr:         nil,
   545  		},
   546  		{
   547  			Name:            "Returns error when application unpairing failed",
   548  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   549  			ServiceFn: func() *automock.ApplicationService {
   550  				svc := &automock.ApplicationService{}
   551  				svc.AssertNotCalled(t, "Get")
   552  				svc.On("Unpair", context.TODO(), appID.String()).Return(testErr).Once()
   553  				return svc
   554  			},
   555  			ConverterFn: func() *automock.ApplicationConverter {
   556  				conv := &automock.ApplicationConverter{}
   557  				return conv
   558  			},
   559  			SysAuthServiceFn: func() *automock.SystemAuthService {
   560  				svc := &automock.SystemAuthService{}
   561  				svc.AssertNotCalled(t, "DeleteMultipleByIDForObject")
   562  				svc.AssertNotCalled(t, "ListForObject")
   563  				return svc
   564  			},
   565  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   566  				svc := &automock.OAuth20Service{}
   567  				svc.AssertNotCalled(t, "DeleteMultipleClientCredentials")
   568  
   569  				return svc
   570  			},
   571  			InputID:             appID.String(),
   572  			ExpectedApplication: nil,
   573  			ExpectedErr:         testErr,
   574  		},
   575  		{
   576  			Name:            "Returns error when application retrieval failed",
   577  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   578  			ServiceFn: func() *automock.ApplicationService {
   579  				svc := &automock.ApplicationService{}
   580  				svc.On("Get", context.TODO(), appID.String()).Return(nil, testErr).Once()
   581  				svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once()
   582  				return svc
   583  			},
   584  			ConverterFn: func() *automock.ApplicationConverter {
   585  				conv := &automock.ApplicationConverter{}
   586  				return conv
   587  			},
   588  			SysAuthServiceFn: func() *automock.SystemAuthService {
   589  				svc := &automock.SystemAuthService{}
   590  				svc.AssertNotCalled(t, "DeleteMultipleByIDForObject")
   591  				svc.AssertNotCalled(t, "ListForObject")
   592  				return svc
   593  			},
   594  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   595  				svc := &automock.OAuth20Service{}
   596  				svc.AssertNotCalled(t, "DeleteMultipleClientCredentials")
   597  				return svc
   598  			},
   599  			InputID:             appID.String(),
   600  			ExpectedApplication: nil,
   601  			ExpectedErr:         testErr,
   602  		},
   603  		{
   604  			Name:            "Return error when listing all auths failed",
   605  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   606  			ServiceFn: func() *automock.ApplicationService {
   607  				svc := &automock.ApplicationService{}
   608  				svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once()
   609  				svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once()
   610  				return svc
   611  			},
   612  			ConverterFn: func() *automock.ApplicationConverter {
   613  				conv := &automock.ApplicationConverter{}
   614  				conv.AssertNotCalled(t, "ToGraphQL")
   615  				return conv
   616  			},
   617  			SysAuthServiceFn: func() *automock.SystemAuthService {
   618  				svc := &automock.SystemAuthService{}
   619  				svc.AssertNotCalled(t, "DeleteMultipleClientCredentials")
   620  				svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(nil, testErr)
   621  				return svc
   622  			},
   623  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   624  				svc := &automock.OAuth20Service{}
   625  				svc.AssertNotCalled(t, "DeleteMultipleClientCredentials")
   626  				return svc
   627  			},
   628  			InputID:             appID.String(),
   629  			ExpectedApplication: nil,
   630  			ExpectedErr:         testErr,
   631  		},
   632  		{
   633  			Name:            "Return error when removing oauth from hydra",
   634  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   635  			ServiceFn: func() *automock.ApplicationService {
   636  				svc := &automock.ApplicationService{}
   637  				svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once()
   638  				svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once()
   639  
   640  				return svc
   641  			},
   642  			ConverterFn: func() *automock.ApplicationConverter {
   643  				conv := &automock.ApplicationConverter{}
   644  				conv.AssertNotCalled(t, "ToGraphQL")
   645  
   646  				return conv
   647  			},
   648  			SysAuthServiceFn: func() *automock.SystemAuthService {
   649  				svc := &automock.SystemAuthService{}
   650  				svc.On("DeleteMultipleByIDForObject", context.TODO(), testAuths).Return(nil).Once()
   651  				svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil)
   652  				return svc
   653  			},
   654  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   655  				svc := &automock.OAuth20Service{}
   656  				svc.On("DeleteMultipleClientCredentials", context.TODO(), testAuths).Return(testErr)
   657  				return svc
   658  			},
   659  			InputID:             appID.String(),
   660  			ExpectedApplication: nil,
   661  			ExpectedErr:         testErr,
   662  		},
   663  		{
   664  			Name:            "Return error when removing system auths",
   665  			TransactionerFn: txGen.ThatDoesntStartTransaction,
   666  			ServiceFn: func() *automock.ApplicationService {
   667  				svc := &automock.ApplicationService{}
   668  				svc.On("Get", context.TODO(), appID.String()).Return(modelApplication, nil).Once()
   669  				svc.On("Unpair", context.TODO(), appID.String()).Return(nil).Once()
   670  				return svc
   671  			},
   672  			ConverterFn: func() *automock.ApplicationConverter {
   673  				conv := &automock.ApplicationConverter{}
   674  				conv.AssertNotCalled(t, "ToGraphQL")
   675  				return conv
   676  			},
   677  			SysAuthServiceFn: func() *automock.SystemAuthService {
   678  				svc := &automock.SystemAuthService{}
   679  				svc.On("DeleteMultipleByIDForObject", context.TODO(), testAuths).Return(testErr).Once()
   680  				svc.On("ListForObject", context.TODO(), pkgmodel.ApplicationReference, modelApplication.ID).Return(testAuths, nil)
   681  				return svc
   682  			},
   683  			OAuth20ServiceFn: func() *automock.OAuth20Service {
   684  				svc := &automock.OAuth20Service{}
   685  				svc.AssertNotCalled(t, "DeleteMultipleClientCredentials")
   686  				return svc
   687  			},
   688  			InputID:             appID.String(),
   689  			ExpectedApplication: nil,
   690  			ExpectedErr:         testErr,
   691  		},
   692  	}
   693  
   694  	for _, testCase := range testCases {
   695  		t.Run(testCase.Name, func(t *testing.T) {
   696  			svc := testCase.ServiceFn()
   697  			converter := testCase.ConverterFn()
   698  			persistTx, transact := testCase.TransactionerFn()
   699  			sysAuthSvc := testCase.SysAuthServiceFn()
   700  			oAuth20Svc := testCase.OAuth20ServiceFn()
   701  			resolver := application.NewResolver(transact, svc, nil, oAuth20Svc, sysAuthSvc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
   702  			resolver.SetConverter(converter)
   703  
   704  			// WHEN
   705  			result, err := resolver.UnpairApplication(context.TODO(), testCase.InputID)
   706  
   707  			// then
   708  			assert.Equal(t, testCase.ExpectedApplication, result)
   709  			if testCase.ExpectedErr != nil {
   710  				assert.EqualError(t, testCase.ExpectedErr, err.Error())
   711  			} else {
   712  				assert.NoError(t, err)
   713  			}
   714  
   715  			mock.AssertExpectationsForObjects(t, svc, converter, persistTx, transact, sysAuthSvc, oAuth20Svc)
   716  		})
   717  	}
   718  }
   719  
   720  func TestResolver_MergeApplications(t *testing.T) {
   721  	// GIVEN
   722  	srcAppID := "srcID"
   723  	destAppID := "destID"
   724  
   725  	modelApplication := fixModelApplication(destAppID, "tenant-foo", "Foo", "Lorem ipsum")
   726  	gqlApplication := fixGQLApplication(destAppID, "Foo", "Lorem ipsum")
   727  
   728  	testErr := errors.New("Test error")
   729  
   730  	testCases := []struct {
   731  		Name                   string
   732  		PersistenceFn          func() *persistenceautomock.PersistenceTx
   733  		TransactionerFn        func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
   734  		ServiceFn              func() *automock.ApplicationService
   735  		ApplicationConverterFn func() *automock.ApplicationConverter
   736  		ExpectedResult         *graphql.Application
   737  		ExpectedErr            error
   738  	}{
   739  		{
   740  			Name:            "Success",
   741  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
   742  			TransactionerFn: txtest.TransactionerThatSucceeds,
   743  			ApplicationConverterFn: func() *automock.ApplicationConverter {
   744  				conv := &automock.ApplicationConverter{}
   745  				conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once()
   746  
   747  				return conv
   748  			},
   749  			ServiceFn: func() *automock.ApplicationService {
   750  				svc := &automock.ApplicationService{}
   751  				svc.On("Merge", txtest.CtxWithDBMatcher(), destAppID, srcAppID).Return(modelApplication, nil).Once()
   752  
   753  				return svc
   754  			},
   755  			ExpectedResult: gqlApplication,
   756  			ExpectedErr:    nil,
   757  		},
   758  		{
   759  			Name: "Returns error when webhook conversion to graphql fails",
   760  			TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner {
   761  				transact := &persistenceautomock.Transactioner{}
   762  				transact.On("Begin").Return(nil, testErr).Once()
   763  				return transact
   764  			},
   765  			PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit,
   766  			ApplicationConverterFn: func() *automock.ApplicationConverter {
   767  				conv := &automock.ApplicationConverter{}
   768  				conv.AssertNotCalled(t, "ToGraphQL")
   769  
   770  				return conv
   771  			},
   772  			ServiceFn: func() *automock.ApplicationService {
   773  				svc := &automock.ApplicationService{}
   774  				svc.AssertNotCalled(t, "Merge")
   775  
   776  				return svc
   777  			},
   778  			ExpectedResult: nil,
   779  			ExpectedErr:    testErr,
   780  		},
   781  		{
   782  			Name: "Returns error on committing transaction",
   783  			PersistenceFn: func() *persistenceautomock.PersistenceTx {
   784  				persistTx := &persistenceautomock.PersistenceTx{}
   785  				persistTx.On("Commit").Return(testErr).Once()
   786  				return persistTx
   787  			},
   788  			TransactionerFn: txtest.TransactionerThatSucceeds,
   789  			ApplicationConverterFn: func() *automock.ApplicationConverter {
   790  				conv := &automock.ApplicationConverter{}
   791  				conv.AssertNotCalled(t, "ToGraphQL")
   792  
   793  				return conv
   794  			},
   795  			ServiceFn: func() *automock.ApplicationService {
   796  				svc := &automock.ApplicationService{}
   797  				svc.On("Merge", txtest.CtxWithDBMatcher(), destAppID, srcAppID).Return(modelApplication, nil).Once()
   798  
   799  				return svc
   800  			},
   801  			ExpectedErr: testErr,
   802  		},
   803  		{
   804  			Name:          "Returns error then Merge fails",
   805  			PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit,
   806  			ApplicationConverterFn: func() *automock.ApplicationConverter {
   807  				conv := &automock.ApplicationConverter{}
   808  				conv.AssertNotCalled(t, "ToGraphQL")
   809  
   810  				return conv
   811  			},
   812  			ServiceFn: func() *automock.ApplicationService {
   813  				svc := &automock.ApplicationService{}
   814  				svc.On("Merge", txtest.CtxWithDBMatcher(), destAppID, srcAppID).Return(nil, testErr).Once()
   815  
   816  				return svc
   817  			},
   818  			TransactionerFn: txtest.TransactionerThatSucceeds,
   819  			ExpectedResult:  nil,
   820  			ExpectedErr:     testErr,
   821  		},
   822  	}
   823  
   824  	for _, testCase := range testCases {
   825  		t.Run(testCase.Name, func(t *testing.T) {
   826  			svc := testCase.ServiceFn()
   827  			converter := testCase.ApplicationConverterFn()
   828  
   829  			mockPersistence := testCase.PersistenceFn()
   830  			mockTransactioner := testCase.TransactionerFn(mockPersistence)
   831  
   832  			resolver := application.NewResolver(mockTransactioner, svc, nil, nil, nil, converter, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
   833  
   834  			// WHEN
   835  			result, err := resolver.MergeApplications(context.TODO(), destAppID, srcAppID)
   836  
   837  			// then
   838  			assert.Equal(t, testCase.ExpectedResult, result)
   839  			assert.Equal(t, testCase.ExpectedErr, err)
   840  
   841  			svc.AssertExpectations(t)
   842  			mockPersistence.AssertExpectations(t)
   843  			mockTransactioner.AssertExpectations(t)
   844  		})
   845  	}
   846  }
   847  
   848  func TestResolver_ApplicationBySystemNumber(t *testing.T) {
   849  	// GIVEN
   850  	systemNumber := "18"
   851  	modelApplication := fixModelApplication("foo", "tenant-foo", appName, "Bar")
   852  	gqlApplication := fixGQLApplication("foo", appName, "Bar")
   853  	testErr := errors.New("Test error")
   854  
   855  	testCases := []struct {
   856  		Name                string
   857  		PersistenceFn       func() *persistenceautomock.PersistenceTx
   858  		TransactionerFn     func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
   859  		ServiceFn           func() *automock.ApplicationService
   860  		ConverterFn         func() *automock.ApplicationConverter
   861  		SystemNumber        string
   862  		ExpectedApplication *graphql.Application
   863  		ExpectedErr         error
   864  	}{
   865  		{
   866  			Name:            "Success",
   867  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
   868  			TransactionerFn: txtest.TransactionerThatSucceeds,
   869  			ServiceFn: func() *automock.ApplicationService {
   870  				svc := &automock.ApplicationService{}
   871  				svc.On("GetBySystemNumber", contextParam, systemNumber).Return(modelApplication, nil).Once()
   872  
   873  				return svc
   874  			},
   875  			ConverterFn: func() *automock.ApplicationConverter {
   876  				conv := &automock.ApplicationConverter{}
   877  				conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once()
   878  				return conv
   879  			},
   880  			SystemNumber:        systemNumber,
   881  			ExpectedApplication: gqlApplication,
   882  		},
   883  		{
   884  			Name:            "GetBySystemNumber returns NotFound error",
   885  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
   886  			TransactionerFn: txtest.TransactionerThatSucceeds,
   887  			ServiceFn: func() *automock.ApplicationService {
   888  				svc := &automock.ApplicationService{}
   889  				svc.On("GetBySystemNumber", contextParam, systemNumber).Return(nil, apperrors.NewNotFoundError(resource.Application, "foo")).Once()
   890  				return svc
   891  			},
   892  			ConverterFn: func() *automock.ApplicationConverter {
   893  				conv := &automock.ApplicationConverter{}
   894  				conv.AssertNotCalled(t, "ToGraphQL")
   895  				return conv
   896  			},
   897  			SystemNumber:        systemNumber,
   898  			ExpectedApplication: nil,
   899  			ExpectedErr:         nil,
   900  		},
   901  		{
   902  			Name:            "GetBySystemNumber returns error",
   903  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
   904  			TransactionerFn: txtest.TransactionerThatSucceeds,
   905  			ServiceFn: func() *automock.ApplicationService {
   906  				svc := &automock.ApplicationService{}
   907  				svc.On("GetBySystemNumber", contextParam, systemNumber).Return(nil, testErr).Once()
   908  				return svc
   909  			},
   910  			ConverterFn: func() *automock.ApplicationConverter {
   911  				conv := &automock.ApplicationConverter{}
   912  				conv.AssertNotCalled(t, "ToGraphQL")
   913  				return conv
   914  			},
   915  			SystemNumber:        systemNumber,
   916  			ExpectedApplication: nil,
   917  			ExpectedErr:         testErr,
   918  		},
   919  		{
   920  			Name:          "Returns error when starting transaction failed",
   921  			PersistenceFn: txtest.PersistenceContextThatExpectsCommit,
   922  			ServiceFn: func() *automock.ApplicationService {
   923  				appSvc := &automock.ApplicationService{}
   924  				return appSvc
   925  			},
   926  			ConverterFn: func() *automock.ApplicationConverter {
   927  				conv := &automock.ApplicationConverter{}
   928  				conv.AssertNotCalled(t, "ToGraphQL")
   929  				return conv
   930  			},
   931  			TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner {
   932  				transact := &persistenceautomock.Transactioner{}
   933  				transact.On("Begin").Return(nil, testErr).Once()
   934  				return transact
   935  			},
   936  			SystemNumber:        systemNumber,
   937  			ExpectedApplication: nil,
   938  			ExpectedErr:         testErr,
   939  		},
   940  		{
   941  			Name: "Returns error when transaction commit failed",
   942  			PersistenceFn: func() *persistenceautomock.PersistenceTx {
   943  				persistTx := &persistenceautomock.PersistenceTx{}
   944  				persistTx.On("Commit").Return(testErr).Once()
   945  				return persistTx
   946  			},
   947  			ServiceFn: func() *automock.ApplicationService {
   948  				svc := &automock.ApplicationService{}
   949  				svc.On("GetBySystemNumber", contextParam, systemNumber).Return(modelApplication, nil).Once()
   950  				return svc
   951  			},
   952  			ConverterFn: func() *automock.ApplicationConverter {
   953  				conv := &automock.ApplicationConverter{}
   954  				conv.AssertNotCalled(t, "ToGraphQL")
   955  				return conv
   956  			},
   957  			TransactionerFn:     txtest.TransactionerThatSucceeds,
   958  			SystemNumber:        systemNumber,
   959  			ExpectedApplication: nil,
   960  			ExpectedErr:         testErr,
   961  		},
   962  	}
   963  
   964  	for _, testCase := range testCases {
   965  		t.Run(testCase.Name, func(t *testing.T) {
   966  			persistTx := testCase.PersistenceFn()
   967  			transact := testCase.TransactionerFn(persistTx)
   968  			svc := testCase.ServiceFn()
   969  			converter := testCase.ConverterFn()
   970  
   971  			resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
   972  			resolver.SetConverter(converter)
   973  
   974  			// WHEN
   975  			result, err := resolver.ApplicationBySystemNumber(context.TODO(), testCase.SystemNumber)
   976  
   977  			// then
   978  			assert.Equal(t, testCase.ExpectedApplication, result)
   979  			assert.Equal(t, testCase.ExpectedErr, err)
   980  
   981  			svc.AssertExpectations(t)
   982  			converter.AssertExpectations(t)
   983  		})
   984  	}
   985  }
   986  
   987  func TestResolver_Application(t *testing.T) {
   988  	// GIVEN
   989  	modelApplication := fixModelApplication("foo", "tenant-foo", "Foo", "Bar")
   990  	gqlApplication := fixGQLApplication("foo", "Foo", "Bar")
   991  	testErr := errors.New("Test error")
   992  
   993  	testCases := []struct {
   994  		Name                string
   995  		PersistenceFn       func() *persistenceautomock.PersistenceTx
   996  		TransactionerFn     func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
   997  		ServiceFn           func() *automock.ApplicationService
   998  		ConverterFn         func() *automock.ApplicationConverter
   999  		InputID             string
  1000  		ExpectedApplication *graphql.Application
  1001  		ExpectedErr         error
  1002  	}{
  1003  		{
  1004  			Name:            "Success",
  1005  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1006  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1007  			ServiceFn: func() *automock.ApplicationService {
  1008  				svc := &automock.ApplicationService{}
  1009  				svc.On("Get", contextParam, "foo").Return(modelApplication, nil).Once()
  1010  
  1011  				return svc
  1012  			},
  1013  			ConverterFn: func() *automock.ApplicationConverter {
  1014  				conv := &automock.ApplicationConverter{}
  1015  				conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once()
  1016  				return conv
  1017  			},
  1018  			InputID:             "foo",
  1019  			ExpectedApplication: gqlApplication,
  1020  			ExpectedErr:         nil,
  1021  		},
  1022  		{
  1023  			Name:            "Success returns nil when application not found",
  1024  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1025  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1026  			ServiceFn: func() *automock.ApplicationService {
  1027  				svc := &automock.ApplicationService{}
  1028  				svc.On("Get", contextParam, "foo").Return(nil, apperrors.NewNotFoundError(resource.Application, "foo")).Once()
  1029  
  1030  				return svc
  1031  			},
  1032  			ConverterFn: func() *automock.ApplicationConverter {
  1033  				conv := &automock.ApplicationConverter{}
  1034  				return conv
  1035  			},
  1036  			InputID:             "foo",
  1037  			ExpectedApplication: nil,
  1038  			ExpectedErr:         nil,
  1039  		},
  1040  		{
  1041  			Name:            "Returns error when application retrieval failed",
  1042  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1043  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1044  			ServiceFn: func() *automock.ApplicationService {
  1045  				svc := &automock.ApplicationService{}
  1046  				svc.On("Get", contextParam, "foo").Return(nil, testErr).Once()
  1047  
  1048  				return svc
  1049  			},
  1050  			ConverterFn: func() *automock.ApplicationConverter {
  1051  				conv := &automock.ApplicationConverter{}
  1052  				return conv
  1053  			},
  1054  			InputID:             "foo",
  1055  			ExpectedApplication: nil,
  1056  			ExpectedErr:         testErr,
  1057  		},
  1058  	}
  1059  
  1060  	for _, testCase := range testCases {
  1061  		t.Run(testCase.Name, func(t *testing.T) {
  1062  			persistTx := testCase.PersistenceFn()
  1063  			transact := testCase.TransactionerFn(persistTx)
  1064  			svc := testCase.ServiceFn()
  1065  			converter := testCase.ConverterFn()
  1066  
  1067  			resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  1068  			resolver.SetConverter(converter)
  1069  
  1070  			// WHEN
  1071  			result, err := resolver.Application(context.TODO(), testCase.InputID)
  1072  
  1073  			// then
  1074  			assert.Equal(t, testCase.ExpectedApplication, result)
  1075  			assert.Equal(t, testCase.ExpectedErr, err)
  1076  
  1077  			svc.AssertExpectations(t)
  1078  			converter.AssertExpectations(t)
  1079  		})
  1080  	}
  1081  }
  1082  
  1083  func TestResolver_Applications(t *testing.T) {
  1084  	// GIVEN
  1085  	modelApplications := []*model.Application{
  1086  		fixModelApplication("foo", "tenant-foo", "Foo", "Lorem Ipsum"),
  1087  		fixModelApplication("bar", "tenant-bar", "Bar", "Lorem Ipsum"),
  1088  	}
  1089  
  1090  	gqlApplications := []*graphql.Application{
  1091  		fixGQLApplication("foo", "Foo", "Lorem Ipsum"),
  1092  		fixGQLApplication("bar", "Bar", "Lorem Ipsum"),
  1093  	}
  1094  
  1095  	first := 2
  1096  	gqlAfter := graphql.PageCursor("test")
  1097  	after := "test"
  1098  	query := "foo"
  1099  	filter := []*labelfilter.LabelFilter{
  1100  		{Key: "", Query: &query},
  1101  	}
  1102  	gqlFilter := []*graphql.LabelFilter{
  1103  		{Key: "", Query: &query},
  1104  	}
  1105  	testErr := errors.New("Test error")
  1106  
  1107  	testCases := []struct {
  1108  		Name              string
  1109  		PersistenceFn     func() *persistenceautomock.PersistenceTx
  1110  		TransactionerFn   func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
  1111  		ServiceFn         func() *automock.ApplicationService
  1112  		ConverterFn       func() *automock.ApplicationConverter
  1113  		InputLabelFilters []*graphql.LabelFilter
  1114  		ExpectedResult    *graphql.ApplicationPage
  1115  		ExpectedErr       error
  1116  	}{
  1117  		{
  1118  			Name:            "Success",
  1119  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1120  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1121  			ServiceFn: func() *automock.ApplicationService {
  1122  				svc := &automock.ApplicationService{}
  1123  				svc.On("List", contextParam, filter, first, after).Return(fixApplicationPage(modelApplications), nil).Once()
  1124  				return svc
  1125  			},
  1126  			ConverterFn: func() *automock.ApplicationConverter {
  1127  				conv := &automock.ApplicationConverter{}
  1128  				conv.On("MultipleToGraphQL", modelApplications).Return(gqlApplications).Once()
  1129  				return conv
  1130  			},
  1131  			InputLabelFilters: gqlFilter,
  1132  			ExpectedResult:    fixGQLApplicationPage(gqlApplications),
  1133  			ExpectedErr:       nil,
  1134  		},
  1135  		{
  1136  			Name:            "Returns error when application listing failed",
  1137  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1138  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1139  			ServiceFn: func() *automock.ApplicationService {
  1140  				svc := &automock.ApplicationService{}
  1141  				svc.On("List", contextParam, filter, first, after).Return(nil, testErr).Once()
  1142  				return svc
  1143  			},
  1144  			ConverterFn: func() *automock.ApplicationConverter {
  1145  				conv := &automock.ApplicationConverter{}
  1146  				return conv
  1147  			},
  1148  			InputLabelFilters: gqlFilter,
  1149  			ExpectedResult:    nil,
  1150  			ExpectedErr:       testErr,
  1151  		},
  1152  	}
  1153  
  1154  	for _, testCase := range testCases {
  1155  		t.Run(testCase.Name, func(t *testing.T) {
  1156  			persistTx := testCase.PersistenceFn()
  1157  			transact := testCase.TransactionerFn(persistTx)
  1158  			svc := testCase.ServiceFn()
  1159  			converter := testCase.ConverterFn()
  1160  
  1161  			resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  1162  			resolver.SetConverter(converter)
  1163  
  1164  			// WHEN
  1165  			ctx := consumer.SaveToContext(context.TODO(), consumer.Consumer{ConsumerID: "testConsumerID"})
  1166  			result, err := resolver.Applications(ctx, testCase.InputLabelFilters, &first, &gqlAfter)
  1167  
  1168  			// then
  1169  			assert.Equal(t, testCase.ExpectedErr, err)
  1170  			assert.Equal(t, testCase.ExpectedResult, result)
  1171  
  1172  			svc.AssertExpectations(t)
  1173  			converter.AssertExpectations(t)
  1174  		})
  1175  	}
  1176  }
  1177  
  1178  func TestResolver_Applications_DoubleAuthFlow(t *testing.T) {
  1179  	// GIVEN
  1180  	appTemplateID := "12345678-ae7e-4d1a-8027-520a96d5319d"
  1181  
  1182  	modelApplication := fixModelApplication("foo", "tenant-foo", "Foo", "Bar")
  1183  	gqlApplication := fixGQLApplication("foo", "Foo", "Bar")
  1184  
  1185  	modelApplication.ApplicationTemplateID = &appTemplateID
  1186  	gqlApplication.ApplicationTemplateID = &appTemplateID
  1187  
  1188  	modelApplicationList := []*model.Application{
  1189  		modelApplication,
  1190  	}
  1191  	modelApplicationListWithNoMatchingRecord := []*model.Application{
  1192  		fixModelApplication("foo", "tenant-foo", "Foo", "Bar"),
  1193  	}
  1194  
  1195  	consumerID := "abcd1122-ae7e-4d1a-8027-520a96d5319d"
  1196  	onBehalfOf := "a9653128-gs3e-4d1a-8sdj-52a96dd5301d"
  1197  	region := "eu-1"
  1198  	tokenClientID := "sb-token-client-id"
  1199  	strippedTokenClientID := "token-client-id"
  1200  	selfRegisterDistinguishLabelKey := "test-distinguish-label-key"
  1201  
  1202  	certConsumer := consumer.Consumer{
  1203  		ConsumerID:    consumerID,
  1204  		ConsumerType:  consumer.ExternalCertificate,
  1205  		Flow:          oathkeeper.CertificateFlow,
  1206  		OnBehalfOf:    onBehalfOf,
  1207  		Region:        region,
  1208  		TokenClientID: tokenClientID,
  1209  	}
  1210  	ctxWithConsumerInfo := consumer.SaveToContext(context.TODO(), certConsumer)
  1211  
  1212  	appTmplFilters := []*labelfilter.LabelFilter{
  1213  		labelfilter.NewForKeyWithQuery(scenarioassignment.SubaccountIDKey, fmt.Sprintf("\"%s\"", consumerID)),
  1214  		labelfilter.NewForKeyWithQuery(tenant.RegionLabelKey, fmt.Sprintf("\"%s\"", region)),
  1215  		labelfilter.NewForKeyWithQuery(selfRegisterDistinguishLabelKey, fmt.Sprintf("\"%s\"", strippedTokenClientID)),
  1216  	}
  1217  
  1218  	appTemplate := fixModelApplicationTemplate(appTemplateID, "app-template")
  1219  
  1220  	testErr := errors.New("Test error")
  1221  
  1222  	testCases := []struct {
  1223  		Name                    string
  1224  		PersistenceFn           func() *persistenceautomock.PersistenceTx
  1225  		TransactionerFn         func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
  1226  		ServiceFn               func() *automock.ApplicationService
  1227  		AppTemplateServiceFn    func() *automock.ApplicationTemplateService
  1228  		ConverterFn             func() *automock.ApplicationConverter
  1229  		Context                 context.Context
  1230  		ExpectedApplicationPage *graphql.ApplicationPage
  1231  		ExpectedErr             error
  1232  	}{
  1233  		{
  1234  			Name:            "Success",
  1235  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1236  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1237  			ServiceFn: func() *automock.ApplicationService {
  1238  				svc := &automock.ApplicationService{}
  1239  				svc.On("ListAll", contextParam).Return(modelApplicationList, nil).Once()
  1240  
  1241  				return svc
  1242  			},
  1243  			ConverterFn: func() *automock.ApplicationConverter {
  1244  				conv := &automock.ApplicationConverter{}
  1245  				conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once()
  1246  				return conv
  1247  			},
  1248  			AppTemplateServiceFn: func() *automock.ApplicationTemplateService {
  1249  				svc := &automock.ApplicationTemplateService{}
  1250  				svc.On("GetByFilters", contextParam, appTmplFilters).Return(appTemplate, nil).Once()
  1251  
  1252  				return svc
  1253  			},
  1254  			Context: ctxWithConsumerInfo,
  1255  			ExpectedApplicationPage: &graphql.ApplicationPage{
  1256  				Data:       []*graphql.Application{gqlApplication},
  1257  				TotalCount: 1,
  1258  				PageInfo: &graphql.PageInfo{
  1259  					StartCursor: "1",
  1260  					EndCursor:   "1",
  1261  					HasNextPage: false,
  1262  				},
  1263  			},
  1264  			ExpectedErr: nil,
  1265  		},
  1266  		{
  1267  			Name:            "Error when no consumer is found in the context",
  1268  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1269  			TransactionerFn: txtest.NoopTransactioner,
  1270  			ServiceFn: func() *automock.ApplicationService {
  1271  				svc := &automock.ApplicationService{}
  1272  				svc.AssertNotCalled(t, "ListAll")
  1273  
  1274  				return svc
  1275  			},
  1276  			ConverterFn: func() *automock.ApplicationConverter {
  1277  				conv := &automock.ApplicationConverter{}
  1278  				conv.AssertNotCalled(t, "ToGraphQL")
  1279  				return conv
  1280  			},
  1281  			AppTemplateServiceFn: func() *automock.ApplicationTemplateService {
  1282  				svc := &automock.ApplicationTemplateService{}
  1283  				svc.AssertNotCalled(t, "GetByFilters")
  1284  
  1285  				return svc
  1286  			},
  1287  			Context:     context.TODO(),
  1288  			ExpectedErr: errors.New("cannot read consumer from context"),
  1289  		},
  1290  		{
  1291  			Name:            "Error when getting application template",
  1292  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1293  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1294  			ServiceFn: func() *automock.ApplicationService {
  1295  				svc := &automock.ApplicationService{}
  1296  				svc.AssertNotCalled(t, "ListAll")
  1297  
  1298  				return svc
  1299  			},
  1300  			ConverterFn: func() *automock.ApplicationConverter {
  1301  				conv := &automock.ApplicationConverter{}
  1302  				conv.AssertNotCalled(t, "ToGraphQL")
  1303  				return conv
  1304  			},
  1305  			AppTemplateServiceFn: func() *automock.ApplicationTemplateService {
  1306  				svc := &automock.ApplicationTemplateService{}
  1307  				svc.On("GetByFilters", contextParam, appTmplFilters).Return(nil, testErr).Once()
  1308  
  1309  				return svc
  1310  			},
  1311  			Context:     ctxWithConsumerInfo,
  1312  			ExpectedErr: testErr,
  1313  		},
  1314  		{
  1315  			Name:            "Error when listing applications template",
  1316  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1317  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1318  			ServiceFn: func() *automock.ApplicationService {
  1319  				svc := &automock.ApplicationService{}
  1320  				svc.On("ListAll", contextParam).Return(nil, testErr).Once()
  1321  
  1322  				return svc
  1323  			},
  1324  			ConverterFn: func() *automock.ApplicationConverter {
  1325  				conv := &automock.ApplicationConverter{}
  1326  				conv.AssertNotCalled(t, "ToGraphQL")
  1327  				return conv
  1328  			},
  1329  			AppTemplateServiceFn: func() *automock.ApplicationTemplateService {
  1330  				svc := &automock.ApplicationTemplateService{}
  1331  				svc.On("GetByFilters", contextParam, appTmplFilters).Return(appTemplate, nil).Once()
  1332  
  1333  				return svc
  1334  			},
  1335  			Context:     ctxWithConsumerInfo,
  1336  			ExpectedErr: testErr,
  1337  		},
  1338  		{
  1339  			Name:            "Error when no application found",
  1340  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1341  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1342  			ServiceFn: func() *automock.ApplicationService {
  1343  				svc := &automock.ApplicationService{}
  1344  				svc.On("ListAll", contextParam).Return(modelApplicationListWithNoMatchingRecord, nil).Once()
  1345  
  1346  				return svc
  1347  			},
  1348  			ConverterFn: func() *automock.ApplicationConverter {
  1349  				conv := &automock.ApplicationConverter{}
  1350  				conv.AssertNotCalled(t, "ToGraphQL")
  1351  				return conv
  1352  			},
  1353  			AppTemplateServiceFn: func() *automock.ApplicationTemplateService {
  1354  				svc := &automock.ApplicationTemplateService{}
  1355  				svc.On("GetByFilters", contextParam, appTmplFilters).Return(appTemplate, nil).Once()
  1356  
  1357  				return svc
  1358  			},
  1359  			Context:     ctxWithConsumerInfo,
  1360  			ExpectedErr: errors.New("No application found for template with ID \"12345678-ae7e-4d1a-8027-520a96d5319d\""),
  1361  		},
  1362  		{
  1363  			Name: "Error when committing",
  1364  			PersistenceFn: func() *persistenceautomock.PersistenceTx {
  1365  				persistTx := &persistenceautomock.PersistenceTx{}
  1366  				persistTx.On("Commit").Return(testErr).Once()
  1367  				return persistTx
  1368  			},
  1369  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1370  			ServiceFn: func() *automock.ApplicationService {
  1371  				svc := &automock.ApplicationService{}
  1372  				svc.On("ListAll", contextParam).Return(modelApplicationList, nil).Once()
  1373  
  1374  				return svc
  1375  			},
  1376  			ConverterFn: func() *automock.ApplicationConverter {
  1377  				conv := &automock.ApplicationConverter{}
  1378  				conv.On("ToGraphQL", modelApplication).Return(gqlApplication).Once()
  1379  				return conv
  1380  			},
  1381  			AppTemplateServiceFn: func() *automock.ApplicationTemplateService {
  1382  				svc := &automock.ApplicationTemplateService{}
  1383  				svc.On("GetByFilters", contextParam, appTmplFilters).Return(appTemplate, nil).Once()
  1384  
  1385  				return svc
  1386  			},
  1387  			Context:     ctxWithConsumerInfo,
  1388  			ExpectedErr: testErr,
  1389  		},
  1390  	}
  1391  
  1392  	for _, testCase := range testCases {
  1393  		t.Run(testCase.Name, func(t *testing.T) {
  1394  			persistTx := testCase.PersistenceFn()
  1395  			transact := testCase.TransactionerFn(persistTx)
  1396  			svc := testCase.ServiceFn()
  1397  			appTemplateSvc := testCase.AppTemplateServiceFn()
  1398  			converter := testCase.ConverterFn()
  1399  
  1400  			resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, appTemplateSvc, nil, nil, nil, selfRegisterDistinguishLabelKey, "sb-")
  1401  			resolver.SetConverter(converter)
  1402  
  1403  			first := 2
  1404  			gqlAfter := graphql.PageCursor("test")
  1405  			query := "foo"
  1406  			gqlFilter := []*graphql.LabelFilter{
  1407  				{Key: "", Query: &query},
  1408  			}
  1409  
  1410  			// WHEN
  1411  			result, err := resolver.Applications(testCase.Context, gqlFilter, &first, &gqlAfter)
  1412  
  1413  			// then
  1414  			assert.Equal(t, testCase.ExpectedApplicationPage, result)
  1415  
  1416  			if testCase.ExpectedErr != nil {
  1417  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1418  			}
  1419  
  1420  			mock.AssertExpectationsForObjects(t, svc, converter, appTemplateSvc)
  1421  		})
  1422  	}
  1423  }
  1424  
  1425  func TestResolver_ApplicationsForRuntime(t *testing.T) {
  1426  	testError := errors.New("test error")
  1427  
  1428  	modelApplications := []*model.Application{
  1429  		fixModelApplication("id1", "tenant-foo", "name", "desc"),
  1430  		fixModelApplication("id2", "tenant-bar", "name", "desc"),
  1431  	}
  1432  
  1433  	applicationGraphQL := []*graphql.Application{
  1434  		fixGQLApplication("id1", "name", "desc"),
  1435  		fixGQLApplication("id2", "name", "desc"),
  1436  	}
  1437  
  1438  	first := 10
  1439  	after := "test"
  1440  	gqlAfter := graphql.PageCursor(after)
  1441  
  1442  	txGen := txtest.NewTransactionContextGenerator(testError)
  1443  
  1444  	runtimeUUID := uuid.New()
  1445  	runtimeID := runtimeUUID.String()
  1446  	testCases := []struct {
  1447  		Name            string
  1448  		AppConverterFn  func() *automock.ApplicationConverter
  1449  		AppServiceFn    func() *automock.ApplicationService
  1450  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  1451  		InputRuntimeID  string
  1452  		ExpectedResult  *graphql.ApplicationPage
  1453  		ExpectedError   error
  1454  	}{
  1455  		{
  1456  			Name: "Success",
  1457  			AppServiceFn: func() *automock.ApplicationService {
  1458  				appService := &automock.ApplicationService{}
  1459  				appService.On("ListByRuntimeID", contextParam, runtimeUUID, first, after).Return(fixApplicationPage(modelApplications), nil).Once()
  1460  				return appService
  1461  			},
  1462  			AppConverterFn: func() *automock.ApplicationConverter {
  1463  				appConverter := &automock.ApplicationConverter{}
  1464  				appConverter.On("MultipleToGraphQL", modelApplications).Return(applicationGraphQL).Once()
  1465  				return appConverter
  1466  			},
  1467  			TransactionerFn: txGen.ThatSucceeds,
  1468  			InputRuntimeID:  runtimeID,
  1469  			ExpectedResult:  fixGQLApplicationPage(applicationGraphQL),
  1470  			ExpectedError:   nil,
  1471  		},
  1472  		{
  1473  			Name:            "Returns error when transaction commit failed",
  1474  			TransactionerFn: txGen.ThatFailsOnCommit,
  1475  			AppServiceFn: func() *automock.ApplicationService {
  1476  				appService := &automock.ApplicationService{}
  1477  				appService.On("ListByRuntimeID", contextParam, runtimeUUID, first, after).Return(fixApplicationPage(modelApplications), nil).Once()
  1478  				return appService
  1479  			},
  1480  			AppConverterFn: func() *automock.ApplicationConverter {
  1481  				appConverter := &automock.ApplicationConverter{}
  1482  				return appConverter
  1483  			},
  1484  			InputRuntimeID: runtimeID,
  1485  			ExpectedResult: nil,
  1486  			ExpectedError:  testError,
  1487  		},
  1488  		{
  1489  			Name: "Returns error when application listing failed",
  1490  			AppServiceFn: func() *automock.ApplicationService {
  1491  				appSvc := &automock.ApplicationService{}
  1492  				appSvc.On("ListByRuntimeID", contextParam, runtimeUUID, first, after).Return(nil, testError).Once()
  1493  				return appSvc
  1494  			},
  1495  			AppConverterFn: func() *automock.ApplicationConverter {
  1496  				appConverter := &automock.ApplicationConverter{}
  1497  				return appConverter
  1498  			},
  1499  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1500  			InputRuntimeID:  runtimeID,
  1501  			ExpectedResult:  nil,
  1502  			ExpectedError:   testError,
  1503  		},
  1504  		{
  1505  			Name: "Returns error when starting transaction failed",
  1506  			AppServiceFn: func() *automock.ApplicationService {
  1507  				appSvc := &automock.ApplicationService{}
  1508  				return appSvc
  1509  			},
  1510  			AppConverterFn: func() *automock.ApplicationConverter {
  1511  				appConverter := &automock.ApplicationConverter{}
  1512  				return appConverter
  1513  			},
  1514  			TransactionerFn: txGen.ThatFailsOnBegin,
  1515  			InputRuntimeID:  runtimeID,
  1516  			ExpectedResult:  nil,
  1517  			ExpectedError:   testError,
  1518  		},
  1519  		{
  1520  			Name: "Returns error when runtimeID is not UUID",
  1521  			AppServiceFn: func() *automock.ApplicationService {
  1522  				appSvc := &automock.ApplicationService{}
  1523  				return appSvc
  1524  			},
  1525  			AppConverterFn: func() *automock.ApplicationConverter {
  1526  				appConverter := &automock.ApplicationConverter{}
  1527  				return appConverter
  1528  			},
  1529  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  1530  			InputRuntimeID:  "blabla",
  1531  			ExpectedResult:  nil,
  1532  			ExpectedError:   errors.New("invalid UUID length"),
  1533  		},
  1534  	}
  1535  
  1536  	for _, testCase := range testCases {
  1537  		t.Run(testCase.Name, func(t *testing.T) {
  1538  			// GIVEN
  1539  			applicationSvc := testCase.AppServiceFn()
  1540  			applicationConverter := testCase.AppConverterFn()
  1541  			persistTx, transact := testCase.TransactionerFn()
  1542  
  1543  			resolver := application.NewResolver(transact, applicationSvc, nil, nil, nil, applicationConverter, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  1544  
  1545  			// WHEN
  1546  			result, err := resolver.ApplicationsForRuntime(context.TODO(), testCase.InputRuntimeID, &first, &gqlAfter)
  1547  
  1548  			// THEN
  1549  			if testCase.ExpectedError != nil {
  1550  				require.NotNil(t, err)
  1551  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
  1552  			} else {
  1553  				require.NoError(t, err)
  1554  			}
  1555  			assert.Equal(t, testCase.ExpectedResult, result)
  1556  			applicationSvc.AssertExpectations(t)
  1557  			applicationConverter.AssertExpectations(t)
  1558  			persistTx.AssertExpectations(t)
  1559  			transact.AssertExpectations(t)
  1560  		})
  1561  	}
  1562  }
  1563  
  1564  func TestResolver_SetApplicationLabel(t *testing.T) {
  1565  	// GIVEN
  1566  	testErr := errors.New("Test error")
  1567  
  1568  	applicationID := "foo"
  1569  	gqlLabel := &graphql.Label{
  1570  		Key:   "key",
  1571  		Value: []string{"foo", "bar"},
  1572  	}
  1573  	modelLabel := &model.LabelInput{
  1574  		Key:        "key",
  1575  		Value:      []string{"foo", "bar"},
  1576  		ObjectID:   applicationID,
  1577  		ObjectType: model.ApplicationLabelableObject,
  1578  	}
  1579  
  1580  	testCases := []struct {
  1581  		Name               string
  1582  		PersistenceFn      func() *persistenceautomock.PersistenceTx
  1583  		TransactionerFn    func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
  1584  		ServiceFn          func() *automock.ApplicationService
  1585  		ConverterFn        func() *automock.ApplicationConverter
  1586  		InputApplicationID string
  1587  		InputKey           string
  1588  		InputValue         interface{}
  1589  		ExpectedLabel      *graphql.Label
  1590  		ExpectedErr        error
  1591  	}{
  1592  		{
  1593  			Name:            "Success",
  1594  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1595  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1596  			ServiceFn: func() *automock.ApplicationService {
  1597  				svc := &automock.ApplicationService{}
  1598  				svc.On("SetLabel", contextParam, modelLabel).Return(nil).Once()
  1599  				return svc
  1600  			},
  1601  			ConverterFn: func() *automock.ApplicationConverter {
  1602  				conv := &automock.ApplicationConverter{}
  1603  				return conv
  1604  			},
  1605  			InputApplicationID: applicationID,
  1606  			InputKey:           gqlLabel.Key,
  1607  			InputValue:         gqlLabel.Value,
  1608  			ExpectedLabel:      gqlLabel,
  1609  			ExpectedErr:        nil,
  1610  		},
  1611  		{
  1612  			Name:            "Returns error when adding label to application failed",
  1613  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1614  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1615  			ServiceFn: func() *automock.ApplicationService {
  1616  				svc := &automock.ApplicationService{}
  1617  				svc.On("SetLabel", contextParam, modelLabel).Return(testErr).Once()
  1618  				return svc
  1619  			},
  1620  			ConverterFn: func() *automock.ApplicationConverter {
  1621  				conv := &automock.ApplicationConverter{}
  1622  				return conv
  1623  			},
  1624  			InputApplicationID: applicationID,
  1625  			InputKey:           gqlLabel.Key,
  1626  			InputValue:         gqlLabel.Value,
  1627  			ExpectedLabel:      nil,
  1628  			ExpectedErr:        testErr,
  1629  		},
  1630  	}
  1631  
  1632  	for _, testCase := range testCases {
  1633  		t.Run(testCase.Name, func(t *testing.T) {
  1634  			svc := testCase.ServiceFn()
  1635  			converter := testCase.ConverterFn()
  1636  			persistTx := testCase.PersistenceFn()
  1637  			transactioner := testCase.TransactionerFn(persistTx)
  1638  
  1639  			resolver := application.NewResolver(transactioner, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  1640  			resolver.SetConverter(converter)
  1641  
  1642  			// WHEN
  1643  			result, err := resolver.SetApplicationLabel(context.TODO(), testCase.InputApplicationID, testCase.InputKey, testCase.InputValue)
  1644  
  1645  			// then
  1646  			assert.Equal(t, testCase.ExpectedLabel, result)
  1647  			assert.Equal(t, testCase.ExpectedErr, err)
  1648  
  1649  			svc.AssertExpectations(t)
  1650  			converter.AssertExpectations(t)
  1651  			persistTx.AssertExpectations(t)
  1652  		})
  1653  	}
  1654  
  1655  	t.Run("Returns error when Label input validation failed", func(t *testing.T) {
  1656  		resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  1657  
  1658  		// WHEN
  1659  		result, err := resolver.SetApplicationLabel(context.TODO(), "", "", "")
  1660  
  1661  		// then
  1662  		require.Nil(t, result)
  1663  		require.Error(t, err)
  1664  		assert.Contains(t, err.Error(), "key=cannot be blank")
  1665  		assert.Contains(t, err.Error(), "value=cannot be blank")
  1666  		assert.Contains(t, err.Error(), "validation error for type LabelInput:")
  1667  	})
  1668  }
  1669  
  1670  func TestResolver_DeleteApplicationLabel(t *testing.T) {
  1671  	// GIVEN
  1672  	testErr := errors.New("Test error")
  1673  
  1674  	applicationID := "foo"
  1675  
  1676  	labelKey := "key"
  1677  
  1678  	gqlLabel := &graphql.Label{
  1679  		Key:   labelKey,
  1680  		Value: []string{"foo", "bar"},
  1681  	}
  1682  
  1683  	modelLabel := &model.Label{
  1684  		ID:         "b39ba24d-87fe-43fe-ac55-7f2e5ee04bcb",
  1685  		Tenant:     str.Ptr("tnt"),
  1686  		Key:        labelKey,
  1687  		Value:      []string{"foo", "bar"},
  1688  		ObjectID:   applicationID,
  1689  		ObjectType: model.ApplicationLabelableObject,
  1690  	}
  1691  
  1692  	testCases := []struct {
  1693  		Name               string
  1694  		PersistenceFn      func() *persistenceautomock.PersistenceTx
  1695  		TransactionerFn    func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
  1696  		ServiceFn          func() *automock.ApplicationService
  1697  		ConverterFn        func() *automock.ApplicationConverter
  1698  		InputApplicationID string
  1699  		InputKey           string
  1700  		ExpectedLabel      *graphql.Label
  1701  		ExpectedErr        error
  1702  	}{
  1703  		{
  1704  			Name:            "Success",
  1705  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1706  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1707  			ServiceFn: func() *automock.ApplicationService {
  1708  				svc := &automock.ApplicationService{}
  1709  				svc.On("GetLabel", contextParam, applicationID, labelKey).Return(modelLabel, nil).Once()
  1710  				svc.On("DeleteLabel", contextParam, applicationID, labelKey).Return(nil).Once()
  1711  				return svc
  1712  			},
  1713  			ConverterFn: func() *automock.ApplicationConverter {
  1714  				conv := &automock.ApplicationConverter{}
  1715  				return conv
  1716  			},
  1717  			InputApplicationID: applicationID,
  1718  			InputKey:           gqlLabel.Key,
  1719  			ExpectedLabel:      gqlLabel,
  1720  			ExpectedErr:        nil,
  1721  		},
  1722  		{
  1723  			Name:            "Returns error when label retrieval failed",
  1724  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1725  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1726  			ServiceFn: func() *automock.ApplicationService {
  1727  				svc := &automock.ApplicationService{}
  1728  				svc.On("GetLabel", contextParam, applicationID, labelKey).Return(nil, testErr).Once()
  1729  				return svc
  1730  			},
  1731  			ConverterFn: func() *automock.ApplicationConverter {
  1732  				conv := &automock.ApplicationConverter{}
  1733  				return conv
  1734  			},
  1735  			InputApplicationID: applicationID,
  1736  			InputKey:           gqlLabel.Key,
  1737  			ExpectedLabel:      nil,
  1738  			ExpectedErr:        testErr,
  1739  		},
  1740  		{
  1741  			Name:            "Returns error when deleting application's label failed",
  1742  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1743  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1744  			ServiceFn: func() *automock.ApplicationService {
  1745  				svc := &automock.ApplicationService{}
  1746  				svc.On("GetLabel", contextParam, applicationID, labelKey).Return(modelLabel, nil).Once()
  1747  				svc.On("DeleteLabel", contextParam, applicationID, labelKey).Return(testErr).Once()
  1748  				return svc
  1749  			},
  1750  			ConverterFn: func() *automock.ApplicationConverter {
  1751  				conv := &automock.ApplicationConverter{}
  1752  				return conv
  1753  			},
  1754  			InputApplicationID: applicationID,
  1755  			InputKey:           gqlLabel.Key,
  1756  			ExpectedLabel:      nil,
  1757  			ExpectedErr:        testErr,
  1758  		},
  1759  	}
  1760  
  1761  	for _, testCase := range testCases {
  1762  		t.Run(testCase.Name, func(t *testing.T) {
  1763  			svc := testCase.ServiceFn()
  1764  			converter := testCase.ConverterFn()
  1765  			persistTx := testCase.PersistenceFn()
  1766  			transactioner := testCase.TransactionerFn(persistTx)
  1767  
  1768  			resolver := application.NewResolver(transactioner, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  1769  			resolver.SetConverter(converter)
  1770  
  1771  			// WHEN
  1772  			result, err := resolver.DeleteApplicationLabel(context.TODO(), testCase.InputApplicationID, testCase.InputKey)
  1773  
  1774  			// then
  1775  			assert.Equal(t, testCase.ExpectedLabel, result)
  1776  			assert.Equal(t, testCase.ExpectedErr, err)
  1777  
  1778  			svc.AssertExpectations(t)
  1779  			converter.AssertExpectations(t)
  1780  			transactioner.AssertExpectations(t)
  1781  			persistTx.AssertExpectations(t)
  1782  		})
  1783  	}
  1784  }
  1785  
  1786  func TestResolver_Webhooks(t *testing.T) {
  1787  	// GIVEN
  1788  	applicationID := "fooid"
  1789  	modelWebhooks := []*model.Webhook{
  1790  		fixModelWebhook(applicationID, "foo"),
  1791  		fixModelWebhook(applicationID, "bar"),
  1792  	}
  1793  	gqlWebhooks := []*graphql.Webhook{
  1794  		fixGQLWebhook("foo"),
  1795  		fixGQLWebhook("bar"),
  1796  	}
  1797  	app := fixGQLApplication(applicationID, "foo", "bar")
  1798  	testErr := errors.New("Test error")
  1799  
  1800  	testCases := []struct {
  1801  		Name               string
  1802  		PersistenceFn      func() *persistenceautomock.PersistenceTx
  1803  		TransactionerFn    func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
  1804  		ServiceFn          func() *automock.WebhookService
  1805  		WebhookConverterFn func() *automock.WebhookConverter
  1806  		ExpectedResult     []*graphql.Webhook
  1807  		ExpectedErr        error
  1808  	}{
  1809  		{
  1810  			Name:            "Success",
  1811  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1812  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1813  			ServiceFn: func() *automock.WebhookService {
  1814  				svc := &automock.WebhookService{}
  1815  				svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(modelWebhooks, nil).Once()
  1816  				return svc
  1817  			},
  1818  			WebhookConverterFn: func() *automock.WebhookConverter {
  1819  				conv := &automock.WebhookConverter{}
  1820  				conv.On("MultipleToGraphQL", modelWebhooks).Return(gqlWebhooks, nil).Once()
  1821  				return conv
  1822  			},
  1823  			ExpectedResult: gqlWebhooks,
  1824  			ExpectedErr:    nil,
  1825  		},
  1826  		{
  1827  			Name:            "Returns error when webhook listing failed",
  1828  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1829  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1830  			ServiceFn: func() *automock.WebhookService {
  1831  				svc := &automock.WebhookService{}
  1832  				svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(nil, testErr).Once()
  1833  				return svc
  1834  			},
  1835  			WebhookConverterFn: func() *automock.WebhookConverter {
  1836  				return &automock.WebhookConverter{}
  1837  			},
  1838  			ExpectedResult: nil,
  1839  			ExpectedErr:    testErr,
  1840  		},
  1841  		{
  1842  			Name:            "Returns error when webhook conversion to graphql fails",
  1843  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1844  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1845  			ServiceFn: func() *automock.WebhookService {
  1846  				svc := &automock.WebhookService{}
  1847  				svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(modelWebhooks, nil).Once()
  1848  				return svc
  1849  			},
  1850  			WebhookConverterFn: func() *automock.WebhookConverter {
  1851  				conv := &automock.WebhookConverter{}
  1852  				conv.On("MultipleToGraphQL", modelWebhooks).Return(nil, testErr).Once()
  1853  				return conv
  1854  			},
  1855  			ExpectedResult: nil,
  1856  			ExpectedErr:    testErr,
  1857  		},
  1858  		{
  1859  			Name: "Returns error on starting transaction",
  1860  			TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner {
  1861  				transact := &persistenceautomock.Transactioner{}
  1862  				transact.On("Begin").Return(nil, testErr).Once()
  1863  				return transact
  1864  			},
  1865  			PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit,
  1866  			ServiceFn: func() *automock.WebhookService {
  1867  				return &automock.WebhookService{}
  1868  			},
  1869  			WebhookConverterFn: func() *automock.WebhookConverter {
  1870  				return &automock.WebhookConverter{}
  1871  			},
  1872  			ExpectedErr: testErr,
  1873  		},
  1874  		{
  1875  			Name: "Returns error on committing transaction",
  1876  			PersistenceFn: func() *persistenceautomock.PersistenceTx {
  1877  				persistTx := &persistenceautomock.PersistenceTx{}
  1878  				persistTx.On("Commit").Return(testErr).Once()
  1879  				return persistTx
  1880  			},
  1881  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1882  			ServiceFn: func() *automock.WebhookService {
  1883  				svc := &automock.WebhookService{}
  1884  				svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(modelWebhooks, nil).Once()
  1885  				return svc
  1886  			},
  1887  			WebhookConverterFn: func() *automock.WebhookConverter {
  1888  				conv := &automock.WebhookConverter{}
  1889  				conv.On("MultipleToGraphQL", modelWebhooks).Return(gqlWebhooks, nil).Once()
  1890  				return conv
  1891  			},
  1892  			ExpectedErr: testErr,
  1893  		},
  1894  		{
  1895  			Name: "Webhook service returns not found error",
  1896  			PersistenceFn: func() *persistenceautomock.PersistenceTx {
  1897  				persistTx := &persistenceautomock.PersistenceTx{}
  1898  				persistTx.On("Commit").Return(nil).Once()
  1899  				return persistTx
  1900  			},
  1901  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1902  			ServiceFn: func() *automock.WebhookService {
  1903  				svc := &automock.WebhookService{}
  1904  				svc.On("ListAllApplicationWebhooks", contextParam, applicationID).Return(nil, apperrors.NewNotFoundError(resource.Webhook, "foo")).Once()
  1905  				return svc
  1906  			},
  1907  			WebhookConverterFn: func() *automock.WebhookConverter {
  1908  				return &automock.WebhookConverter{}
  1909  			},
  1910  			ExpectedResult: nil,
  1911  			ExpectedErr:    nil,
  1912  		},
  1913  	}
  1914  
  1915  	for _, testCase := range testCases {
  1916  		t.Run(testCase.Name, func(t *testing.T) {
  1917  			svc := testCase.ServiceFn()
  1918  			converter := testCase.WebhookConverterFn()
  1919  
  1920  			mockPersistence := testCase.PersistenceFn()
  1921  			mockTransactioner := testCase.TransactionerFn(mockPersistence)
  1922  
  1923  			resolver := application.NewResolver(mockTransactioner, nil, svc, nil, nil, nil, converter, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  1924  
  1925  			// WHEN
  1926  			result, err := resolver.Webhooks(context.TODO(), app)
  1927  
  1928  			// then
  1929  			assert.Equal(t, testCase.ExpectedResult, result)
  1930  			assert.Equal(t, testCase.ExpectedErr, err)
  1931  
  1932  			svc.AssertExpectations(t)
  1933  			converter.AssertExpectations(t)
  1934  			mockPersistence.AssertExpectations(t)
  1935  			mockTransactioner.AssertExpectations(t)
  1936  		})
  1937  	}
  1938  }
  1939  
  1940  func TestResolver_Labels(t *testing.T) {
  1941  	// GIVEN
  1942  
  1943  	id := "foo"
  1944  	tenant := "tenant"
  1945  	labelKey1 := "key1"
  1946  	labelValue1 := "val1"
  1947  	labelKey2 := "key2"
  1948  	labelValue2 := "val2"
  1949  
  1950  	gqlApp := fixGQLApplication(id, "name", "desc")
  1951  
  1952  	modelLabels := map[string]*model.Label{
  1953  		"abc": {
  1954  			ID:         "abc",
  1955  			Tenant:     str.Ptr(tenant),
  1956  			Key:        labelKey1,
  1957  			Value:      labelValue1,
  1958  			ObjectID:   id,
  1959  			ObjectType: model.ApplicationLabelableObject,
  1960  		},
  1961  		"def": {
  1962  			ID:         "def",
  1963  			Tenant:     str.Ptr(tenant),
  1964  			Key:        labelKey2,
  1965  			Value:      labelValue2,
  1966  			ObjectID:   id,
  1967  			ObjectType: model.ApplicationLabelableObject,
  1968  		},
  1969  	}
  1970  
  1971  	gqlLabels := graphql.Labels{
  1972  		labelKey1: labelValue1,
  1973  		labelKey2: labelValue2,
  1974  	}
  1975  
  1976  	gqlLabels1 := graphql.Labels{
  1977  		labelKey1: labelValue1,
  1978  	}
  1979  
  1980  	testErr := errors.New("Test error")
  1981  
  1982  	testCases := []struct {
  1983  		Name            string
  1984  		PersistenceFn   func() *persistenceautomock.PersistenceTx
  1985  		TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
  1986  		ServiceFn       func() *automock.ApplicationService
  1987  		InputApp        *graphql.Application
  1988  		InputKey        *string
  1989  		ExpectedResult  graphql.Labels
  1990  		ExpectedErr     error
  1991  	}{
  1992  		{
  1993  			Name:            "Success",
  1994  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1995  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1996  			ServiceFn: func() *automock.ApplicationService {
  1997  				svc := &automock.ApplicationService{}
  1998  				svc.On("ListLabels", contextParam, id).Return(modelLabels, nil).Once()
  1999  				return svc
  2000  			},
  2001  			InputKey:       nil,
  2002  			ExpectedResult: gqlLabels,
  2003  			ExpectedErr:    nil,
  2004  		},
  2005  		{
  2006  			Name:            "Success when labels are filtered",
  2007  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  2008  			TransactionerFn: txtest.TransactionerThatSucceeds,
  2009  			ServiceFn: func() *automock.ApplicationService {
  2010  				svc := &automock.ApplicationService{}
  2011  				svc.On("ListLabels", contextParam, id).Return(modelLabels, nil).Once()
  2012  				return svc
  2013  			},
  2014  			InputKey:       &labelKey1,
  2015  			ExpectedResult: gqlLabels1,
  2016  			ExpectedErr:    nil,
  2017  		},
  2018  		{
  2019  			Name:            "Returns error when label listing failed",
  2020  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  2021  			TransactionerFn: txtest.TransactionerThatSucceeds,
  2022  			ServiceFn: func() *automock.ApplicationService {
  2023  				svc := &automock.ApplicationService{}
  2024  				svc.On("ListLabels", contextParam, id).Return(nil, testErr).Once()
  2025  				return svc
  2026  			},
  2027  			InputKey:       &labelKey1,
  2028  			ExpectedResult: nil,
  2029  			ExpectedErr:    testErr,
  2030  		},
  2031  	}
  2032  
  2033  	for _, testCase := range testCases {
  2034  		t.Run(testCase.Name, func(t *testing.T) {
  2035  			svc := testCase.ServiceFn()
  2036  			persistTx := testCase.PersistenceFn()
  2037  			transact := testCase.TransactionerFn(persistTx)
  2038  
  2039  			resolver := application.NewResolver(transact, svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  2040  
  2041  			// WHEN
  2042  			result, err := resolver.Labels(context.TODO(), gqlApp, testCase.InputKey)
  2043  
  2044  			// then
  2045  			assert.Equal(t, testCase.ExpectedResult, result)
  2046  			assert.Equal(t, testCase.ExpectedErr, err)
  2047  
  2048  			svc.AssertExpectations(t)
  2049  			transact.AssertExpectations(t)
  2050  			persistTx.AssertExpectations(t)
  2051  		})
  2052  	}
  2053  }
  2054  
  2055  func TestResolver_Auths(t *testing.T) {
  2056  	// GIVEN
  2057  	id := "foo"
  2058  	auth := model.Auth{
  2059  		Credential: model.CredentialData{},
  2060  		OneTimeToken: &model.OneTimeToken{
  2061  			Token:     "sometoken",
  2062  			Type:      tokens.ApplicationToken,
  2063  			CreatedAt: time.Now(),
  2064  			Used:      false,
  2065  		},
  2066  	}
  2067  	gqlAuth := graphql.OneTimeTokenForApplication{
  2068  		TokenWithURL: graphql.TokenWithURL{
  2069  			Token:        auth.OneTimeToken.Token,
  2070  			ConnectorURL: auth.OneTimeToken.ConnectorURL,
  2071  		},
  2072  		LegacyConnectorURL: legacyConnectorURL,
  2073  	}
  2074  	testError := errors.New("error")
  2075  	gqlApp := fixGQLApplication(id, "name", "desc")
  2076  	txGen := txtest.NewTransactionContextGenerator(testError)
  2077  
  2078  	sysAuthModels := []pkgmodel.SystemAuth{{ID: "id1", AppID: &id, Value: &auth}, {ID: "id2", AppID: &id, Value: &auth}}
  2079  	sysAuthModelCert := []pkgmodel.SystemAuth{{ID: "id1", AppID: &id, Value: nil}}
  2080  	sysAuthGQL := []*graphql.AppSystemAuth{{ID: "id1", Auth: &graphql.Auth{
  2081  		OneTimeToken: &gqlAuth,
  2082  	}}, {ID: "id2", Auth: &graphql.Auth{
  2083  		OneTimeToken: &gqlAuth,
  2084  	}}}
  2085  	sysAuthGQLCert := []*graphql.AppSystemAuth{{ID: "id1", Auth: nil}}
  2086  	sysAuthExpected := []*graphql.AppSystemAuth{{ID: "id1", Auth: &graphql.Auth{OneTimeToken: &gqlAuth}}, {ID: "id2", Auth: &graphql.Auth{OneTimeToken: &gqlAuth}}}
  2087  	testCases := []struct {
  2088  		Name            string
  2089  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  2090  		ServiceFn       func() *automock.SystemAuthService
  2091  		SysAuthConvFn   func() *automock.SystemAuthConverter
  2092  		InputApp        *graphql.Application
  2093  		ExpectedResult  []*graphql.AppSystemAuth
  2094  		ExpectedErr     error
  2095  	}{
  2096  		{
  2097  			Name:            "Success",
  2098  			TransactionerFn: txGen.ThatSucceeds,
  2099  			ServiceFn: func() *automock.SystemAuthService {
  2100  				svc := &automock.SystemAuthService{}
  2101  				svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return(sysAuthModels, nil).Once()
  2102  				return svc
  2103  			},
  2104  			SysAuthConvFn: func() *automock.SystemAuthConverter {
  2105  				sysAuthConv := &automock.SystemAuthConverter{}
  2106  				sysAuthConv.On("ToGraphQL", &sysAuthModels[0]).Return(sysAuthGQL[0], nil).Once()
  2107  				sysAuthConv.On("ToGraphQL", &sysAuthModels[1]).Return(sysAuthGQL[1], nil).Once()
  2108  				return sysAuthConv
  2109  			},
  2110  			InputApp:       gqlApp,
  2111  			ExpectedResult: sysAuthExpected,
  2112  			ExpectedErr:    nil,
  2113  		},
  2114  		{
  2115  			Name:            "Success when System Auth is certificate",
  2116  			TransactionerFn: txGen.ThatSucceeds,
  2117  			ServiceFn: func() *automock.SystemAuthService {
  2118  				svc := &automock.SystemAuthService{}
  2119  				svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return(sysAuthModelCert, nil).Once()
  2120  				return svc
  2121  			},
  2122  			SysAuthConvFn: func() *automock.SystemAuthConverter {
  2123  				sysAuthConv := &automock.SystemAuthConverter{}
  2124  				sysAuthConv.On("ToGraphQL", &sysAuthModelCert[0]).Return(sysAuthGQLCert[0], nil).Once()
  2125  				return sysAuthConv
  2126  			},
  2127  			InputApp:       gqlApp,
  2128  			ExpectedResult: sysAuthGQLCert,
  2129  			ExpectedErr:    nil,
  2130  		},
  2131  		{
  2132  			Name:            "Returns error when commit transaction failed",
  2133  			TransactionerFn: txGen.ThatFailsOnCommit,
  2134  			ServiceFn: func() *automock.SystemAuthService {
  2135  				svc := &automock.SystemAuthService{}
  2136  				svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return(sysAuthModels, nil).Once()
  2137  				svc.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType")
  2138  				return svc
  2139  			},
  2140  			SysAuthConvFn: func() *automock.SystemAuthConverter {
  2141  				sysAuthConv := &automock.SystemAuthConverter{}
  2142  				sysAuthConv.AssertNotCalled(t, "ToGraphQL")
  2143  				return sysAuthConv
  2144  			},
  2145  			InputApp:       gqlApp,
  2146  			ExpectedResult: nil,
  2147  			ExpectedErr:    testError,
  2148  		},
  2149  		{
  2150  			Name:            "Returns error when list for SystemAuths failed",
  2151  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  2152  			ServiceFn: func() *automock.SystemAuthService {
  2153  				svc := &automock.SystemAuthService{}
  2154  				svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return([]pkgmodel.SystemAuth{}, testError).Once()
  2155  				svc.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType")
  2156  				return svc
  2157  			},
  2158  			SysAuthConvFn: func() *automock.SystemAuthConverter {
  2159  				sysAuthConv := &automock.SystemAuthConverter{}
  2160  				sysAuthConv.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType")
  2161  				return sysAuthConv
  2162  			},
  2163  			InputApp:       gqlApp,
  2164  			ExpectedResult: nil,
  2165  			ExpectedErr:    testError,
  2166  		},
  2167  		{
  2168  			Name:            "Returns error when conversion to graphql fails",
  2169  			TransactionerFn: txGen.ThatSucceeds,
  2170  			ServiceFn: func() *automock.SystemAuthService {
  2171  				svc := &automock.SystemAuthService{}
  2172  				svc.On("ListForObject", txtest.CtxWithDBMatcher(), pkgmodel.ApplicationReference, id).Return(sysAuthModels, nil).Once()
  2173  				svc.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType")
  2174  				return svc
  2175  			},
  2176  			SysAuthConvFn: func() *automock.SystemAuthConverter {
  2177  				sysAuthConv := &automock.SystemAuthConverter{}
  2178  				sysAuthConv.On("ToGraphQL", &sysAuthModels[0]).Return(nil, testError).Once()
  2179  				return sysAuthConv
  2180  			},
  2181  			InputApp:       gqlApp,
  2182  			ExpectedResult: nil,
  2183  			ExpectedErr:    testError,
  2184  		},
  2185  		{
  2186  			Name:            "Returns error when starting transaction failed",
  2187  			TransactionerFn: txGen.ThatFailsOnBegin,
  2188  			ServiceFn: func() *automock.SystemAuthService {
  2189  				svc := &automock.SystemAuthService{}
  2190  				svc.AssertNotCalled(t, "IsSystemAuthOneTimeTokenType")
  2191  				return svc
  2192  			},
  2193  			SysAuthConvFn: func() *automock.SystemAuthConverter {
  2194  				sysAuthConv := &automock.SystemAuthConverter{}
  2195  				return sysAuthConv
  2196  			},
  2197  			InputApp:       gqlApp,
  2198  			ExpectedResult: nil,
  2199  			ExpectedErr:    testError,
  2200  		},
  2201  	}
  2202  
  2203  	for _, testCase := range testCases {
  2204  		t.Run(testCase.Name, func(t *testing.T) {
  2205  			svc := testCase.ServiceFn()
  2206  			persist, transact := testCase.TransactionerFn()
  2207  			conv := testCase.SysAuthConvFn()
  2208  
  2209  			resolver := application.NewResolver(transact, nil, nil, nil, svc, nil, nil, conv, nil, nil, nil, nil, nil, nil, nil, "", "")
  2210  
  2211  			// WHEN
  2212  			result, err := resolver.Auths(context.TODO(), testCase.InputApp)
  2213  
  2214  			// then
  2215  			assert.Equal(t, testCase.ExpectedResult, result)
  2216  			assert.Equal(t, testCase.ExpectedErr, err)
  2217  
  2218  			svc.AssertExpectations(t)
  2219  			conv.AssertExpectations(t)
  2220  			transact.AssertExpectations(t)
  2221  			persist.AssertExpectations(t)
  2222  		})
  2223  	}
  2224  
  2225  	t.Run("Returns error when application is nil", func(t *testing.T) {
  2226  		resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  2227  		// WHEN
  2228  		_, err := resolver.Auths(context.TODO(), nil)
  2229  		// THEN
  2230  		require.Error(t, err)
  2231  		assert.EqualError(t, err, "Internal Server Error: Application cannot be empty")
  2232  	})
  2233  }
  2234  
  2235  func TestResolver_EventingConfiguration(t *testing.T) {
  2236  	// GIVEN
  2237  	tnt := "tnt"
  2238  	externalTnt := "ex-tnt"
  2239  	ctx := context.TODO()
  2240  	ctx = tenant.SaveToContext(ctx, tnt, externalTnt)
  2241  
  2242  	applicationID := uuid.New()
  2243  	gqlApp := fixGQLApplication(applicationID.String(), "bar", "baz")
  2244  	app := fixModelApplication(applicationID.String(), tnt, "bar", "baz")
  2245  
  2246  	converterMock := func() *automock.ApplicationConverter {
  2247  		converter := &automock.ApplicationConverter{}
  2248  		converter.On("GraphQLToModel", gqlApp, tnt).Return(app).Once()
  2249  		return converter
  2250  	}
  2251  
  2252  	testErr := errors.New("this is a test error")
  2253  	txGen := txtest.NewTransactionContextGenerator(testErr)
  2254  
  2255  	defaultEveningURL := "https://eventing.domain.local"
  2256  	modelAppEventingCfg := fixModelApplicationEventingConfiguration(t, defaultEveningURL)
  2257  	gqlAppEventingCfg := fixGQLApplicationEventingConfiguration(defaultEveningURL)
  2258  
  2259  	testCases := []struct {
  2260  		Name            string
  2261  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  2262  		EventingSvcFn   func() *automock.EventingService
  2263  		ConverterFn     func() *automock.ApplicationConverter
  2264  		ExpectedOutput  *graphql.ApplicationEventingConfiguration
  2265  		ExpectedError   error
  2266  	}{
  2267  		{
  2268  			Name:            "Success",
  2269  			TransactionerFn: txGen.ThatSucceeds,
  2270  			EventingSvcFn: func() *automock.EventingService {
  2271  				eventingSvc := &automock.EventingService{}
  2272  				eventingSvc.On("GetForApplication", txtest.CtxWithDBMatcher(), *app).Return(modelAppEventingCfg, nil).Once()
  2273  
  2274  				return eventingSvc
  2275  			},
  2276  			ConverterFn:    converterMock,
  2277  			ExpectedOutput: gqlAppEventingCfg,
  2278  			ExpectedError:  nil,
  2279  		}, {
  2280  			Name:            "Error when getting the configuration for runtime failed",
  2281  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  2282  			EventingSvcFn: func() *automock.EventingService {
  2283  				eventingSvc := &automock.EventingService{}
  2284  				eventingSvc.On("GetForApplication", txtest.CtxWithDBMatcher(), *app).Return(nil, testErr).Once()
  2285  				return eventingSvc
  2286  			},
  2287  			ConverterFn:    converterMock,
  2288  			ExpectedOutput: nil,
  2289  			ExpectedError:  testErr,
  2290  		}, {
  2291  			Name:            "Error when beginning transaction",
  2292  			TransactionerFn: txGen.ThatFailsOnBegin,
  2293  			EventingSvcFn: func() *automock.EventingService {
  2294  				eventingSvc := &automock.EventingService{}
  2295  				return eventingSvc
  2296  			},
  2297  			ConverterFn:    converterMock,
  2298  			ExpectedOutput: nil,
  2299  			ExpectedError:  testErr,
  2300  		}, {
  2301  			Name:            "Error when committing transaction",
  2302  			TransactionerFn: txGen.ThatFailsOnCommit,
  2303  			EventingSvcFn: func() *automock.EventingService {
  2304  				eventingSvc := &automock.EventingService{}
  2305  				eventingSvc.On("GetForApplication", txtest.CtxWithDBMatcher(), *app).Return(modelAppEventingCfg, nil).Once()
  2306  				return eventingSvc
  2307  			},
  2308  			ConverterFn:    converterMock,
  2309  			ExpectedOutput: nil,
  2310  			ExpectedError:  testErr,
  2311  		},
  2312  	}
  2313  
  2314  	for _, testCase := range testCases {
  2315  		t.Run(testCase.Name, func(t *testing.T) {
  2316  			persist, transact := testCase.TransactionerFn()
  2317  			eventingSvc := testCase.EventingSvcFn()
  2318  			converter := testCase.ConverterFn()
  2319  
  2320  			resolver := application.NewResolver(transact, nil, nil, nil, nil, converter, nil, nil, eventingSvc, nil, nil, nil, nil, nil, nil, "", "")
  2321  
  2322  			// WHEN
  2323  			result, err := resolver.EventingConfiguration(ctx, gqlApp)
  2324  
  2325  			// THEN
  2326  			if testCase.ExpectedError != nil {
  2327  				require.Error(t, err)
  2328  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
  2329  			} else {
  2330  				assert.NoError(t, err)
  2331  			}
  2332  			assert.Equal(t, testCase.ExpectedOutput, result)
  2333  
  2334  			mock.AssertExpectationsForObjects(t, eventingSvc, transact, persist, converter)
  2335  		})
  2336  	}
  2337  
  2338  	t.Run("Error when tenant not in context", func(t *testing.T) {
  2339  		// GIVEN
  2340  		resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  2341  
  2342  		// WHEN
  2343  		_, err := resolver.EventingConfiguration(context.TODO(), &graphql.Application{})
  2344  
  2345  		// THEN
  2346  		require.Error(t, err)
  2347  		assert.EqualError(t, err, "cannot read tenant from context")
  2348  	})
  2349  
  2350  	t.Run("Error when parent object is nil", func(t *testing.T) {
  2351  		// GIVEN
  2352  		resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  2353  
  2354  		// WHEN
  2355  		result, err := resolver.EventingConfiguration(context.TODO(), nil)
  2356  
  2357  		// THEN
  2358  		require.Error(t, err)
  2359  		assert.Contains(t, err.Error(), "Application cannot be empty")
  2360  		assert.Nil(t, result)
  2361  	})
  2362  }
  2363  
  2364  func TestResolver_Bundles(t *testing.T) {
  2365  	// GIVEN
  2366  	testErr := errors.New("test error")
  2367  
  2368  	firstAppID := "appID"
  2369  	secondAppID := "appID2"
  2370  	appIDs := []string{firstAppID, secondAppID}
  2371  
  2372  	bundleFirstApp := fixModelBundle("foo", firstAppID, "Foo", "Lorem Ipsum")
  2373  	bundleSecondApp := fixModelBundle("foo", secondAppID, "Foo", "Lorem Ipsum")
  2374  
  2375  	bundlesFirstApp := []*model.Bundle{bundleFirstApp}
  2376  	bundlesSecondApp := []*model.Bundle{bundleSecondApp}
  2377  
  2378  	gqlBundleFirstApp := fixGQLBundle("foo", "Foo", "Lorem Ipsum")
  2379  	gqlBundleSecondApp := fixGQLBundle("foo", "Foo", "Lorem Ipsum")
  2380  
  2381  	gqlBundlesFirstApp := []*graphql.Bundle{gqlBundleFirstApp}
  2382  	gqlBundlesSecondApp := []*graphql.Bundle{gqlBundleSecondApp}
  2383  
  2384  	bundlePageFirstApp := fixBundlePage(bundlesFirstApp)
  2385  	bundlePageSecondApp := fixBundlePage(bundlesSecondApp)
  2386  	bundlePages := []*model.BundlePage{bundlePageFirstApp, bundlePageSecondApp}
  2387  
  2388  	gqlBundlePageFirstApp := fixGQLBundlePage(gqlBundlesFirstApp)
  2389  	gqlBundlePageSecondApp := fixGQLBundlePage(gqlBundlesSecondApp)
  2390  	gqlBundlePages := []*graphql.BundlePage{gqlBundlePageFirstApp, gqlBundlePageSecondApp}
  2391  
  2392  	txGen := txtest.NewTransactionContextGenerator(testErr)
  2393  
  2394  	first := 2
  2395  	gqlAfter := graphql.PageCursor("test")
  2396  	after := "test"
  2397  
  2398  	testCases := []struct {
  2399  		Name            string
  2400  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  2401  		ServiceFn       func() *automock.BundleService
  2402  		ConverterFn     func() *automock.BundleConverter
  2403  		ExpectedResult  []*graphql.BundlePage
  2404  		ExpectedErr     []error
  2405  	}{
  2406  		{
  2407  			Name:            "Success",
  2408  			TransactionerFn: txGen.ThatSucceeds,
  2409  			ServiceFn: func() *automock.BundleService {
  2410  				svc := &automock.BundleService{}
  2411  				svc.On("ListByApplicationIDs", txtest.CtxWithDBMatcher(), appIDs, first, after).Return(bundlePages, nil).Once()
  2412  				return svc
  2413  			},
  2414  			ConverterFn: func() *automock.BundleConverter {
  2415  				conv := &automock.BundleConverter{}
  2416  				conv.On("MultipleToGraphQL", bundlesFirstApp).Return(gqlBundlesFirstApp, nil).Once()
  2417  				conv.On("MultipleToGraphQL", bundlesSecondApp).Return(gqlBundlesSecondApp, nil).Once()
  2418  				return conv
  2419  			},
  2420  			ExpectedResult: gqlBundlePages,
  2421  			ExpectedErr:    nil,
  2422  		},
  2423  		{
  2424  			Name:            "Returns error when transaction begin failed",
  2425  			TransactionerFn: txGen.ThatFailsOnBegin,
  2426  			ServiceFn: func() *automock.BundleService {
  2427  				svc := &automock.BundleService{}
  2428  				return svc
  2429  			},
  2430  			ConverterFn: func() *automock.BundleConverter {
  2431  				conv := &automock.BundleConverter{}
  2432  				return conv
  2433  			},
  2434  			ExpectedResult: nil,
  2435  			ExpectedErr:    []error{testErr},
  2436  		},
  2437  		{
  2438  			Name:            "Returns error when Bundles listing failed",
  2439  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  2440  			ServiceFn: func() *automock.BundleService {
  2441  				svc := &automock.BundleService{}
  2442  				svc.On("ListByApplicationIDs", txtest.CtxWithDBMatcher(), appIDs, first, after).Return(nil, testErr).Once()
  2443  				return svc
  2444  			},
  2445  			ConverterFn: func() *automock.BundleConverter {
  2446  				conv := &automock.BundleConverter{}
  2447  				return conv
  2448  			},
  2449  			ExpectedResult: nil,
  2450  			ExpectedErr:    []error{testErr},
  2451  		},
  2452  		{
  2453  			Name:            "Returns error when converting to GraphQL failed",
  2454  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  2455  			ServiceFn: func() *automock.BundleService {
  2456  				svc := &automock.BundleService{}
  2457  				svc.On("ListByApplicationIDs", txtest.CtxWithDBMatcher(), appIDs, first, after).Return(bundlePages, nil).Once()
  2458  				return svc
  2459  			},
  2460  			ConverterFn: func() *automock.BundleConverter {
  2461  				conv := &automock.BundleConverter{}
  2462  				conv.On("MultipleToGraphQL", bundlesFirstApp).Return(nil, testErr).Once()
  2463  				return conv
  2464  			},
  2465  			ExpectedResult: nil,
  2466  			ExpectedErr:    []error{testErr},
  2467  		},
  2468  		{
  2469  			Name:            "Returns error when transaction commit failed",
  2470  			TransactionerFn: txGen.ThatFailsOnCommit,
  2471  			ServiceFn: func() *automock.BundleService {
  2472  				svc := &automock.BundleService{}
  2473  				svc.On("ListByApplicationIDs", txtest.CtxWithDBMatcher(), appIDs, first, after).Return(bundlePages, nil).Once()
  2474  				return svc
  2475  			},
  2476  			ConverterFn: func() *automock.BundleConverter {
  2477  				conv := &automock.BundleConverter{}
  2478  				conv.On("MultipleToGraphQL", bundlesFirstApp).Return(gqlBundlesFirstApp, nil).Once()
  2479  				conv.On("MultipleToGraphQL", bundlesSecondApp).Return(gqlBundlesSecondApp, nil).Once()
  2480  				return conv
  2481  			},
  2482  			ExpectedResult: nil,
  2483  			ExpectedErr:    []error{testErr},
  2484  		},
  2485  	}
  2486  
  2487  	for _, testCase := range testCases {
  2488  		t.Run(testCase.Name, func(t *testing.T) {
  2489  			// GIVEN
  2490  			persist, transact := testCase.TransactionerFn()
  2491  			svc := testCase.ServiceFn()
  2492  			converter := testCase.ConverterFn()
  2493  
  2494  			resolver := application.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, svc, converter, nil, nil, nil, nil, "", "")
  2495  			firstAppParams := dataloader.ParamBundle{ID: firstAppID, Ctx: context.TODO(), First: &first, After: &gqlAfter}
  2496  			secondAppParams := dataloader.ParamBundle{ID: secondAppID, Ctx: context.TODO(), First: &first, After: &gqlAfter}
  2497  			keys := []dataloader.ParamBundle{firstAppParams, secondAppParams}
  2498  
  2499  			// WHEN
  2500  			result, err := resolver.BundlesDataLoader(keys)
  2501  
  2502  			// then
  2503  			assert.Equal(t, testCase.ExpectedResult, result)
  2504  			assert.Equal(t, testCase.ExpectedErr, err)
  2505  
  2506  			persist.AssertExpectations(t)
  2507  			transact.AssertExpectations(t)
  2508  			svc.AssertExpectations(t)
  2509  			converter.AssertExpectations(t)
  2510  		})
  2511  	}
  2512  
  2513  	t.Run("Returns error when there are no Applications", func(t *testing.T) {
  2514  		resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  2515  		// WHEN
  2516  		_, err := resolver.BundlesDataLoader([]dataloader.ParamBundle{})
  2517  		// THEN
  2518  		require.Error(t, err[0])
  2519  		assert.EqualError(t, err[0], apperrors.NewInternalError("No Applications found").Error())
  2520  	})
  2521  
  2522  	t.Run("Returns error when start cursor is nil", func(t *testing.T) {
  2523  		firstAppParams := dataloader.ParamBundle{ID: firstAppID, Ctx: context.TODO(), First: nil, After: &gqlAfter}
  2524  		keys := []dataloader.ParamBundle{firstAppParams}
  2525  
  2526  		resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  2527  		// WHEN
  2528  		_, err := resolver.BundlesDataLoader(keys)
  2529  		// THEN
  2530  		require.Error(t, err[0])
  2531  		assert.EqualError(t, err[0], apperrors.NewInvalidDataError("missing required parameter 'first'").Error())
  2532  	})
  2533  }
  2534  
  2535  func TestResolver_Bundle(t *testing.T) {
  2536  	// GIVEN
  2537  	id := "foo"
  2538  	appID := "bar"
  2539  	modelBundle := fixModelBundle(id, appID, "name", "bar")
  2540  	gqlBundle := fixGQLBundle(id, "name", "bar")
  2541  	app := fixGQLApplication("foo", "foo", "foo")
  2542  	testErr := errors.New("Test error")
  2543  	txGen := txtest.NewTransactionContextGenerator(testErr)
  2544  
  2545  	testCases := []struct {
  2546  		Name            string
  2547  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  2548  		ServiceFn       func() *automock.BundleService
  2549  		ConverterFn     func() *automock.BundleConverter
  2550  		InputID         string
  2551  		Application     *graphql.Application
  2552  		ExpectedBundle  *graphql.Bundle
  2553  		ExpectedErr     error
  2554  	}{
  2555  		{
  2556  			Name:            "Success",
  2557  			TransactionerFn: txGen.ThatSucceeds,
  2558  			ServiceFn: func() *automock.BundleService {
  2559  				svc := &automock.BundleService{}
  2560  				svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelBundle, nil).Once()
  2561  
  2562  				return svc
  2563  			},
  2564  			ConverterFn: func() *automock.BundleConverter {
  2565  				conv := &automock.BundleConverter{}
  2566  				conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once()
  2567  				return conv
  2568  			},
  2569  			InputID:        "foo",
  2570  			Application:    app,
  2571  			ExpectedBundle: gqlBundle,
  2572  			ExpectedErr:    nil,
  2573  		},
  2574  		{
  2575  			Name:            "Returns error when application retrieval failed",
  2576  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  2577  			ServiceFn: func() *automock.BundleService {
  2578  				svc := &automock.BundleService{}
  2579  				svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, testErr).Once()
  2580  
  2581  				return svc
  2582  			},
  2583  			ConverterFn: func() *automock.BundleConverter {
  2584  				conv := &automock.BundleConverter{}
  2585  				return conv
  2586  			},
  2587  			InputID:        "foo",
  2588  			Application:    app,
  2589  			ExpectedBundle: nil,
  2590  			ExpectedErr:    testErr,
  2591  		},
  2592  		{
  2593  			Name:            "Returns error when conversion to graphql fails",
  2594  			TransactionerFn: txGen.ThatDoesntExpectCommit,
  2595  			ServiceFn: func() *automock.BundleService {
  2596  				svc := &automock.BundleService{}
  2597  				svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelBundle, nil).Once()
  2598  				return svc
  2599  			},
  2600  			ConverterFn: func() *automock.BundleConverter {
  2601  				conv := &automock.BundleConverter{}
  2602  				conv.On("ToGraphQL", modelBundle).Return(nil, testErr).Once()
  2603  				return conv
  2604  			},
  2605  			InputID:        "foo",
  2606  			Application:    app,
  2607  			ExpectedBundle: nil,
  2608  			ExpectedErr:    testErr,
  2609  		},
  2610  		{
  2611  			Name:            "Returns nil when bundle for application not found",
  2612  			TransactionerFn: txGen.ThatSucceeds,
  2613  			ServiceFn: func() *automock.BundleService {
  2614  				svc := &automock.BundleService{}
  2615  				svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(nil, apperrors.NewNotFoundError(resource.Application, "")).Once()
  2616  
  2617  				return svc
  2618  			},
  2619  			ConverterFn: func() *automock.BundleConverter {
  2620  				conv := &automock.BundleConverter{}
  2621  				return conv
  2622  			},
  2623  			InputID:        "foo",
  2624  			Application:    app,
  2625  			ExpectedBundle: nil,
  2626  			ExpectedErr:    nil,
  2627  		},
  2628  		{
  2629  			Name:            "Returns error when commit begin error",
  2630  			TransactionerFn: txGen.ThatFailsOnBegin,
  2631  			ServiceFn: func() *automock.BundleService {
  2632  				svc := &automock.BundleService{}
  2633  
  2634  				return svc
  2635  			},
  2636  			ConverterFn: func() *automock.BundleConverter {
  2637  				conv := &automock.BundleConverter{}
  2638  				return conv
  2639  			},
  2640  			InputID:        "foo",
  2641  			Application:    app,
  2642  			ExpectedBundle: nil,
  2643  			ExpectedErr:    testErr,
  2644  		},
  2645  		{
  2646  			Name:            "Returns error when commit failed",
  2647  			TransactionerFn: txGen.ThatFailsOnCommit,
  2648  			ServiceFn: func() *automock.BundleService {
  2649  				svc := &automock.BundleService{}
  2650  				svc.On("GetForApplication", txtest.CtxWithDBMatcher(), "foo", "foo").Return(modelBundle, nil).Once()
  2651  				return svc
  2652  			},
  2653  			ConverterFn: func() *automock.BundleConverter {
  2654  				conv := &automock.BundleConverter{}
  2655  				conv.On("ToGraphQL", modelBundle).Return(gqlBundle, nil).Once()
  2656  				return conv
  2657  			},
  2658  			InputID:        "foo",
  2659  			Application:    app,
  2660  			ExpectedBundle: nil,
  2661  			ExpectedErr:    testErr,
  2662  		},
  2663  	}
  2664  
  2665  	for _, testCase := range testCases {
  2666  		t.Run(testCase.Name, func(t *testing.T) {
  2667  			persist, transact := testCase.TransactionerFn()
  2668  			svc := testCase.ServiceFn()
  2669  			converter := testCase.ConverterFn()
  2670  
  2671  			resolver := application.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, svc, converter, nil, nil, nil, nil, "", "")
  2672  
  2673  			// WHEN
  2674  			result, err := resolver.Bundle(context.TODO(), testCase.Application, testCase.InputID)
  2675  
  2676  			// then
  2677  			assert.Equal(t, testCase.ExpectedBundle, result)
  2678  			assert.Equal(t, testCase.ExpectedErr, err)
  2679  
  2680  			svc.AssertExpectations(t)
  2681  			persist.AssertExpectations(t)
  2682  			transact.AssertExpectations(t)
  2683  			converter.AssertExpectations(t)
  2684  		})
  2685  	}
  2686  
  2687  	t.Run("Returns error when application is nil", func(t *testing.T) {
  2688  		resolver := application.NewResolver(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "", "")
  2689  		// WHEN
  2690  		_, err := resolver.Bundle(context.TODO(), nil, "")
  2691  		// THEN
  2692  		require.Error(t, err)
  2693  		assert.EqualError(t, err, apperrors.NewInternalError("Application cannot be empty").Error())
  2694  	})
  2695  }
  2696  
  2697  func fixOAuths() []pkgmodel.SystemAuth {
  2698  	return []pkgmodel.SystemAuth{
  2699  		{
  2700  			ID:       "foo",
  2701  			TenantID: str.Ptr("foo"),
  2702  			Value: &model.Auth{
  2703  				Credential: model.CredentialData{
  2704  					Basic: nil,
  2705  					Oauth: &model.OAuthCredentialData{
  2706  						ClientID:     "foo",
  2707  						ClientSecret: "foo",
  2708  						URL:          "foo",
  2709  					},
  2710  				},
  2711  			},
  2712  		},
  2713  		{
  2714  			ID:       "bar",
  2715  			TenantID: str.Ptr("bar"),
  2716  			Value:    nil,
  2717  		},
  2718  		{
  2719  			ID:       "test",
  2720  			TenantID: str.Ptr("test"),
  2721  			Value: &model.Auth{
  2722  				Credential: model.CredentialData{
  2723  					Basic: &model.BasicCredentialData{
  2724  						Username: "test",
  2725  						Password: "test",
  2726  					},
  2727  					Oauth: nil,
  2728  				},
  2729  			},
  2730  		},
  2731  	}
  2732  }
  2733  
  2734  func TestResolver_ApplicationTemplate(t *testing.T) {
  2735  	// GIVEN
  2736  
  2737  	id := "foo"
  2738  	appTemplateID := "12345678-ae7e-4d1a-8027-520a96d5319d"
  2739  	appTemplateName := "app-template"
  2740  
  2741  	gqlApp := fixGQLApplication(id, "name", "desc")
  2742  	gqlAppWithAppTemplate := fixGQLApplicationWithAppTemplate(id, "name", "desc", appTemplateID)
  2743  	modelAppTemplate := fixModelApplicationTemplate(appTemplateID, appTemplateName)
  2744  	gqlAppTemplate := fixGQLApplicationTemplate(appTemplateID, appTemplateName)
  2745  
  2746  	testErr := errors.New("Test error")
  2747  
  2748  	testCases := []struct {
  2749  		Name            string
  2750  		PersistenceFn   func() *persistenceautomock.PersistenceTx
  2751  		TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
  2752  		ServiceFn       func() *automock.ApplicationTemplateService
  2753  		ConverterFn     func() *automock.ApplicationTemplateConverter
  2754  		Application     *graphql.Application
  2755  		ExpectedResult  *graphql.ApplicationTemplate
  2756  		ExpectedErr     error
  2757  	}{
  2758  		{
  2759  			Name:            "Success",
  2760  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  2761  			TransactionerFn: txtest.TransactionerThatSucceeds,
  2762  			ServiceFn: func() *automock.ApplicationTemplateService {
  2763  				svc := &automock.ApplicationTemplateService{}
  2764  				svc.On("Get", contextParam, appTemplateID).Return(modelAppTemplate, nil).Once()
  2765  				return svc
  2766  			},
  2767  			ConverterFn: func() *automock.ApplicationTemplateConverter {
  2768  				conv := &automock.ApplicationTemplateConverter{}
  2769  				conv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once()
  2770  				return conv
  2771  			},
  2772  			Application:    gqlAppWithAppTemplate,
  2773  			ExpectedResult: gqlAppTemplate,
  2774  			ExpectedErr:    nil,
  2775  		},
  2776  		{
  2777  			Name:            "Success when application does not contain app template",
  2778  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  2779  			TransactionerFn: txtest.NoopTransactioner,
  2780  			ServiceFn: func() *automock.ApplicationTemplateService {
  2781  				svc := &automock.ApplicationTemplateService{}
  2782  				svc.AssertNotCalled(t, "Get", contextParam, appTemplateID)
  2783  				return svc
  2784  			},
  2785  			ConverterFn: func() *automock.ApplicationTemplateConverter {
  2786  				conv := &automock.ApplicationTemplateConverter{}
  2787  				conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate)
  2788  				return conv
  2789  			},
  2790  			Application:    gqlApp,
  2791  			ExpectedResult: nil,
  2792  			ExpectedErr:    nil,
  2793  		},
  2794  		{
  2795  			Name:            "Returns error when application is empty",
  2796  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  2797  			TransactionerFn: txtest.NoopTransactioner,
  2798  			ServiceFn: func() *automock.ApplicationTemplateService {
  2799  				svc := &automock.ApplicationTemplateService{}
  2800  				svc.AssertNotCalled(t, "Get", contextParam, appTemplateID)
  2801  				return svc
  2802  			},
  2803  			ConverterFn: func() *automock.ApplicationTemplateConverter {
  2804  				conv := &automock.ApplicationTemplateConverter{}
  2805  				conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate)
  2806  				return conv
  2807  			},
  2808  			Application:    nil,
  2809  			ExpectedResult: nil,
  2810  			ExpectedErr:    apperrors.NewInternalError("Application cannot be empty"),
  2811  		},
  2812  		{
  2813  			Name:          "Returns error when transaction begin fails",
  2814  			PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit,
  2815  			TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner {
  2816  				transact := &persistenceautomock.Transactioner{}
  2817  				transact.On("Begin").Return(persistTx, testErr).Once()
  2818  				return transact
  2819  			},
  2820  			ServiceFn: func() *automock.ApplicationTemplateService {
  2821  				svc := &automock.ApplicationTemplateService{}
  2822  				svc.AssertNotCalled(t, "Get", contextParam, appTemplateID)
  2823  				return svc
  2824  			},
  2825  			ConverterFn: func() *automock.ApplicationTemplateConverter {
  2826  				conv := &automock.ApplicationTemplateConverter{}
  2827  				conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate)
  2828  				return conv
  2829  			},
  2830  			Application:    gqlAppWithAppTemplate,
  2831  			ExpectedResult: nil,
  2832  			ExpectedErr:    testErr,
  2833  		},
  2834  		{
  2835  			Name: "Returns error when transaction commit fails",
  2836  			PersistenceFn: func() *persistenceautomock.PersistenceTx {
  2837  				persistTx := &persistenceautomock.PersistenceTx{}
  2838  				persistTx.On("Commit").Return(testErr).Once()
  2839  				return persistTx
  2840  			},
  2841  			TransactionerFn: txtest.TransactionerThatSucceeds,
  2842  			ServiceFn: func() *automock.ApplicationTemplateService {
  2843  				svc := &automock.ApplicationTemplateService{}
  2844  				svc.On("Get", contextParam, appTemplateID).Return(modelAppTemplate, nil).Once()
  2845  				return svc
  2846  			},
  2847  			ConverterFn: func() *automock.ApplicationTemplateConverter {
  2848  				conv := &automock.ApplicationTemplateConverter{}
  2849  				conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate)
  2850  				return conv
  2851  			},
  2852  			Application:    gqlAppWithAppTemplate,
  2853  			ExpectedResult: nil,
  2854  			ExpectedErr:    testErr,
  2855  		},
  2856  		{
  2857  			Name:            "Returns error when app template is not found",
  2858  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  2859  			TransactionerFn: txtest.TransactionerThatDoesARollback,
  2860  			ServiceFn: func() *automock.ApplicationTemplateService {
  2861  				svc := &automock.ApplicationTemplateService{}
  2862  				svc.On("Get", contextParam, appTemplateID).Return(nil, testErr).Once()
  2863  				return svc
  2864  			},
  2865  			ConverterFn: func() *automock.ApplicationTemplateConverter {
  2866  				conv := &automock.ApplicationTemplateConverter{}
  2867  				conv.AssertNotCalled(t, "ToGraphQL", modelAppTemplate)
  2868  				return conv
  2869  			},
  2870  			Application:    gqlAppWithAppTemplate,
  2871  			ExpectedResult: nil,
  2872  			ExpectedErr:    errors.Wrapf(testErr, "no app template found with id %s", appTemplateID),
  2873  		},
  2874  	}
  2875  
  2876  	for _, testCase := range testCases {
  2877  		t.Run(testCase.Name, func(t *testing.T) {
  2878  			svc := testCase.ServiceFn()
  2879  			converter := testCase.ConverterFn()
  2880  			persistTx := testCase.PersistenceFn()
  2881  			transact := testCase.TransactionerFn(persistTx)
  2882  
  2883  			resolver := application.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, svc, converter, nil, nil, "", "")
  2884  			// WHEN
  2885  			result, err := resolver.ApplicationTemplate(context.TODO(), testCase.Application)
  2886  
  2887  			// then
  2888  			assert.Equal(t, testCase.ExpectedResult, result)
  2889  			if testCase.ExpectedErr != nil {
  2890  				assert.EqualError(t, testCase.ExpectedErr, err.Error())
  2891  			} else {
  2892  				assert.NoError(t, err)
  2893  			}
  2894  
  2895  			svc.AssertExpectations(t)
  2896  			converter.AssertExpectations(t)
  2897  			transact.AssertExpectations(t)
  2898  			persistTx.AssertExpectations(t)
  2899  		})
  2900  	}
  2901  }
  2902  
  2903  func TestResolver_TenantBusinessType(t *testing.T) {
  2904  	// GIVEN
  2905  
  2906  	id := "foo"
  2907  	//appTemplateName := "app-template"
  2908  
  2909  	gqlApp := fixGQLApplication(id, "name", "desc")
  2910  	gqlAppWithTbt := fixGQLApplicationWithTenantBusinessType(id, "name", "desc")
  2911  	gqlTbt := fixGQLTenantBusinessType(id, "test-code", "test-name")
  2912  	modelTbt := fixModelTenantBusinessType(tbtID, "test-code", "test-name")
  2913  	//gqlAppTemplate := fixGQLApplicationTemplate(appTemplateID, appTemplateName)
  2914  
  2915  	testErr := errors.New("Test error")
  2916  
  2917  	testCases := []struct {
  2918  		Name            string
  2919  		PersistenceFn   func() *persistenceautomock.PersistenceTx
  2920  		TransactionerFn func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
  2921  		ServiceFn       func() *automock.TenantBusinessTypeService
  2922  		ConverterFn     func() *automock.TenantBusinessTypeConverter
  2923  		Application     *graphql.Application
  2924  		ExpectedResult  *graphql.TenantBusinessType
  2925  		ExpectedErr     error
  2926  	}{
  2927  		{
  2928  			Name:            "Success",
  2929  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  2930  			TransactionerFn: txtest.TransactionerThatSucceeds,
  2931  			ServiceFn: func() *automock.TenantBusinessTypeService {
  2932  				svc := &automock.TenantBusinessTypeService{}
  2933  				svc.On("GetByID", contextParam, tbtID).Return(modelTbt, nil).Once()
  2934  				return svc
  2935  			},
  2936  			ConverterFn: func() *automock.TenantBusinessTypeConverter {
  2937  				conv := &automock.TenantBusinessTypeConverter{}
  2938  				conv.On("ToGraphQL", modelTbt).Return(gqlTbt, nil).Once()
  2939  				return conv
  2940  			},
  2941  			Application:    gqlAppWithTbt,
  2942  			ExpectedResult: gqlTbt,
  2943  			ExpectedErr:    nil,
  2944  		},
  2945  		{
  2946  			Name:            "Success when application does not contain tenant business type",
  2947  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  2948  			TransactionerFn: txtest.NoopTransactioner,
  2949  			ServiceFn: func() *automock.TenantBusinessTypeService {
  2950  				svc := &automock.TenantBusinessTypeService{}
  2951  				svc.AssertNotCalled(t, "GetByID", contextParam, tbtID)
  2952  				return svc
  2953  			},
  2954  			ConverterFn: func() *automock.TenantBusinessTypeConverter {
  2955  				conv := &automock.TenantBusinessTypeConverter{}
  2956  				conv.AssertNotCalled(t, "ToGraphQL", modelTbt)
  2957  				return conv
  2958  			},
  2959  			Application:    gqlApp,
  2960  			ExpectedResult: nil,
  2961  			ExpectedErr:    nil,
  2962  		},
  2963  		{
  2964  			Name:            "Returns error when application is empty",
  2965  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  2966  			TransactionerFn: txtest.NoopTransactioner,
  2967  			ServiceFn: func() *automock.TenantBusinessTypeService {
  2968  				svc := &automock.TenantBusinessTypeService{}
  2969  				svc.AssertNotCalled(t, "GetByID", contextParam, tbtID)
  2970  				return svc
  2971  			},
  2972  			ConverterFn: func() *automock.TenantBusinessTypeConverter {
  2973  				conv := &automock.TenantBusinessTypeConverter{}
  2974  				conv.AssertNotCalled(t, "ToGraphQL", modelTbt)
  2975  				return conv
  2976  			},
  2977  			Application:    nil,
  2978  			ExpectedResult: nil,
  2979  			ExpectedErr:    apperrors.NewInternalError("Application cannot be empty"),
  2980  		},
  2981  		{
  2982  			Name:          "Returns error when transaction begin fails",
  2983  			PersistenceFn: txtest.PersistenceContextThatDoesntExpectCommit,
  2984  			TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner {
  2985  				transact := &persistenceautomock.Transactioner{}
  2986  				transact.On("Begin").Return(persistTx, testErr).Once()
  2987  				return transact
  2988  			},
  2989  			ServiceFn: func() *automock.TenantBusinessTypeService {
  2990  				svc := &automock.TenantBusinessTypeService{}
  2991  				svc.AssertNotCalled(t, "GetByID", contextParam, tbtID)
  2992  				return svc
  2993  			},
  2994  			ConverterFn: func() *automock.TenantBusinessTypeConverter {
  2995  				conv := &automock.TenantBusinessTypeConverter{}
  2996  				conv.AssertNotCalled(t, "ToGraphQL", modelTbt)
  2997  				return conv
  2998  			},
  2999  			Application:    gqlAppWithTbt,
  3000  			ExpectedResult: nil,
  3001  			ExpectedErr:    testErr,
  3002  		},
  3003  		{
  3004  			Name: "Returns error when transaction commit fails",
  3005  			PersistenceFn: func() *persistenceautomock.PersistenceTx {
  3006  				persistTx := &persistenceautomock.PersistenceTx{}
  3007  				persistTx.On("Commit").Return(testErr).Once()
  3008  				return persistTx
  3009  			},
  3010  			TransactionerFn: txtest.TransactionerThatSucceeds,
  3011  			ServiceFn: func() *automock.TenantBusinessTypeService {
  3012  				svc := &automock.TenantBusinessTypeService{}
  3013  				svc.On("GetByID", contextParam, tbtID).Return(modelTbt, nil).Once()
  3014  				return svc
  3015  			},
  3016  			ConverterFn: func() *automock.TenantBusinessTypeConverter {
  3017  				conv := &automock.TenantBusinessTypeConverter{}
  3018  				conv.AssertNotCalled(t, "ToGraphQL", modelTbt)
  3019  				return conv
  3020  			},
  3021  			Application:    gqlAppWithTbt,
  3022  			ExpectedResult: nil,
  3023  			ExpectedErr:    testErr,
  3024  		},
  3025  		{
  3026  			Name:            "Returns error when tenant business type is not found",
  3027  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  3028  			TransactionerFn: txtest.TransactionerThatDoesARollback,
  3029  			ServiceFn: func() *automock.TenantBusinessTypeService {
  3030  				svc := &automock.TenantBusinessTypeService{}
  3031  				svc.On("GetByID", contextParam, tbtID).Return(nil, testErr).Once()
  3032  				return svc
  3033  			},
  3034  			ConverterFn: func() *automock.TenantBusinessTypeConverter {
  3035  				conv := &automock.TenantBusinessTypeConverter{}
  3036  				conv.AssertNotCalled(t, "ToGraphQL", modelTbt)
  3037  				return conv
  3038  			},
  3039  			Application:    gqlAppWithTbt,
  3040  			ExpectedResult: nil,
  3041  			ExpectedErr:    errors.Wrapf(testErr, "no tenant business type found with id %s", tbtID),
  3042  		},
  3043  	}
  3044  
  3045  	for _, testCase := range testCases {
  3046  		t.Run(testCase.Name, func(t *testing.T) {
  3047  			svc := testCase.ServiceFn()
  3048  			converter := testCase.ConverterFn()
  3049  			persistTx := testCase.PersistenceFn()
  3050  			transact := testCase.TransactionerFn(persistTx)
  3051  
  3052  			resolver := application.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, svc, converter, "", "")
  3053  			// WHEN
  3054  			result, err := resolver.TenantBusinessType(context.TODO(), testCase.Application)
  3055  
  3056  			// then
  3057  			assert.Equal(t, testCase.ExpectedResult, result)
  3058  			if testCase.ExpectedErr != nil {
  3059  				assert.EqualError(t, testCase.ExpectedErr, err.Error())
  3060  			} else {
  3061  				assert.NoError(t, err)
  3062  			}
  3063  
  3064  			svc.AssertExpectations(t)
  3065  			converter.AssertExpectations(t)
  3066  			transact.AssertExpectations(t)
  3067  			persistTx.AssertExpectations(t)
  3068  		})
  3069  	}
  3070  }