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

     1  package apptemplate_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"testing"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/internal/domain/scenarioassignment"
    10  
    11  	"github.com/kyma-incubator/compass/components/hydrator/pkg/oathkeeper"
    12  
    13  	"github.com/kyma-incubator/compass/components/director/internal/selfregmanager"
    14  
    15  	"github.com/kyma-incubator/compass/components/director/pkg/consumer"
    16  
    17  	"github.com/kyma-incubator/compass/components/director/internal/labelfilter"
    18  
    19  	"github.com/kyma-incubator/compass/components/director/internal/domain/apptemplate/apptmpltest"
    20  	"github.com/kyma-incubator/compass/components/director/pkg/str"
    21  	"github.com/stretchr/testify/mock"
    22  
    23  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
    24  
    25  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
    26  
    27  	"github.com/kyma-incubator/compass/components/director/internal/model"
    28  
    29  	"github.com/kyma-incubator/compass/components/director/internal/domain/apptemplate"
    30  	persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock"
    31  
    32  	"github.com/kyma-incubator/compass/components/director/internal/domain/apptemplate/automock"
    33  
    34  	"github.com/kyma-incubator/compass/components/director/internal/domain/tenant"
    35  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    36  	"github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest"
    37  	"github.com/stretchr/testify/assert"
    38  	"github.com/stretchr/testify/require"
    39  )
    40  
    41  const (
    42  	RegionKey               = "region"
    43  	AppTemplateProductLabel = "systemRole"
    44  )
    45  
    46  func TestResolver_ApplicationTemplate(t *testing.T) {
    47  	// GIVEN
    48  	ctx := tenant.SaveToContext(context.TODO(), testTenant, testExternalTenant)
    49  
    50  	txGen := txtest.NewTransactionContextGenerator(testError)
    51  
    52  	modelAppTemplate := fixModelApplicationTemplate(testID, testName, fixModelApplicationTemplateWebhooks(testWebhookID, testID))
    53  	gqlAppTemplate := fixGQLAppTemplate(testID, testName, fixGQLApplicationTemplateWebhooks(testWebhookID, testID))
    54  
    55  	testCases := []struct {
    56  		Name              string
    57  		TxFn              func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
    58  		AppTemplateSvcFn  func() *automock.ApplicationTemplateService
    59  		AppTemplateConvFn func() *automock.ApplicationTemplateConverter
    60  		WebhookSvcFn      func() *automock.WebhookService
    61  		WebhookConvFn     func() *automock.WebhookConverter
    62  		ExpectedOutput    *graphql.ApplicationTemplate
    63  		ExpectedError     error
    64  	}{
    65  		{
    66  			Name: "Success",
    67  			TxFn: txGen.ThatSucceeds,
    68  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
    69  				appTemplateSvc := &automock.ApplicationTemplateService{}
    70  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
    71  				return appTemplateSvc
    72  			},
    73  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
    74  				appTemplateConv := &automock.ApplicationTemplateConverter{}
    75  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once()
    76  				return appTemplateConv
    77  			},
    78  			WebhookConvFn:  UnusedWebhookConv,
    79  			WebhookSvcFn:   UnusedWebhookSvc,
    80  			ExpectedOutput: gqlAppTemplate,
    81  		},
    82  		{
    83  			Name: "Returns nil when application template not found",
    84  			TxFn: txGen.ThatSucceeds,
    85  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
    86  				appTemplateSvc := &automock.ApplicationTemplateService{}
    87  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, apperrors.NewNotFoundError(resource.ApplicationTemplate, "")).Once()
    88  				return appTemplateSvc
    89  			},
    90  			AppTemplateConvFn: UnusedAppTemplateConv,
    91  			WebhookConvFn:     UnusedWebhookConv,
    92  			WebhookSvcFn:      UnusedWebhookSvc,
    93  			ExpectedOutput:    nil,
    94  		},
    95  		{
    96  			Name: "Returns error when getting application template failed",
    97  			TxFn: txGen.ThatDoesntExpectCommit,
    98  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
    99  				appTemplateSvc := &automock.ApplicationTemplateService{}
   100  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testError).Once()
   101  				return appTemplateSvc
   102  			},
   103  			AppTemplateConvFn: UnusedAppTemplateConv,
   104  			WebhookConvFn:     UnusedWebhookConv,
   105  			WebhookSvcFn:      UnusedWebhookSvc,
   106  			ExpectedError:     testError,
   107  		},
   108  		{
   109  			Name:              "Returns error when beginning transaction",
   110  			TxFn:              txGen.ThatFailsOnBegin,
   111  			AppTemplateSvcFn:  UnusedAppTemplateSvc,
   112  			AppTemplateConvFn: UnusedAppTemplateConv,
   113  			WebhookConvFn:     UnusedWebhookConv,
   114  			WebhookSvcFn:      UnusedWebhookSvc,
   115  			ExpectedError:     testError,
   116  		},
   117  		{
   118  			Name: "Returns error when committing transaction",
   119  			TxFn: txGen.ThatFailsOnCommit,
   120  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   121  				appTemplateSvc := &automock.ApplicationTemplateService{}
   122  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
   123  				return appTemplateSvc
   124  			},
   125  			AppTemplateConvFn: UnusedAppTemplateConv,
   126  			WebhookConvFn:     UnusedWebhookConv,
   127  			WebhookSvcFn:      UnusedWebhookSvc,
   128  			ExpectedError:     testError,
   129  		},
   130  		{
   131  			Name: "Returns error when can't convert application template to graphql",
   132  			TxFn: txGen.ThatSucceeds,
   133  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   134  				appTemplateSvc := &automock.ApplicationTemplateService{}
   135  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
   136  				return appTemplateSvc
   137  			},
   138  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   139  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   140  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(nil, testError).Once()
   141  				return appTemplateConv
   142  			},
   143  			WebhookConvFn: UnusedWebhookConv,
   144  			WebhookSvcFn:  UnusedWebhookSvc,
   145  			ExpectedError: testError,
   146  		},
   147  	}
   148  
   149  	for _, testCase := range testCases {
   150  		t.Run(testCase.Name, func(t *testing.T) {
   151  			persist, transact := testCase.TxFn()
   152  			appTemplateSvc := testCase.AppTemplateSvcFn()
   153  			appTemplateConv := testCase.AppTemplateConvFn()
   154  			webhookSvc := testCase.WebhookSvcFn()
   155  			webhookConverter := testCase.WebhookConvFn()
   156  
   157  			resolver := apptemplate.NewResolver(transact, nil, nil, appTemplateSvc, appTemplateConv, webhookSvc, webhookConverter, nil, nil, "")
   158  
   159  			// WHEN
   160  			result, err := resolver.ApplicationTemplate(ctx, testID)
   161  
   162  			// THEN
   163  			if testCase.ExpectedError != nil {
   164  				require.Error(t, err)
   165  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
   166  			} else {
   167  				assert.NoError(t, err)
   168  			}
   169  			assert.Equal(t, testCase.ExpectedOutput, result)
   170  
   171  			persist.AssertExpectations(t)
   172  			transact.AssertExpectations(t)
   173  			appTemplateSvc.AssertExpectations(t)
   174  			appTemplateConv.AssertExpectations(t)
   175  		})
   176  	}
   177  }
   178  
   179  func TestResolver_ApplicationTemplates(t *testing.T) {
   180  	// GIVEN
   181  	ctx := tenant.SaveToContext(context.TODO(), testTenant, testExternalTenant)
   182  	txGen := txtest.NewTransactionContextGenerator(testError)
   183  	modelAppTemplates := []*model.ApplicationTemplate{
   184  		fixModelApplicationTemplate("i1", "n1", fixModelApplicationTemplateWebhooks("webhook-id-1", "i1")),
   185  		fixModelApplicationTemplate("i2", "n2", fixModelApplicationTemplateWebhooks("webhook-id-2", "i2")),
   186  	}
   187  	modelPage := fixModelAppTemplatePage(modelAppTemplates)
   188  	gqlAppTemplates := []*graphql.ApplicationTemplate{
   189  		fixGQLAppTemplate("i1", "n1", fixGQLApplicationTemplateWebhooks("webhook-id-1", "i1")),
   190  		fixGQLAppTemplate("i2", "n2", fixGQLApplicationTemplateWebhooks("webhook-id-2", "i2")),
   191  	}
   192  	gqlPage := fixGQLAppTemplatePage(gqlAppTemplates)
   193  	first := 2
   194  	after := "test"
   195  	gqlAfter := graphql.PageCursor(after)
   196  
   197  	labelFilters := []*labelfilter.LabelFilter{labelfilter.NewForKeyWithQuery(RegionKey, "eu-1")}
   198  	labelFiltersEmpty := []*labelfilter.LabelFilter{}
   199  	gqlFilter := []*graphql.LabelFilter{
   200  		{Key: RegionKey, Query: str.Ptr("eu-1")},
   201  	}
   202  
   203  	testCases := []struct {
   204  		Name              string
   205  		LabelFilter       []*graphql.LabelFilter
   206  		TxFn              func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   207  		AppTemplateSvcFn  func() *automock.ApplicationTemplateService
   208  		AppTemplateConvFn func() *automock.ApplicationTemplateConverter
   209  		WebhookSvcFn      func() *automock.WebhookService
   210  		WebhookConvFn     func() *automock.WebhookConverter
   211  		ExpectedOutput    *graphql.ApplicationTemplatePage
   212  		ExpectedError     error
   213  	}{
   214  		{
   215  			Name:        "Success",
   216  			LabelFilter: gqlFilter,
   217  			TxFn:        txGen.ThatSucceeds,
   218  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   219  				appTemplateSvc := &automock.ApplicationTemplateService{}
   220  				appTemplateSvc.On("List", txtest.CtxWithDBMatcher(), labelFilters, first, after).Return(modelPage, nil).Once()
   221  				return appTemplateSvc
   222  			},
   223  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   224  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   225  				appTemplateConv.On("MultipleToGraphQL", modelAppTemplates).Return(gqlAppTemplates, nil).Once()
   226  				return appTemplateConv
   227  			},
   228  			WebhookConvFn:  UnusedWebhookConv,
   229  			WebhookSvcFn:   UnusedWebhookSvc,
   230  			ExpectedOutput: &gqlPage,
   231  		},
   232  		{
   233  			Name: "Returns error when getting application templates failed",
   234  			TxFn: txGen.ThatDoesntExpectCommit,
   235  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   236  				appTemplateSvc := &automock.ApplicationTemplateService{}
   237  				appTemplateSvc.On("List", txtest.CtxWithDBMatcher(), labelFiltersEmpty, first, after).Return(model.ApplicationTemplatePage{}, testError).Once()
   238  				return appTemplateSvc
   239  			},
   240  			AppTemplateConvFn: UnusedAppTemplateConv,
   241  			WebhookConvFn:     UnusedWebhookConv,
   242  			WebhookSvcFn:      UnusedWebhookSvc,
   243  			ExpectedError:     testError,
   244  		},
   245  		{
   246  			Name:              "Returns error when beginning transaction",
   247  			TxFn:              txGen.ThatFailsOnBegin,
   248  			AppTemplateSvcFn:  UnusedAppTemplateSvc,
   249  			AppTemplateConvFn: UnusedAppTemplateConv,
   250  			WebhookConvFn:     UnusedWebhookConv,
   251  			WebhookSvcFn:      UnusedWebhookSvc,
   252  			ExpectedError:     testError,
   253  		},
   254  		{
   255  			Name: "Returns error when committing transaction",
   256  			TxFn: txGen.ThatFailsOnCommit,
   257  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   258  				appTemplateSvc := &automock.ApplicationTemplateService{}
   259  				appTemplateSvc.On("List", txtest.CtxWithDBMatcher(), labelFiltersEmpty, first, after).Return(modelPage, nil).Once()
   260  				return appTemplateSvc
   261  			},
   262  			AppTemplateConvFn: UnusedAppTemplateConv,
   263  			WebhookConvFn:     UnusedWebhookConv,
   264  			WebhookSvcFn:      UnusedWebhookSvc,
   265  			ExpectedError:     testError,
   266  		},
   267  		{
   268  			Name: "Returns error when can't convert at least one of application templates to graphql",
   269  			TxFn: txGen.ThatSucceeds,
   270  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   271  				appTemplateSvc := &automock.ApplicationTemplateService{}
   272  				appTemplateSvc.On("List", txtest.CtxWithDBMatcher(), labelFiltersEmpty, first, after).Return(modelPage, nil).Once()
   273  				return appTemplateSvc
   274  			},
   275  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   276  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   277  				appTemplateConv.On("MultipleToGraphQL", modelAppTemplates).Return(nil, testError).Once()
   278  				return appTemplateConv
   279  			},
   280  			WebhookConvFn: UnusedWebhookConv,
   281  			WebhookSvcFn:  UnusedWebhookSvc,
   282  			ExpectedError: testError,
   283  		},
   284  	}
   285  
   286  	for _, testCase := range testCases {
   287  		t.Run(testCase.Name, func(t *testing.T) {
   288  			persist, transact := testCase.TxFn()
   289  			appTemplateSvc := testCase.AppTemplateSvcFn()
   290  			appTemplateConv := testCase.AppTemplateConvFn()
   291  			webhookSvc := testCase.WebhookSvcFn()
   292  			webhookConverter := testCase.WebhookConvFn()
   293  
   294  			resolver := apptemplate.NewResolver(transact, nil, nil, appTemplateSvc, appTemplateConv, webhookSvc, webhookConverter, nil, nil, "")
   295  
   296  			// WHEN
   297  			result, err := resolver.ApplicationTemplates(ctx, testCase.LabelFilter, &first, &gqlAfter)
   298  
   299  			// THEN
   300  			if testCase.ExpectedError != nil {
   301  				require.Error(t, err)
   302  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
   303  			} else {
   304  				assert.NoError(t, err)
   305  			}
   306  			assert.Equal(t, testCase.ExpectedOutput, result)
   307  
   308  			persist.AssertExpectations(t)
   309  			transact.AssertExpectations(t)
   310  			appTemplateSvc.AssertExpectations(t)
   311  			appTemplateConv.AssertExpectations(t)
   312  		})
   313  	}
   314  }
   315  
   316  func TestResolver_Webhooks(t *testing.T) {
   317  	// GIVEN
   318  	applicationTemplateID := "fooid"
   319  	modelWebhooks := fixModelApplicationTemplateWebhooks("test-webhook-1", applicationTemplateID)
   320  	gqlWebhooks := fixGQLApplicationTemplateWebhooks("test-webhook-1", applicationTemplateID)
   321  
   322  	appTemplate := fixGQLAppTemplate(applicationTemplateID, "foo", gqlWebhooks)
   323  	testErr := errors.New("Test error")
   324  
   325  	testCases := []struct {
   326  		Name               string
   327  		PersistenceFn      func() *persistenceautomock.PersistenceTx
   328  		TransactionerFn    func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
   329  		WebhookServiceFn   func() *automock.WebhookService
   330  		WebhookConverterFn func() *automock.WebhookConverter
   331  		ExpectedResult     []*graphql.Webhook
   332  		ExpectedErr        error
   333  	}{
   334  		{
   335  			Name:            "Success",
   336  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
   337  			TransactionerFn: txtest.TransactionerThatSucceeds,
   338  			WebhookServiceFn: func() *automock.WebhookService {
   339  				svc := &automock.WebhookService{}
   340  				svc.On("ListForApplicationTemplate", txtest.CtxWithDBMatcher(), applicationTemplateID).Return(modelWebhooks, nil).Once()
   341  				return svc
   342  			},
   343  			WebhookConverterFn: func() *automock.WebhookConverter {
   344  				conv := &automock.WebhookConverter{}
   345  				conv.On("MultipleToGraphQL", modelWebhooks).Return(gqlWebhooks, nil).Once()
   346  				return conv
   347  			},
   348  			ExpectedResult: gqlWebhooks,
   349  			ExpectedErr:    nil,
   350  		},
   351  		{
   352  			Name:            "Returns error when webhook listing failed",
   353  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
   354  			TransactionerFn: txtest.TransactionerThatSucceeds,
   355  			WebhookServiceFn: func() *automock.WebhookService {
   356  				svc := &automock.WebhookService{}
   357  				svc.On("ListForApplicationTemplate", txtest.CtxWithDBMatcher(), applicationTemplateID).Return(nil, testErr).Once()
   358  				return svc
   359  			},
   360  			WebhookConverterFn: func() *automock.WebhookConverter {
   361  				return &automock.WebhookConverter{}
   362  			},
   363  			ExpectedResult: nil,
   364  			ExpectedErr:    testErr,
   365  		},
   366  		{
   367  			Name: "Returns error on starting transaction",
   368  			TransactionerFn: func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner {
   369  				transact := &persistenceautomock.Transactioner{}
   370  				transact.On("Begin").Return(nil, testErr).Once()
   371  				return transact
   372  			},
   373  			PersistenceFn:      txtest.PersistenceContextThatDoesntExpectCommit,
   374  			WebhookServiceFn:   UnusedWebhookSvc,
   375  			WebhookConverterFn: UnusedWebhookConv,
   376  			ExpectedErr:        testErr,
   377  		},
   378  		{
   379  			Name: "Returns error on committing transaction",
   380  			PersistenceFn: func() *persistenceautomock.PersistenceTx {
   381  				persistTx := &persistenceautomock.PersistenceTx{}
   382  				persistTx.On("Commit").Return(testErr).Once()
   383  				return persistTx
   384  			},
   385  			TransactionerFn: txtest.TransactionerThatSucceeds,
   386  			WebhookServiceFn: func() *automock.WebhookService {
   387  				svc := &automock.WebhookService{}
   388  				svc.On("ListForApplicationTemplate", txtest.CtxWithDBMatcher(), applicationTemplateID).Return(modelWebhooks, nil).Once()
   389  				return svc
   390  			},
   391  			WebhookConverterFn: UnusedWebhookConv,
   392  			ExpectedErr:        testErr,
   393  		},
   394  	}
   395  
   396  	for _, testCase := range testCases {
   397  		t.Run(testCase.Name, func(t *testing.T) {
   398  			webhookSvc := testCase.WebhookServiceFn()
   399  			converter := testCase.WebhookConverterFn()
   400  
   401  			mockPersistence := testCase.PersistenceFn()
   402  			mockTransactioner := testCase.TransactionerFn(mockPersistence)
   403  
   404  			resolver := apptemplate.NewResolver(mockTransactioner, nil, nil, nil, nil, webhookSvc, converter, nil, nil, "")
   405  
   406  			// WHEN
   407  			result, err := resolver.Webhooks(context.TODO(), appTemplate)
   408  
   409  			// then
   410  			assert.Equal(t, testCase.ExpectedResult, result)
   411  			assert.Equal(t, testCase.ExpectedErr, err)
   412  
   413  			webhookSvc.AssertExpectations(t)
   414  			converter.AssertExpectations(t)
   415  			mockPersistence.AssertExpectations(t)
   416  			mockTransactioner.AssertExpectations(t)
   417  		})
   418  	}
   419  }
   420  
   421  func TestResolver_CreateApplicationTemplate(t *testing.T) {
   422  	// GIVEN
   423  	tokenConsumer := consumer.Consumer{
   424  		ConsumerID: testTenant,
   425  		Flow:       oathkeeper.OAuth2Flow,
   426  		Region:     "region",
   427  	}
   428  	certConsumer := consumer.Consumer{
   429  		ConsumerID: testTenant,
   430  		Flow:       oathkeeper.CertificateFlow,
   431  		Region:     "region",
   432  	}
   433  
   434  	ctx := tenant.SaveToContext(context.TODO(), testTenant, testExternalTenant)
   435  	ctxWithCertConsumer := consumer.SaveToContext(ctx, certConsumer)
   436  	ctxWithTokenConsumer := consumer.SaveToContext(ctx, tokenConsumer)
   437  
   438  	txGen := txtest.NewTransactionContextGenerator(testError)
   439  
   440  	uidSvcFn := func() *automock.UIDService {
   441  		uidSvc := &automock.UIDService{}
   442  		uidSvc.On("Generate").Return(testUUID)
   443  		return uidSvc
   444  	}
   445  
   446  	modelAppTemplate := fixModelApplicationTemplate(testID, testName, fixModelApplicationWebhooks(testWebhookID, testID))
   447  	modelAppTemplateInput := fixModelAppTemplateInput(testName, appInputJSONString)
   448  	modelAppTemplateInput.ID = &testUUID
   449  	gqlAppTemplate := fixGQLAppTemplate(testID, testName, fixGQLApplicationTemplateWebhooks(testWebhookID, testID))
   450  	gqlAppTemplateInput := fixGQLAppTemplateInputWithPlaceholder(testName)
   451  	gqlAppTemplateInputWithProvider := fixGQLAppTemplateInputWithPlaceholderAndProvider("SAP " + testName)
   452  
   453  	modelAppTemplateInputWithSelRegLabels := fixModelAppTemplateInput(testName, appInputJSONString)
   454  	modelAppTemplateInputWithSelRegLabels.ID = &testUUID
   455  	modelAppTemplateInputWithSelRegLabels.Labels = graphql.Labels{
   456  		apptmpltest.TestDistinguishLabel: "selfRegVal",
   457  		selfregmanager.RegionLabel:       "region",
   458  	}
   459  
   460  	modelAppTemplateInputWithProductLabels := fixModelAppTemplateInput(testName, appInputJSONString)
   461  	modelAppTemplateInputWithProductLabels.ID = &testUUID
   462  	modelAppTemplateInputWithProductLabels.Labels = graphql.Labels{
   463  		AppTemplateProductLabel:    "role",
   464  		selfregmanager.RegionLabel: "region",
   465  	}
   466  
   467  	modelAppTemplateInputWithProductAndSelfRegLabels := fixModelAppTemplateInput(testName, appInputJSONString)
   468  	modelAppTemplateInputWithProductAndSelfRegLabels.ID = &testUUID
   469  	modelAppTemplateInputWithProductAndSelfRegLabels.Labels = graphql.Labels{
   470  		AppTemplateProductLabel:          "role",
   471  		selfregmanager.RegionLabel:       "region",
   472  		apptmpltest.TestDistinguishLabel: "selfRegVal",
   473  	}
   474  
   475  	gqlAppTemplateWithSelfRegLabels := fixGQLAppTemplate(testID, testName, fixGQLApplicationTemplateWebhooks(testWebhookID, testID))
   476  	gqlAppTemplateWithSelfRegLabels.Labels = graphql.Labels{
   477  		apptmpltest.TestDistinguishLabel: "selfRegVal",
   478  		selfregmanager.RegionLabel:       "region",
   479  	}
   480  	gqlAppTemplateInputWithSelfRegLabels := fixGQLAppTemplateInputWithPlaceholder(testName)
   481  	gqlAppTemplateInputWithSelfRegLabels.Labels = graphql.Labels{
   482  		apptmpltest.TestDistinguishLabel: "selfRegVal",
   483  		selfregmanager.RegionLabel:       "region",
   484  	}
   485  	gqlAppTemplateInputWithProductLabels := fixGQLAppTemplateInputWithPlaceholder(testName)
   486  	gqlAppTemplateInputWithProductLabels.Labels = graphql.Labels{
   487  		AppTemplateProductLabel:    "role",
   488  		selfregmanager.RegionLabel: "region",
   489  	}
   490  
   491  	syncMode := graphql.WebhookModeSync
   492  	asyncCallbackMode := graphql.WebhookModeAsyncCallback
   493  
   494  	gqlAppTemplateInputWithProviderAndWebhook := fixGQLAppTemplateInputWithPlaceholderAndProvider("SAP " + testName)
   495  	gqlAppTemplateInputWithProviderAndWebhook.Webhooks = []*graphql.WebhookInput{
   496  		{
   497  			Type:    graphql.WebhookTypeConfigurationChanged,
   498  			URL:     &testURL,
   499  			Auth:    nil,
   500  			Mode:    &syncMode,
   501  			Version: str.Ptr("v1.0"),
   502  		},
   503  		{
   504  			Type: graphql.WebhookTypeOpenResourceDiscovery,
   505  			URL:  &testURL,
   506  			Auth: nil,
   507  		},
   508  	}
   509  	gqlAppTemplateInputWithProviderAndWebhookWithAsyncCallback := fixGQLAppTemplateInputWithPlaceholderAndProvider("SAP " + testName)
   510  	gqlAppTemplateInputWithProviderAndWebhookWithAsyncCallback.Webhooks = []*graphql.WebhookInput{
   511  		{
   512  			Type:    graphql.WebhookTypeConfigurationChanged,
   513  			URL:     &testURL,
   514  			Auth:    nil,
   515  			Mode:    &asyncCallbackMode,
   516  			Version: str.Ptr("v1.0"),
   517  		},
   518  		{
   519  			Type: graphql.WebhookTypeOpenResourceDiscovery,
   520  			URL:  &testURL,
   521  			Auth: nil,
   522  		},
   523  	}
   524  
   525  	labelsContainingSelfRegistrationAndInvaidRegion := map[string]interface{}{apptmpltest.TestDistinguishLabel: "selfRegVal", RegionKey: 1}
   526  	labelsContainingSelfRegistration := map[string]interface{}{apptmpltest.TestDistinguishLabel: "selfRegVal", RegionKey: "region"}
   527  	labelsContainingSelfRegAndSubaccount := map[string]interface{}{
   528  		apptmpltest.TestDistinguishLabel:   "selfRegVal",
   529  		RegionKey:                          "region",
   530  		scenarioassignment.SubaccountIDKey: testTenant,
   531  	}
   532  	distinguishLabel := map[string]interface{}{apptmpltest.TestDistinguishLabel: "selfRegVal"}
   533  	regionLabel := map[string]interface{}{RegionKey: "region"}
   534  
   535  	getAppTemplateFiltersForSelfReg := []*labelfilter.LabelFilter{
   536  		labelfilter.NewForKeyWithQuery(apptmpltest.TestDistinguishLabel, fmt.Sprintf("\"%s\"", "selfRegVal")),
   537  		labelfilter.NewForKeyWithQuery(selfregmanager.RegionLabel, fmt.Sprintf("\"%s\"", "region")),
   538  	}
   539  
   540  	getAppTemplateFiltersForProduct := []*labelfilter.LabelFilter{
   541  		labelfilter.NewForKeyWithQuery(AppTemplateProductLabel, fmt.Sprintf("\"%s\"", "role")),
   542  		labelfilter.NewForKeyWithQuery(selfregmanager.RegionLabel, fmt.Sprintf("\"%s\"", "region")),
   543  	}
   544  
   545  	testCases := []struct {
   546  		Name              string
   547  		TxFn              func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   548  		AppTemplateSvcFn  func() *automock.ApplicationTemplateService
   549  		AppTemplateConvFn func() *automock.ApplicationTemplateConverter
   550  		WebhookSvcFn      func() *automock.WebhookService
   551  		WebhookConvFn     func() *automock.WebhookConverter
   552  		SelfRegManagerFn  func() *automock.SelfRegisterManager
   553  		Ctx               context.Context
   554  		Input             *graphql.ApplicationTemplateInput
   555  		ExpectedOutput    *graphql.ApplicationTemplate
   556  		ExpectedError     error
   557  	}{
   558  		{
   559  			Name: "Success - no self reg flow",
   560  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
   561  				persistTx := &persistenceautomock.PersistenceTx{}
   562  				persistTx.On("Commit").Return(nil).Once()
   563  
   564  				transact := &persistenceautomock.Transactioner{}
   565  				transact.On("Begin").Return(persistTx, nil).Once()
   566  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false)
   567  
   568  				return persistTx, transact
   569  			},
   570  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   571  				appTemplateSvc := &automock.ApplicationTemplateService{}
   572  				appTemplateSvc.On("CreateWithLabels", txtest.CtxWithDBMatcher(), *modelAppTemplateInput, modelAppTemplateInput.Labels).Return(modelAppTemplate.ID, nil).Once()
   573  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
   574  				return appTemplateSvc
   575  			},
   576  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   577  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   578  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInputWithProvider).Return(*modelAppTemplateInput, nil).Once()
   579  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once()
   580  				return appTemplateConv
   581  			},
   582  			WebhookConvFn:    UnusedWebhookConv,
   583  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInputWithProvider.Webhooks, gqlAppTemplateInputWithProvider.Webhooks),
   584  			SelfRegManagerFn: apptmpltest.SelfRegManagerOnlyGetDistinguishedLabelKey(),
   585  			Ctx:              ctxWithTokenConsumer,
   586  			Input:            gqlAppTemplateInputWithProvider,
   587  			ExpectedOutput:   gqlAppTemplate,
   588  		},
   589  		{
   590  			Name: "Success with tenant mapping configuration",
   591  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
   592  				persistTx := &persistenceautomock.PersistenceTx{}
   593  				persistTx.On("Commit").Return(nil).Once()
   594  
   595  				transact := &persistenceautomock.Transactioner{}
   596  				transact.On("Begin").Return(persistTx, nil).Once()
   597  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false)
   598  
   599  				return persistTx, transact
   600  			},
   601  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   602  				appTemplateSvc := &automock.ApplicationTemplateService{}
   603  				appTemplateSvc.On("CreateWithLabels", txtest.CtxWithDBMatcher(), *modelAppTemplateInput, modelAppTemplateInput.Labels).Return(modelAppTemplate.ID, nil).Once()
   604  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
   605  				return appTemplateSvc
   606  			},
   607  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   608  				expectedGqlAppTemplateInputWithProviderAndWebhook := fixGQLAppTemplateInputWithPlaceholderAndProvider("SAP " + testName)
   609  				expectedGqlAppTemplateInputWithProviderAndWebhook.Webhooks = fixEnrichedTenantMappedWebhooks()
   610  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   611  				appTemplateConv.On("InputFromGraphQL", *expectedGqlAppTemplateInputWithProviderAndWebhook).Return(*modelAppTemplateInput, nil).Once()
   612  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once()
   613  				return appTemplateConv
   614  			},
   615  			WebhookConvFn:    UnusedWebhookConv,
   616  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInputWithProviderAndWebhook.Webhooks, fixEnrichedTenantMappedWebhooks()),
   617  			SelfRegManagerFn: apptmpltest.SelfRegManagerOnlyGetDistinguishedLabelKey(),
   618  			Ctx:              ctxWithTokenConsumer,
   619  			Input:            gqlAppTemplateInputWithProviderAndWebhook,
   620  			ExpectedOutput:   gqlAppTemplate,
   621  		},
   622  		{
   623  			Name: "Success when self registered app template still does not exists",
   624  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
   625  				persistTx := &persistenceautomock.PersistenceTx{}
   626  				persistTx.On("Commit").Return(nil).Once()
   627  
   628  				transact := &persistenceautomock.Transactioner{}
   629  				transact.On("Begin").Return(persistTx, nil).Once()
   630  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false)
   631  
   632  				return persistTx, transact
   633  			},
   634  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   635  				appTemplateSvc := &automock.ApplicationTemplateService{}
   636  				appTemplateSvc.On("CreateWithLabels", txtest.CtxWithDBMatcher(), *modelAppTemplateInputWithSelRegLabels, labelsContainingSelfRegistration).Return(modelAppTemplate.ID, nil).Once()
   637  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
   638  				appTemplateSvc.On("GetByFilters", txtest.CtxWithDBMatcher(), getAppTemplateFiltersForSelfReg).Return(nil, nil).Once()
   639  				return appTemplateSvc
   640  			},
   641  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   642  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   643  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInputWithSelfRegLabels).Return(*modelAppTemplateInputWithSelRegLabels, nil).Once()
   644  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplateWithSelfRegLabels, nil).Once()
   645  				return appTemplateConv
   646  			},
   647  			WebhookConvFn:    UnusedWebhookConv,
   648  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInputWithSelfRegLabels.Webhooks, gqlAppTemplateInputWithSelfRegLabels.Webhooks),
   649  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesNotCleanupFunc(labelsContainingSelfRegistration),
   650  			Ctx:              ctxWithCertConsumer,
   651  			Input:            gqlAppTemplateInputWithSelfRegLabels,
   652  			ExpectedOutput:   gqlAppTemplateWithSelfRegLabels,
   653  		},
   654  		{
   655  			Name: "Error when self registered app template already exists for the given self reg labels",
   656  			TxFn: txGen.ThatDoesntExpectCommit,
   657  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   658  				appTemplateSvc := &automock.ApplicationTemplateService{}
   659  				appTemplateSvc.AssertNotCalled(t, "CreateWithLabels")
   660  				appTemplateSvc.AssertNotCalled(t, "Get")
   661  				appTemplateSvc.On("GetByFilters", txtest.CtxWithDBMatcher(), getAppTemplateFiltersForSelfReg).Return(modelAppTemplate, nil).Once()
   662  				return appTemplateSvc
   663  			},
   664  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   665  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   666  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInputWithSelfRegLabels).Return(*modelAppTemplateInputWithSelRegLabels, nil).Once()
   667  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   668  				return appTemplateConv
   669  			},
   670  			WebhookConvFn:    UnusedWebhookConv,
   671  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInputWithSelfRegLabels.Webhooks, gqlAppTemplateInputWithSelfRegLabels.Webhooks),
   672  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesCleanup(labelsContainingSelfRegistration),
   673  			Input:            gqlAppTemplateInputWithSelfRegLabels,
   674  			Ctx:              ctxWithCertConsumer,
   675  			ExpectedError:    errors.New("Cannot have more than one application template with labels \"test-distinguish-label\": \"selfRegVal\" and \"region\": \"region\""),
   676  		},
   677  		{
   678  			Name: "Error when app template already exists for the given product labels",
   679  			TxFn: txGen.ThatDoesntExpectCommit,
   680  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   681  				appTemplateSvc := &automock.ApplicationTemplateService{}
   682  				appTemplateSvc.AssertNotCalled(t, "CreateWithLabels")
   683  				appTemplateSvc.AssertNotCalled(t, "Get")
   684  				appTemplateSvc.On("GetByFilters", txtest.CtxWithDBMatcher(), getAppTemplateFiltersForProduct).Return(modelAppTemplate, nil).Once()
   685  				return appTemplateSvc
   686  			},
   687  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   688  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   689  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInputWithProductLabels).Return(*modelAppTemplateInputWithProductLabels, nil).Once()
   690  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   691  				return appTemplateConv
   692  			},
   693  			WebhookConvFn:    UnusedWebhookConv,
   694  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInputWithProductLabels.Webhooks, gqlAppTemplateInputWithProductLabels.Webhooks),
   695  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatInitiatesCleanupButNotFinishIt(),
   696  			Ctx:              ctxWithCertConsumer,
   697  			Input:            gqlAppTemplateInputWithProductLabels,
   698  			ExpectedError:    errors.New("Cannot have more than one application template with labels \"systemRole\": \"role\" and \"region\": \"region\""),
   699  		},
   700  		{
   701  			Name: "Error when checking if self registered app template already exists for the given labels",
   702  			TxFn: txGen.ThatDoesntExpectCommit,
   703  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   704  				appTemplateSvc := &automock.ApplicationTemplateService{}
   705  				appTemplateSvc.AssertNotCalled(t, "CreateWithLabels")
   706  				appTemplateSvc.AssertNotCalled(t, "Get")
   707  				appTemplateSvc.On("GetByFilters", txtest.CtxWithDBMatcher(), getAppTemplateFiltersForSelfReg).Return(nil, testError).Once()
   708  				return appTemplateSvc
   709  			},
   710  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   711  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   712  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInputWithSelfRegLabels).Return(*modelAppTemplateInputWithSelRegLabels, nil).Once()
   713  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   714  				return appTemplateConv
   715  			},
   716  			WebhookConvFn:    UnusedWebhookConv,
   717  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInputWithSelfRegLabels.Webhooks, gqlAppTemplateInputWithSelfRegLabels.Webhooks),
   718  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesCleanup(labelsContainingSelfRegistration),
   719  			Ctx:              ctxWithCertConsumer,
   720  			Input:            gqlAppTemplateInputWithSelfRegLabels,
   721  			ExpectedError:    testError,
   722  		},
   723  		{
   724  			Name: "Returns error when can't convert input from graphql",
   725  			TxFn: txGen.ThatDoesntStartTransaction,
   726  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   727  				appTemplateSvc := &automock.ApplicationTemplateService{}
   728  				appTemplateSvc.AssertNotCalled(t, "CreateWithLabels")
   729  				appTemplateSvc.AssertNotCalled(t, "Get")
   730  				appTemplateSvc.AssertNotCalled(t, "GetByFilters")
   731  				return appTemplateSvc
   732  			},
   733  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   734  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   735  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(model.ApplicationTemplateInput{}, testError).Once()
   736  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   737  				return appTemplateConv
   738  			},
   739  			WebhookConvFn:    UnusedWebhookConv,
   740  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   741  			SelfRegManagerFn: apptmpltest.NoopSelfRegManager,
   742  			Ctx:              ctxWithTokenConsumer,
   743  			Input:            gqlAppTemplateInput,
   744  			ExpectedError:    testError,
   745  		},
   746  		{
   747  			Name: "Returns error when loading consumer info",
   748  			TxFn: txGen.ThatDoesntStartTransaction,
   749  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   750  				appTemplateSvc := &automock.ApplicationTemplateService{}
   751  				appTemplateSvc.AssertNotCalled(t, "CreateWithLabels")
   752  				appTemplateSvc.AssertNotCalled(t, "Get")
   753  				appTemplateSvc.AssertNotCalled(t, "GetByFilters")
   754  				return appTemplateSvc
   755  			},
   756  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   757  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   758  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInput, nil).Once()
   759  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   760  				return appTemplateConv
   761  			},
   762  			WebhookConvFn:    UnusedWebhookConv,
   763  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   764  			SelfRegManagerFn: apptmpltest.NoopSelfRegManager,
   765  			Ctx:              context.Background(),
   766  			Input:            gqlAppTemplateInput,
   767  			ExpectedError:    errors.New("while loading consumer"),
   768  		},
   769  		{
   770  			Name: "Returns error when flow is cert and self reg label and product label are present",
   771  			TxFn: txGen.ThatDoesntStartTransaction,
   772  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   773  				return &automock.ApplicationTemplateService{}
   774  			},
   775  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   776  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   777  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInputWithProductAndSelfRegLabels, nil).Once()
   778  				return appTemplateConv
   779  			},
   780  			WebhookConvFn:    UnusedWebhookConv,
   781  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   782  			SelfRegManagerFn: apptmpltest.SelfRegManagerOnlyGetDistinguishedLabelKey(),
   783  			Ctx:              ctxWithCertConsumer,
   784  			Input:            gqlAppTemplateInput,
   785  			ExpectedError:    fmt.Errorf("should provide either %q or %q label", apptmpltest.TestDistinguishLabel, AppTemplateProductLabel),
   786  		},
   787  		{
   788  			Name: "Returns error when flow is cert and self reg label or product label is not present",
   789  			TxFn: txGen.ThatDoesntStartTransaction,
   790  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   791  				return &automock.ApplicationTemplateService{}
   792  			},
   793  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   794  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   795  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInput, nil).Once()
   796  				return appTemplateConv
   797  			},
   798  			WebhookConvFn:    UnusedWebhookConv,
   799  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   800  			SelfRegManagerFn: apptmpltest.SelfRegManagerOnlyGetDistinguishedLabelKey(),
   801  			Ctx:              ctxWithCertConsumer,
   802  			Input:            gqlAppTemplateInput,
   803  			ExpectedError:    fmt.Errorf("missing %q or %q label", apptmpltest.TestDistinguishLabel, AppTemplateProductLabel),
   804  		},
   805  		{
   806  			Name: "Returns error when creating application template failed",
   807  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
   808  				persistTx := &persistenceautomock.PersistenceTx{}
   809  				persistTx.AssertNotCalled(t, "Commit")
   810  
   811  				transact := &persistenceautomock.Transactioner{}
   812  				transact.On("Begin").Return(persistTx, nil).Once()
   813  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
   814  
   815  				return persistTx, transact
   816  			},
   817  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   818  				appTemplateSvc := &automock.ApplicationTemplateService{}
   819  				appTemplateSvc.On("CreateWithLabels", txtest.CtxWithDBMatcher(), *modelAppTemplateInput, modelAppTemplateInput.Labels).Return("", testError).Once()
   820  				appTemplateSvc.AssertNotCalled(t, "Get")
   821  				return appTemplateSvc
   822  			},
   823  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   824  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   825  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInput, nil).Once()
   826  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   827  				return appTemplateConv
   828  			},
   829  			WebhookConvFn:    UnusedWebhookConv,
   830  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   831  			SelfRegManagerFn: apptmpltest.SelfRegManagerOnlyGetDistinguishedLabelKey(),
   832  			Ctx:              ctxWithTokenConsumer,
   833  			Input:            gqlAppTemplateInput,
   834  			ExpectedError:    testError,
   835  		},
   836  		{
   837  			Name: "Returns error when getting application template failed",
   838  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
   839  				persistTx := &persistenceautomock.PersistenceTx{}
   840  				persistTx.AssertNotCalled(t, "Commit")
   841  
   842  				transact := &persistenceautomock.Transactioner{}
   843  				transact.On("Begin").Return(persistTx, nil).Once()
   844  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
   845  
   846  				return persistTx, transact
   847  			},
   848  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   849  				appTemplateSvc := &automock.ApplicationTemplateService{}
   850  				appTemplateSvc.On("CreateWithLabels", txtest.CtxWithDBMatcher(), *modelAppTemplateInput, modelAppTemplateInput.Labels).Return(modelAppTemplate.ID, nil).Once()
   851  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testError).Once()
   852  				return appTemplateSvc
   853  			},
   854  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   855  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   856  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInput, nil).Once()
   857  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   858  				return appTemplateConv
   859  			},
   860  			WebhookConvFn:    UnusedWebhookConv,
   861  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   862  			SelfRegManagerFn: apptmpltest.SelfRegManagerOnlyGetDistinguishedLabelKey(),
   863  			Input:            gqlAppTemplateInput,
   864  			Ctx:              ctxWithTokenConsumer,
   865  			ExpectedError:    testError,
   866  		},
   867  		{
   868  			Name: "Returns error when beginning transaction",
   869  			TxFn: txGen.ThatFailsOnBegin,
   870  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   871  				appTemplateSvc := &automock.ApplicationTemplateService{}
   872  				appTemplateSvc.AssertNotCalled(t, "CreateWithLabels")
   873  				appTemplateSvc.AssertNotCalled(t, "Get")
   874  				return appTemplateSvc
   875  			},
   876  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   877  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   878  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInput, nil).Once()
   879  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   880  				return appTemplateConv
   881  			},
   882  			WebhookConvFn:    UnusedWebhookConv,
   883  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   884  			Input:            gqlAppTemplateInput,
   885  			SelfRegManagerFn: apptmpltest.NoopSelfRegManager,
   886  			Ctx:              ctxWithTokenConsumer,
   887  			ExpectedError:    testError,
   888  		},
   889  		{
   890  			Name: "Returns error when committing transaction",
   891  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
   892  				persistTx := &persistenceautomock.PersistenceTx{}
   893  				persistTx.On("Commit").Return(testError).Once()
   894  
   895  				transact := &persistenceautomock.Transactioner{}
   896  				transact.On("Begin").Return(persistTx, nil).Once()
   897  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
   898  
   899  				return persistTx, transact
   900  			},
   901  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   902  				appTemplateSvc := &automock.ApplicationTemplateService{}
   903  				appTemplateSvc.On("CreateWithLabels", txtest.CtxWithDBMatcher(), *modelAppTemplateInput, modelAppTemplateInput.Labels).Return(modelAppTemplate.ID, nil).Once()
   904  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
   905  				return appTemplateSvc
   906  			},
   907  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   908  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   909  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInput, nil).Once()
   910  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   911  				return appTemplateConv
   912  			},
   913  			WebhookConvFn:    UnusedWebhookConv,
   914  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   915  			SelfRegManagerFn: apptmpltest.SelfRegManagerOnlyGetDistinguishedLabelKey(),
   916  			Ctx:              ctxWithTokenConsumer,
   917  			Input:            gqlAppTemplateInput,
   918  			ExpectedError:    testError,
   919  		},
   920  		{
   921  			Name: "Returns error when can't convert application template to graphql",
   922  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
   923  				persistTx := &persistenceautomock.PersistenceTx{}
   924  				persistTx.On("Commit").Return(nil).Once()
   925  
   926  				transact := &persistenceautomock.Transactioner{}
   927  				transact.On("Begin").Return(persistTx, nil).Once()
   928  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
   929  
   930  				return persistTx, transact
   931  			},
   932  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   933  				appTemplateSvc := &automock.ApplicationTemplateService{}
   934  				appTemplateSvc.On("CreateWithLabels", txtest.CtxWithDBMatcher(), *modelAppTemplateInput, modelAppTemplateInput.Labels).Return(modelAppTemplate.ID, nil).Once()
   935  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
   936  				return appTemplateSvc
   937  			},
   938  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   939  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   940  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInput, nil).Once()
   941  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(nil, testError).Once()
   942  				return appTemplateConv
   943  			},
   944  			WebhookConvFn:    UnusedWebhookConv,
   945  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   946  			SelfRegManagerFn: apptmpltest.SelfRegManagerOnlyGetDistinguishedLabelKey(),
   947  			Input:            gqlAppTemplateInput,
   948  			Ctx:              ctxWithTokenConsumer,
   949  			ExpectedError:    testError,
   950  		},
   951  		{
   952  			Name: "Success when labels are nil after converting gql AppTemplateInput",
   953  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
   954  				persistTx := &persistenceautomock.PersistenceTx{}
   955  				persistTx.On("Commit").Return(nil).Once()
   956  
   957  				transact := &persistenceautomock.Transactioner{}
   958  				transact.On("Begin").Return(persistTx, nil).Once()
   959  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
   960  
   961  				return persistTx, transact
   962  			},
   963  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   964  				appTemplateSvc := &automock.ApplicationTemplateService{}
   965  				modelAppTemplateInput.Labels = map[string]interface{}{}
   966  				appTemplateSvc.On("CreateWithLabels", txtest.CtxWithDBMatcher(), *modelAppTemplateInput, modelAppTemplateInput.Labels).Return(modelAppTemplate.ID, nil).Once()
   967  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
   968  				return appTemplateSvc
   969  			},
   970  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   971  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   972  				modelAppTemplateInput.Labels = nil
   973  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInput, nil).Once()
   974  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once()
   975  				return appTemplateConv
   976  			},
   977  			WebhookConvFn:    UnusedWebhookConv,
   978  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
   979  			SelfRegManagerFn: apptmpltest.SelfRegManagerOnlyGetDistinguishedLabelKey(),
   980  			Ctx:              ctxWithTokenConsumer,
   981  			Input:            gqlAppTemplateInput,
   982  			ExpectedOutput:   gqlAppTemplate,
   983  		},
   984  		{
   985  			Name: "Returns error when app template self registration fails",
   986  			TxFn: txGen.ThatDoesntStartTransaction,
   987  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
   988  				appTemplateSvc := &automock.ApplicationTemplateService{}
   989  				appTemplateSvc.AssertNotCalled(t, "CreateWithLabels")
   990  				appTemplateSvc.AssertNotCalled(t, "Get")
   991  				return appTemplateSvc
   992  			},
   993  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
   994  				appTemplateConv := &automock.ApplicationTemplateConverter{}
   995  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInputWithSelRegLabels, nil).Once()
   996  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
   997  				return appTemplateConv
   998  			},
   999  			WebhookConvFn:    UnusedWebhookConv,
  1000  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
  1001  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatReturnsErrorOnPrep,
  1002  			Input:            gqlAppTemplateInput,
  1003  			Ctx:              ctxWithCertConsumer,
  1004  			ExpectedError:    errors.New(apptmpltest.SelfRegErrorMsg),
  1005  		},
  1006  		{
  1007  			Name: "Returns error when self registered app template fails on create",
  1008  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  1009  				persistTx := &persistenceautomock.PersistenceTx{}
  1010  				persistTx.AssertNotCalled(t, "Commit")
  1011  
  1012  				transact := &persistenceautomock.Transactioner{}
  1013  				transact.On("Begin").Return(persistTx, nil).Once()
  1014  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(true).Once()
  1015  
  1016  				return persistTx, transact
  1017  			},
  1018  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1019  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1020  				modelAppTemplateInput.Labels = distinguishLabel
  1021  				appTemplateSvc.On("GetByFilters", txtest.CtxWithDBMatcher(), getAppTemplateFiltersForSelfReg).Return(nil, nil).Once()
  1022  				appTemplateSvc.On("CreateWithLabels", txtest.CtxWithDBMatcher(), *modelAppTemplateInput, labelsContainingSelfRegAndSubaccount).Return("", testError).Once()
  1023  				appTemplateSvc.AssertNotCalled(t, "Get")
  1024  				return appTemplateSvc
  1025  			},
  1026  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1027  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1028  				gqlAppTemplateInput.Labels = regionLabel
  1029  				modelAppTemplateInput.Labels = distinguishLabel
  1030  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInput, nil).Once()
  1031  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  1032  				return appTemplateConv
  1033  			},
  1034  			WebhookConvFn:    UnusedWebhookConv,
  1035  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
  1036  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesCleanup(labelsContainingSelfRegistration),
  1037  			Ctx:              ctxWithCertConsumer,
  1038  			Input:            gqlAppTemplateInput,
  1039  			ExpectedError:    testError,
  1040  		},
  1041  		{
  1042  			Name: "Error when couldn't cast region label value to string",
  1043  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  1044  				persistTx := &persistenceautomock.PersistenceTx{}
  1045  				transact := &persistenceautomock.Transactioner{}
  1046  				transact.On("Begin").Return(persistTx, nil).Once()
  1047  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(true).Once()
  1048  
  1049  				return persistTx, transact
  1050  			},
  1051  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1052  				return &automock.ApplicationTemplateService{}
  1053  			},
  1054  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1055  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1056  				appTemplateConv.On("InputFromGraphQL", *gqlAppTemplateInput).Return(*modelAppTemplateInputWithSelRegLabels, nil).Once()
  1057  				//appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once()
  1058  				return appTemplateConv
  1059  			},
  1060  			WebhookConvFn:    UnusedWebhookConv,
  1061  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateInput.Webhooks, gqlAppTemplateInput.Webhooks),
  1062  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesPrepAndInitiatesCleanupButNotFinishIt(labelsContainingSelfRegistrationAndInvaidRegion),
  1063  			Ctx:              ctxWithCertConsumer,
  1064  			Input:            gqlAppTemplateInput,
  1065  			ExpectedError:    errors.New("region label should be string"),
  1066  		},
  1067  		{
  1068  			Name:              "Returns error when validating app template name",
  1069  			TxFn:              txGen.ThatDoesntStartTransaction,
  1070  			AppTemplateSvcFn:  UnusedAppTemplateSvc,
  1071  			AppTemplateConvFn: UnusedAppTemplateConv,
  1072  			WebhookConvFn:     UnusedWebhookConv,
  1073  			WebhookSvcFn:      UnusedWebhookSvc,
  1074  			SelfRegManagerFn:  UnusedSelfRegManager,
  1075  			Input:             fixGQLAppTemplateInputWithPlaceholderAndProvider(testName),
  1076  			ExpectedError:     errors.New("application template name \"bar\" does not comply with the following naming convention: \"SAP <product name>\""),
  1077  		},
  1078  	}
  1079  
  1080  	for _, testCase := range testCases {
  1081  		t.Run(testCase.Name, func(t *testing.T) {
  1082  			persist, transact := testCase.TxFn()
  1083  			appTemplateSvc := testCase.AppTemplateSvcFn()
  1084  			appTemplateConv := testCase.AppTemplateConvFn()
  1085  			webhookSvc := testCase.WebhookSvcFn()
  1086  			webhookConverter := testCase.WebhookConvFn()
  1087  			selfRegManager := testCase.SelfRegManagerFn()
  1088  			uuidSvc := uidSvcFn()
  1089  			ctx := ctxWithCertConsumer
  1090  
  1091  			if testCase.Ctx != nil {
  1092  				ctx = testCase.Ctx
  1093  			}
  1094  
  1095  			resolver := apptemplate.NewResolver(transact, nil, nil, appTemplateSvc, appTemplateConv, webhookSvc, webhookConverter, selfRegManager, uuidSvc, AppTemplateProductLabel)
  1096  
  1097  			// WHEN
  1098  			result, err := resolver.CreateApplicationTemplate(ctx, *testCase.Input)
  1099  
  1100  			// THEN
  1101  			if testCase.ExpectedError != nil {
  1102  				require.Error(t, err)
  1103  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
  1104  			} else {
  1105  				assert.NoError(t, err)
  1106  			}
  1107  			assert.Equal(t, testCase.ExpectedOutput, result)
  1108  
  1109  			persist.AssertExpectations(t)
  1110  			transact.AssertExpectations(t)
  1111  			appTemplateSvc.AssertExpectations(t)
  1112  			appTemplateConv.AssertExpectations(t)
  1113  			selfRegManager.AssertExpectations(t)
  1114  		})
  1115  	}
  1116  	t.Run("Returns error when application template inputs url template has invalid method", func(t *testing.T) {
  1117  		gqlAppTemplateInputInvalid := fixGQLAppTemplateInputInvalidAppInputURLTemplateMethod(testName)
  1118  		expectedError := errors.New("failed to parse webhook url template")
  1119  		_, transact := txGen.ThatSucceeds()
  1120  
  1121  		resolver := apptemplate.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, "")
  1122  
  1123  		// WHEN
  1124  		_, err := resolver.CreateApplicationTemplate(ctxWithCertConsumer, *gqlAppTemplateInputInvalid)
  1125  
  1126  		// THEN
  1127  		require.Error(t, err)
  1128  		assert.Contains(t, err.Error(), expectedError.Error())
  1129  	})
  1130  }
  1131  
  1132  func TestResolver_Labels(t *testing.T) {
  1133  	// GIVEN
  1134  
  1135  	id := "foo"
  1136  	tenant := "tenant"
  1137  	labelKey1 := "key1"
  1138  	labelValue1 := "val1"
  1139  	labelKey2 := "key2"
  1140  	labelValue2 := "val2"
  1141  
  1142  	gqlAppTemplate := fixGQLAppTemplate(testID, testName, fixGQLApplicationTemplateWebhooks(testWebhookID, testID))
  1143  
  1144  	modelLabels := map[string]*model.Label{
  1145  		"abc": {
  1146  			ID:         "abc",
  1147  			Tenant:     str.Ptr(tenant),
  1148  			Key:        labelKey1,
  1149  			Value:      labelValue1,
  1150  			ObjectID:   id,
  1151  			ObjectType: model.AppTemplateLabelableObject,
  1152  		},
  1153  		"def": {
  1154  			ID:         "def",
  1155  			Tenant:     str.Ptr(tenant),
  1156  			Key:        labelKey2,
  1157  			Value:      labelValue2,
  1158  			ObjectID:   id,
  1159  			ObjectType: model.AppTemplateLabelableObject,
  1160  		},
  1161  	}
  1162  
  1163  	gqlLabels := graphql.Labels{
  1164  		labelKey1: labelValue1,
  1165  		labelKey2: labelValue2,
  1166  	}
  1167  
  1168  	gqlLabels1 := graphql.Labels{
  1169  		labelKey1: labelValue1,
  1170  	}
  1171  
  1172  	testErr := errors.New("Test error")
  1173  
  1174  	testCases := []struct {
  1175  		Name             string
  1176  		PersistenceFn    func() *persistenceautomock.PersistenceTx
  1177  		TransactionerFn  func(persistTx *persistenceautomock.PersistenceTx) *persistenceautomock.Transactioner
  1178  		AppTemplateSvcFn func() *automock.ApplicationTemplateService
  1179  		InputKey         *string
  1180  		ExpectedResult   graphql.Labels
  1181  		ExpectedErr      error
  1182  	}{
  1183  		{
  1184  			Name:            "Success",
  1185  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1186  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1187  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1188  				svc := &automock.ApplicationTemplateService{}
  1189  				svc.On("ListLabels", txtest.CtxWithDBMatcher(), id).Return(modelLabels, nil).Once()
  1190  				return svc
  1191  			},
  1192  			InputKey:       nil,
  1193  			ExpectedResult: gqlLabels,
  1194  			ExpectedErr:    nil,
  1195  		},
  1196  		{
  1197  			Name:            "Success when labels are filtered",
  1198  			PersistenceFn:   txtest.PersistenceContextThatExpectsCommit,
  1199  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1200  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1201  				svc := &automock.ApplicationTemplateService{}
  1202  				svc.On("ListLabels", txtest.CtxWithDBMatcher(), id).Return(modelLabels, nil).Once()
  1203  				return svc
  1204  			},
  1205  			InputKey:       &labelKey1,
  1206  			ExpectedResult: gqlLabels1,
  1207  			ExpectedErr:    nil,
  1208  		},
  1209  		{
  1210  			Name:            "Returns error when label listing failed",
  1211  			PersistenceFn:   txtest.PersistenceContextThatDoesntExpectCommit,
  1212  			TransactionerFn: txtest.TransactionerThatSucceeds,
  1213  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1214  				svc := &automock.ApplicationTemplateService{}
  1215  				svc.On("ListLabels", txtest.CtxWithDBMatcher(), id).Return(nil, testErr).Once()
  1216  				return svc
  1217  			},
  1218  			InputKey:       &labelKey1,
  1219  			ExpectedResult: nil,
  1220  			ExpectedErr:    testErr,
  1221  		},
  1222  	}
  1223  
  1224  	for _, testCase := range testCases {
  1225  		t.Run(testCase.Name, func(t *testing.T) {
  1226  			persistTx := testCase.PersistenceFn()
  1227  			transact := testCase.TransactionerFn(persistTx)
  1228  
  1229  			//persist, transact := testCase.TxFn()
  1230  			appTemplateSvc := testCase.AppTemplateSvcFn()
  1231  
  1232  			resolver := apptemplate.NewResolver(transact, nil, nil, appTemplateSvc, nil, nil, nil, nil, nil, "")
  1233  
  1234  			// WHEN
  1235  			result, err := resolver.Labels(context.TODO(), gqlAppTemplate, testCase.InputKey)
  1236  
  1237  			// then
  1238  			assert.Equal(t, testCase.ExpectedResult, result)
  1239  			assert.Equal(t, testCase.ExpectedErr, err)
  1240  
  1241  			appTemplateSvc.AssertExpectations(t)
  1242  			transact.AssertExpectations(t)
  1243  			persistTx.AssertExpectations(t)
  1244  		})
  1245  	}
  1246  }
  1247  
  1248  func TestResolver_RegisterApplicationFromTemplate(t *testing.T) {
  1249  	// GIVEN
  1250  	ctx := tenant.SaveToContext(context.TODO(), testTenant, testExternalTenant)
  1251  	ctx = consumer.SaveToContext(ctx, consumer.Consumer{ConsumerID: testConsumerID})
  1252  
  1253  	txGen := txtest.NewTransactionContextGenerator(testError)
  1254  
  1255  	globalSubaccountIDLabelKey := "global_subaccount_id"
  1256  	filters := []*labelfilter.LabelFilter{
  1257  		labelfilter.NewForKeyWithQuery(globalSubaccountIDLabelKey, fmt.Sprintf("\"%s\"", "consumer-id")),
  1258  	}
  1259  
  1260  	jsonAppCreateInput := fixJSONApplicationCreateInput(testName)
  1261  	modelAppCreateInput := fixModelApplicationCreateInput(testName)
  1262  	modelAppWithLabelCreateInput := fixModelApplicationWithLabelCreateInput(testName)
  1263  	gqlAppCreateInput := fixGQLApplicationCreateInput(testName)
  1264  
  1265  	customID := "customTemplateID"
  1266  	modelAppTemplate := fixModelAppTemplateWithAppInputJSON(testID, testName, jsonAppCreateInput, fixModelApplicationTemplateWebhooks(testWebhookID, testID))
  1267  	modelAppTemplateCustomID := fixModelAppTemplateWithAppInputJSON(customID, testName, jsonAppCreateInput, fixModelApplicationTemplateWebhooks(testWebhookID, customID))
  1268  
  1269  	modelApplication := fixModelApplication(testID, testName)
  1270  	gqlApplication := fixGQLApplication(testID, testName)
  1271  
  1272  	gqlAppFromTemplateInput := fixGQLApplicationFromTemplateInput(testName)
  1273  	gqlAppFromTemplateWithIDInput := fixGQLApplicationFromTemplateInput(testName)
  1274  	gqlAppFromTemplateWithIDInput.ID = &customID
  1275  	modelAppFromTemplateInput := fixModelApplicationFromTemplateInput(testName)
  1276  	modelAppFromTemplateWithIDInput := fixModelApplicationFromTemplateInput(testName)
  1277  	modelAppFromTemplateWithIDInput.ID = &customID
  1278  
  1279  	testCases := []struct {
  1280  		Name                 string
  1281  		AppFromTemplateInput graphql.ApplicationFromTemplateInput
  1282  		TxFn                 func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  1283  		AppTemplateSvcFn     func() *automock.ApplicationTemplateService
  1284  		AppTemplateConvFn    func() *automock.ApplicationTemplateConverter
  1285  		WebhookSvcFn         func() *automock.WebhookService
  1286  		WebhookConvFn        func() *automock.WebhookConverter
  1287  		AppSvcFn             func() *automock.ApplicationService
  1288  		AppConvFn            func() *automock.ApplicationConverter
  1289  		ExpectedOutput       *graphql.Application
  1290  		ExpectedError        error
  1291  	}{
  1292  		{
  1293  			Name:                 "Success",
  1294  			TxFn:                 txGen.ThatSucceeds,
  1295  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1296  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1297  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1298  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{}, nil).Once()
  1299  				appTemplateSvc.On("ListByName", txtest.CtxWithDBMatcher(), testName).Return([]*model.ApplicationTemplate{modelAppTemplate}, nil).Once()
  1300  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, globalSubaccountIDLabelKey).Return(nil, apperrors.NewNotFoundError(resource.Label, "id")).Once()
  1301  				appTemplateSvc.On("PrepareApplicationCreateInputJSON", modelAppTemplate, modelAppFromTemplateInput.Values).Return(jsonAppCreateInput, nil).Once()
  1302  				return appTemplateSvc
  1303  			},
  1304  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1305  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1306  				appTemplateConv.On("ApplicationFromTemplateInputFromGraphQL", modelAppTemplate, gqlAppFromTemplateInput).Return(modelAppFromTemplateInput, nil).Once()
  1307  				return appTemplateConv
  1308  			},
  1309  			AppSvcFn: func() *automock.ApplicationService {
  1310  				appSvc := &automock.ApplicationService{}
  1311  				appSvc.On("CreateFromTemplate", txtest.CtxWithDBMatcher(), modelAppWithLabelCreateInput, str.Ptr(testID)).Return(testID, nil).Once()
  1312  				appSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&modelApplication, nil).Once()
  1313  				return appSvc
  1314  			},
  1315  			AppConvFn: func() *automock.ApplicationConverter {
  1316  				appConv := &automock.ApplicationConverter{}
  1317  				appConv.On("CreateRegisterInputJSONToGQL", jsonAppCreateInput).Return(gqlAppCreateInput, nil).Once()
  1318  				appConv.On("CreateInputFromGraphQL", mock.Anything, gqlAppCreateInput).Return(modelAppCreateInput, nil).Once()
  1319  				appConv.On("ToGraphQL", &modelApplication).Return(&gqlApplication).Once()
  1320  				return appConv
  1321  			},
  1322  			WebhookConvFn:  UnusedWebhookConv,
  1323  			WebhookSvcFn:   UnusedWebhookSvc,
  1324  			ExpectedOutput: &gqlApplication,
  1325  			ExpectedError:  nil,
  1326  		},
  1327  		{
  1328  			Name:                 "SuccessWithIDField",
  1329  			AppFromTemplateInput: gqlAppFromTemplateWithIDInput,
  1330  			TxFn:                 txGen.ThatSucceeds,
  1331  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1332  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1333  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{}, nil).Once()
  1334  				appTemplateSvc.On("ListByName", txtest.CtxWithDBMatcher(), testName).Return([]*model.ApplicationTemplate{modelAppTemplate, modelAppTemplateCustomID}, nil).Once()
  1335  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), customID, globalSubaccountIDLabelKey).Return(nil, apperrors.NewNotFoundError(resource.Label, "id")).Once()
  1336  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, globalSubaccountIDLabelKey).Return(nil, apperrors.NewNotFoundError(resource.Label, "id")).Once()
  1337  				appTemplateSvc.On("PrepareApplicationCreateInputJSON", modelAppTemplateCustomID, modelAppFromTemplateWithIDInput.Values).Return(jsonAppCreateInput, nil).Once()
  1338  				return appTemplateSvc
  1339  			},
  1340  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1341  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1342  				appTemplateConv.On("ApplicationFromTemplateInputFromGraphQL", modelAppTemplateCustomID, gqlAppFromTemplateWithIDInput).Return(modelAppFromTemplateWithIDInput, nil).Once()
  1343  				return appTemplateConv
  1344  			},
  1345  			AppSvcFn: func() *automock.ApplicationService {
  1346  				appSvc := &automock.ApplicationService{}
  1347  				appSvc.On("CreateFromTemplate", txtest.CtxWithDBMatcher(), modelAppWithLabelCreateInput, str.Ptr(customID)).Return(testID, nil).Once()
  1348  				appSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&modelApplication, nil).Once()
  1349  				return appSvc
  1350  			},
  1351  			AppConvFn: func() *automock.ApplicationConverter {
  1352  				appConv := &automock.ApplicationConverter{}
  1353  				appConv.On("CreateRegisterInputJSONToGQL", jsonAppCreateInput).Return(gqlAppCreateInput, nil).Once()
  1354  				appConv.On("CreateInputFromGraphQL", mock.Anything, gqlAppCreateInput).Return(modelAppWithLabelCreateInput, nil).Once()
  1355  				appConv.On("ToGraphQL", &modelApplication).Return(&gqlApplication).Once()
  1356  				return appConv
  1357  			},
  1358  			WebhookConvFn:  UnusedWebhookConv,
  1359  			WebhookSvcFn:   UnusedWebhookSvc,
  1360  			ExpectedOutput: &gqlApplication,
  1361  			ExpectedError:  nil,
  1362  		},
  1363  		{
  1364  			Name:                 "Returns error when transaction begin fails",
  1365  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1366  			TxFn:                 txGen.ThatFailsOnBegin,
  1367  			AppTemplateSvcFn:     UnusedAppTemplateSvc,
  1368  			AppTemplateConvFn:    UnusedAppTemplateConv,
  1369  			AppSvcFn:             UnusedAppSvc,
  1370  			AppConvFn:            UnusedAppConv,
  1371  			WebhookConvFn:        UnusedWebhookConv,
  1372  			WebhookSvcFn:         UnusedWebhookSvc,
  1373  			ExpectedOutput:       nil,
  1374  			ExpectedError:        testError,
  1375  		},
  1376  		{
  1377  			Name:                 "Returns error when list application templates by filters fails",
  1378  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1379  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1380  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1381  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1382  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return(nil, testError).Once()
  1383  				return appTemplateSvc
  1384  			},
  1385  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1386  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1387  				return appTemplateConv
  1388  			},
  1389  			AppSvcFn:       UnusedAppSvc,
  1390  			AppConvFn:      UnusedAppConv,
  1391  			WebhookConvFn:  UnusedWebhookConv,
  1392  			WebhookSvcFn:   UnusedWebhookSvc,
  1393  			ExpectedOutput: nil,
  1394  			ExpectedError:  testError,
  1395  		},
  1396  		{
  1397  			Name:                 "Returns error when list application templates by name fails",
  1398  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1399  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1400  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1401  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1402  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{}, nil).Once()
  1403  				appTemplateSvc.On("ListByName", txtest.CtxWithDBMatcher(), testName).Return(nil, testError).Once()
  1404  				return appTemplateSvc
  1405  			},
  1406  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1407  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1408  				return appTemplateConv
  1409  			},
  1410  			AppSvcFn:       UnusedAppSvc,
  1411  			AppConvFn:      UnusedAppConv,
  1412  			WebhookConvFn:  UnusedWebhookConv,
  1413  			WebhookSvcFn:   UnusedWebhookSvc,
  1414  			ExpectedOutput: nil,
  1415  			ExpectedError:  testError,
  1416  		},
  1417  		{
  1418  			Name:                 "Returns error when get application template label fails",
  1419  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1420  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1421  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1422  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1423  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{}, nil).Once()
  1424  				appTemplateSvc.On("ListByName", txtest.CtxWithDBMatcher(), testName).Return([]*model.ApplicationTemplate{modelAppTemplate}, nil).Once()
  1425  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, globalSubaccountIDLabelKey).Return(nil, testError).Once()
  1426  				return appTemplateSvc
  1427  			},
  1428  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1429  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1430  				return appTemplateConv
  1431  			},
  1432  			AppSvcFn:       UnusedAppSvc,
  1433  			AppConvFn:      UnusedAppConv,
  1434  			WebhookConvFn:  UnusedWebhookConv,
  1435  			WebhookSvcFn:   UnusedWebhookSvc,
  1436  			ExpectedOutput: nil,
  1437  			ExpectedError:  testError,
  1438  		},
  1439  		{
  1440  			Name:                 "Returns error when list application templates by name cannot find application template",
  1441  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1442  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1443  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1444  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1445  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{}, nil).Once()
  1446  				appTemplateSvc.On("ListByName", txtest.CtxWithDBMatcher(), testName).Return([]*model.ApplicationTemplate{}, nil).Once()
  1447  				return appTemplateSvc
  1448  			},
  1449  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1450  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1451  				return appTemplateConv
  1452  			},
  1453  			AppSvcFn:       UnusedAppSvc,
  1454  			AppConvFn:      UnusedAppConv,
  1455  			WebhookConvFn:  UnusedWebhookConv,
  1456  			WebhookSvcFn:   UnusedWebhookSvc,
  1457  			ExpectedOutput: nil,
  1458  			ExpectedError:  errors.New("application template with name \"bar\" and consumer id \"consumer-id\" not found"),
  1459  		},
  1460  		{
  1461  			Name:                 "Returns error when list application templates by name return more than one application template",
  1462  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1463  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1464  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1465  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1466  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{}, nil).Once()
  1467  				appTemplateSvc.On("ListByName", txtest.CtxWithDBMatcher(), testName).Return([]*model.ApplicationTemplate{modelAppTemplate, modelAppTemplate}, nil).Once()
  1468  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, globalSubaccountIDLabelKey).Return(nil, apperrors.NewNotFoundError(resource.Label, "id")).Twice()
  1469  				return appTemplateSvc
  1470  			},
  1471  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1472  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1473  				return appTemplateConv
  1474  			},
  1475  			AppSvcFn:       UnusedAppSvc,
  1476  			AppConvFn:      UnusedAppConv,
  1477  			WebhookConvFn:  UnusedWebhookConv,
  1478  			WebhookSvcFn:   UnusedWebhookSvc,
  1479  			ExpectedOutput: nil,
  1480  			ExpectedError:  errors.New("unexpected number of application templates. found 2"),
  1481  		},
  1482  		{
  1483  			Name:                 "Returns error when preparing ApplicationCreateInputJSON fails",
  1484  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1485  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1486  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1487  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1488  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{modelAppTemplate}, nil).Once()
  1489  				appTemplateSvc.On("PrepareApplicationCreateInputJSON", modelAppTemplate, modelAppFromTemplateInput.Values).Return("", testError).Once()
  1490  				return appTemplateSvc
  1491  			},
  1492  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1493  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1494  				appTemplateConv.On("ApplicationFromTemplateInputFromGraphQL", modelAppTemplate, gqlAppFromTemplateInput).Return(modelAppFromTemplateInput, nil).Once()
  1495  				return appTemplateConv
  1496  			},
  1497  			AppSvcFn:       UnusedAppSvc,
  1498  			AppConvFn:      UnusedAppConv,
  1499  			WebhookConvFn:  UnusedWebhookConv,
  1500  			WebhookSvcFn:   UnusedWebhookSvc,
  1501  			ExpectedOutput: nil,
  1502  			ExpectedError:  testError,
  1503  		},
  1504  		{
  1505  			Name:                 "Returns error when CreateRegisterInputJSONToGQL fails",
  1506  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1507  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1508  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1509  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1510  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{modelAppTemplate}, nil).Once()
  1511  				appTemplateSvc.On("PrepareApplicationCreateInputJSON", modelAppTemplate, modelAppFromTemplateInput.Values).Return(jsonAppCreateInput, nil).Once()
  1512  				return appTemplateSvc
  1513  			},
  1514  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1515  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1516  				appTemplateConv.On("ApplicationFromTemplateInputFromGraphQL", modelAppTemplate, gqlAppFromTemplateInput).Return(modelAppFromTemplateInput, nil).Once()
  1517  				return appTemplateConv
  1518  			},
  1519  			AppSvcFn: UnusedAppSvc,
  1520  			AppConvFn: func() *automock.ApplicationConverter {
  1521  				appConv := &automock.ApplicationConverter{}
  1522  				appConv.On("CreateRegisterInputJSONToGQL", jsonAppCreateInput).Return(graphql.ApplicationRegisterInput{}, testError).Once()
  1523  				return appConv
  1524  			},
  1525  			WebhookConvFn:  UnusedWebhookConv,
  1526  			WebhookSvcFn:   UnusedWebhookSvc,
  1527  			ExpectedOutput: nil,
  1528  			ExpectedError:  testError,
  1529  		},
  1530  		{
  1531  			Name:                 "Returns error when ApplicationCreateInput validation fails",
  1532  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1533  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1534  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1535  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1536  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{modelAppTemplate}, nil).Once()
  1537  				appTemplateSvc.On("PrepareApplicationCreateInputJSON", modelAppTemplate, modelAppFromTemplateInput.Values).Return(jsonAppCreateInput, nil).Once()
  1538  				return appTemplateSvc
  1539  			},
  1540  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1541  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1542  				appTemplateConv.On("ApplicationFromTemplateInputFromGraphQL", modelAppTemplate, gqlAppFromTemplateInput).Return(modelAppFromTemplateInput, nil).Once()
  1543  				return appTemplateConv
  1544  			},
  1545  			AppSvcFn: UnusedAppSvc,
  1546  			AppConvFn: func() *automock.ApplicationConverter {
  1547  				appConv := &automock.ApplicationConverter{}
  1548  				appConv.On("CreateRegisterInputJSONToGQL", jsonAppCreateInput).Return(graphql.ApplicationRegisterInput{}, nil).Once()
  1549  				return appConv
  1550  			},
  1551  			WebhookConvFn:  UnusedWebhookConv,
  1552  			WebhookSvcFn:   UnusedWebhookSvc,
  1553  			ExpectedOutput: nil,
  1554  			ExpectedError:  errors.New("name=cannot be blank"),
  1555  		},
  1556  		{
  1557  			Name:                 "Returns error when creating Application fails",
  1558  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1559  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1560  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1561  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1562  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{modelAppTemplate}, nil).Once()
  1563  				appTemplateSvc.On("PrepareApplicationCreateInputJSON", modelAppTemplate, modelAppFromTemplateInput.Values).Return(jsonAppCreateInput, nil).Once()
  1564  				return appTemplateSvc
  1565  			},
  1566  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1567  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1568  				appTemplateConv.On("ApplicationFromTemplateInputFromGraphQL", modelAppTemplate, gqlAppFromTemplateInput).Return(modelAppFromTemplateInput, nil).Once()
  1569  				return appTemplateConv
  1570  			},
  1571  			AppSvcFn: func() *automock.ApplicationService {
  1572  				appSvc := &automock.ApplicationService{}
  1573  				appSvc.On("CreateFromTemplate", txtest.CtxWithDBMatcher(), modelAppWithLabelCreateInput, str.Ptr(testID)).Return("", testError).Once()
  1574  				return appSvc
  1575  			},
  1576  			AppConvFn: func() *automock.ApplicationConverter {
  1577  				appConv := &automock.ApplicationConverter{}
  1578  				appConv.On("CreateInputFromGraphQL", mock.Anything, gqlAppCreateInput).Return(modelAppCreateInput, nil).Once()
  1579  				appConv.On("CreateRegisterInputJSONToGQL", jsonAppCreateInput).Return(gqlAppCreateInput, nil).Once()
  1580  				return appConv
  1581  			},
  1582  			WebhookConvFn:  UnusedWebhookConv,
  1583  			WebhookSvcFn:   UnusedWebhookSvc,
  1584  			ExpectedOutput: nil,
  1585  			ExpectedError:  testError,
  1586  		},
  1587  		{
  1588  			Name:                 "Returns error when getting Application fails",
  1589  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1590  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1591  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1592  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1593  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{modelAppTemplate}, nil).Once()
  1594  				appTemplateSvc.On("PrepareApplicationCreateInputJSON", modelAppTemplate, modelAppFromTemplateInput.Values).Return(jsonAppCreateInput, nil).Once()
  1595  				return appTemplateSvc
  1596  			},
  1597  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1598  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1599  				appTemplateConv.On("ApplicationFromTemplateInputFromGraphQL", modelAppTemplate, gqlAppFromTemplateInput).Return(modelAppFromTemplateInput, nil).Once()
  1600  				return appTemplateConv
  1601  			},
  1602  			AppSvcFn: func() *automock.ApplicationService {
  1603  				appSvc := &automock.ApplicationService{}
  1604  				appSvc.On("CreateFromTemplate", txtest.CtxWithDBMatcher(), modelAppWithLabelCreateInput, str.Ptr(testID)).Return(testID, nil).Once()
  1605  				appSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testError).Once()
  1606  				return appSvc
  1607  			},
  1608  			AppConvFn: func() *automock.ApplicationConverter {
  1609  				appConv := &automock.ApplicationConverter{}
  1610  				appConv.On("CreateInputFromGraphQL", mock.Anything, gqlAppCreateInput).Return(modelAppCreateInput, nil).Once()
  1611  				appConv.On("CreateRegisterInputJSONToGQL", jsonAppCreateInput).Return(gqlAppCreateInput, nil).Once()
  1612  				return appConv
  1613  			},
  1614  			WebhookConvFn:  UnusedWebhookConv,
  1615  			WebhookSvcFn:   UnusedWebhookSvc,
  1616  			ExpectedOutput: nil,
  1617  			ExpectedError:  testError,
  1618  		},
  1619  		{
  1620  			Name:                 "Returns error when committing transaction fails",
  1621  			AppFromTemplateInput: gqlAppFromTemplateInput,
  1622  			TxFn:                 txGen.ThatFailsOnCommit,
  1623  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1624  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1625  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{modelAppTemplate}, nil).Once()
  1626  				appTemplateSvc.On("PrepareApplicationCreateInputJSON", modelAppTemplate, modelAppFromTemplateInput.Values).Return(jsonAppCreateInput, nil).Once()
  1627  				return appTemplateSvc
  1628  			},
  1629  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1630  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1631  				appTemplateConv.On("ApplicationFromTemplateInputFromGraphQL", modelAppTemplate, gqlAppFromTemplateInput).Return(modelAppFromTemplateInput, nil).Once()
  1632  				return appTemplateConv
  1633  			},
  1634  			AppSvcFn: func() *automock.ApplicationService {
  1635  				appSvc := &automock.ApplicationService{}
  1636  				appSvc.On("CreateFromTemplate", txtest.CtxWithDBMatcher(), modelAppWithLabelCreateInput, str.Ptr(testID)).Return(testID, nil).Once()
  1637  				appSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(&modelApplication, nil).Once()
  1638  				return appSvc
  1639  			},
  1640  			AppConvFn: func() *automock.ApplicationConverter {
  1641  				appConv := &automock.ApplicationConverter{}
  1642  				appConv.On("CreateInputFromGraphQL", mock.Anything, gqlAppCreateInput).Return(modelAppCreateInput, nil).Once()
  1643  				appConv.On("CreateRegisterInputJSONToGQL", jsonAppCreateInput).Return(gqlAppCreateInput, nil).Once()
  1644  				return appConv
  1645  			},
  1646  			WebhookConvFn:  UnusedWebhookConv,
  1647  			WebhookSvcFn:   UnusedWebhookSvc,
  1648  			ExpectedOutput: nil,
  1649  			ExpectedError:  testError,
  1650  		},
  1651  		{
  1652  			Name:                 "ErrorWhenNoTemplatesWithGivenIDFound",
  1653  			AppFromTemplateInput: gqlAppFromTemplateWithIDInput,
  1654  			TxFn:                 txGen.ThatDoesntExpectCommit,
  1655  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1656  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1657  				appTemplateSvc.On("ListByFilters", txtest.CtxWithDBMatcher(), filters).Return([]*model.ApplicationTemplate{}, nil).Once()
  1658  				appTemplateSvc.On("ListByName", txtest.CtxWithDBMatcher(), testName).Return([]*model.ApplicationTemplate{modelAppTemplate}, nil).Once()
  1659  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, globalSubaccountIDLabelKey).Return(nil, apperrors.NewNotFoundError(resource.Label, "id")).Once()
  1660  				return appTemplateSvc
  1661  			},
  1662  			AppTemplateConvFn: UnusedAppTemplateConv,
  1663  			AppSvcFn:          UnusedAppSvc,
  1664  			AppConvFn:         UnusedAppConv,
  1665  			WebhookConvFn:     UnusedWebhookConv,
  1666  			WebhookSvcFn:      UnusedWebhookSvc,
  1667  			ExpectedError:     errors.New("application template with id customTemplateID and consumer id \"consumer-id\" not found"),
  1668  		},
  1669  	}
  1670  
  1671  	for _, testCase := range testCases {
  1672  		t.Run(testCase.Name, func(t *testing.T) {
  1673  			persist, transact := testCase.TxFn()
  1674  			appTemplateSvc := testCase.AppTemplateSvcFn()
  1675  			appTemplateConv := testCase.AppTemplateConvFn()
  1676  			webhookSvc := testCase.WebhookSvcFn()
  1677  			webhookConverter := testCase.WebhookConvFn()
  1678  			appSvc := testCase.AppSvcFn()
  1679  			appConv := testCase.AppConvFn()
  1680  
  1681  			resolver := apptemplate.NewResolver(transact, appSvc, appConv, appTemplateSvc, appTemplateConv, webhookSvc, webhookConverter, nil, nil, "")
  1682  
  1683  			// WHEN
  1684  			result, err := resolver.RegisterApplicationFromTemplate(ctx, testCase.AppFromTemplateInput)
  1685  
  1686  			// THEN
  1687  			if testCase.ExpectedError != nil {
  1688  				require.Error(t, err)
  1689  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
  1690  			} else {
  1691  				assert.NoError(t, err)
  1692  			}
  1693  			assert.Equal(t, testCase.ExpectedOutput, result)
  1694  
  1695  			persist.AssertExpectations(t)
  1696  			transact.AssertExpectations(t)
  1697  			appTemplateSvc.AssertExpectations(t)
  1698  			appTemplateConv.AssertExpectations(t)
  1699  			appSvc.AssertExpectations(t)
  1700  			appConv.AssertExpectations(t)
  1701  		})
  1702  	}
  1703  }
  1704  
  1705  func TestResolver_UpdateApplicationTemplate(t *testing.T) {
  1706  	// GIVEN
  1707  	ctx := tenant.SaveToContext(context.TODO(), testTenant, testExternalTenant)
  1708  
  1709  	txGen := txtest.NewTransactionContextGenerator(testError)
  1710  
  1711  	modelAppTemplate := fixModelApplicationTemplate(testID, testName, fixModelApplicationTemplateWebhooks(testWebhookID, testID))
  1712  	modelAppTemplateInput := fixModelAppTemplateUpdateInput(testName, appInputJSONString)
  1713  	gqlAppTemplate := fixGQLAppTemplate(testID, testName, fixGQLApplicationTemplateWebhooks(testWebhookID, testID))
  1714  	gqlAppTemplateUpdateInput := fixGQLAppTemplateUpdateInputWithPlaceholder(testName)
  1715  	gqlAppTemplateUpdateInputWithoutNameProperty := fixGQLAppTemplateUpdateInputWithPlaceholder(testName)
  1716  	gqlAppTemplateUpdateInputWithoutNameProperty.ApplicationInput.Name = ""
  1717  	gqlAppTemplateUpdateInputWithoutDisplayNameLabel := fixGQLAppTemplateUpdateInputWithPlaceholder(testName)
  1718  	gqlAppTemplateUpdateInputWithoutDisplayNameLabel.ApplicationInput.Labels = graphql.Labels{}
  1719  	gqlAppTemplateUpdateInputWithNonStringDisplayLabel := fixGQLAppTemplateUpdateInputWithPlaceholder(testName)
  1720  	gqlAppTemplateUpdateInputWithNonStringDisplayLabel.ApplicationInput.Labels = graphql.Labels{
  1721  		"displayName": false,
  1722  	}
  1723  	gqlAppTemplateUpdateInputWithProvider := fixGQLAppTemplateUpdateInputWithPlaceholderAndProvider(testName)
  1724  
  1725  	labels := map[string]*model.Label{
  1726  		"test": {
  1727  			Key:   "test key",
  1728  			Value: "test value",
  1729  		},
  1730  	}
  1731  	resultLabels := map[string]interface{}{
  1732  		"test key": "test value",
  1733  	}
  1734  	testCases := []struct {
  1735  		Name              string
  1736  		TxFn              func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  1737  		AppTemplateSvcFn  func() *automock.ApplicationTemplateService
  1738  		AppTemplateConvFn func() *automock.ApplicationTemplateConverter
  1739  		SelfRegManagerFn  func() *automock.SelfRegisterManager
  1740  		WebhookSvcFn      func() *automock.WebhookService
  1741  		WebhookConvFn     func() *automock.WebhookConverter
  1742  		Input             *graphql.ApplicationTemplateUpdateInput
  1743  		ExpectedOutput    *graphql.ApplicationTemplate
  1744  		ExpectedError     error
  1745  	}{
  1746  		{
  1747  			Name: "Success",
  1748  			TxFn: txGen.ThatSucceeds,
  1749  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1750  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1751  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(labels, nil).Once()
  1752  				appTemplateSvc.On("Update", txtest.CtxWithDBMatcher(), testID, *modelAppTemplateInput).Return(nil).Once()
  1753  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  1754  				return appTemplateSvc
  1755  			},
  1756  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1757  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1758  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInput).Return(*modelAppTemplateInput, nil).Once()
  1759  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once()
  1760  				return appTemplateConv
  1761  			},
  1762  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  1763  				srm := &automock.SelfRegisterManager{}
  1764  				srm.On("IsSelfRegistrationFlow", txtest.CtxWithDBMatcher(), resultLabels).Return(false, nil).Once()
  1765  				return srm
  1766  			},
  1767  			WebhookConvFn:  UnusedWebhookConv,
  1768  			WebhookSvcFn:   SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1769  			Input:          gqlAppTemplateUpdateInput,
  1770  			ExpectedOutput: gqlAppTemplate,
  1771  		},
  1772  		{
  1773  			Name: "Success with self reg flow",
  1774  			TxFn: txGen.ThatSucceeds,
  1775  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1776  				placeholders := []model.ApplicationTemplatePlaceholder{
  1777  					{
  1778  						Name:        "name",
  1779  						Description: &testDescription,
  1780  						JSONPath:    &testJSONPath,
  1781  					},
  1782  					{
  1783  						Name:        "display-name",
  1784  						Description: &testDescription,
  1785  						JSONPath:    &testJSONPath,
  1786  					},
  1787  				}
  1788  				modelAppTemplate := fixModelAppTemplateWithAppInputJSONAndPlaceholders(testID, "SAP app-template", appInputJSONString, fixModelApplicationTemplateWebhooks(testWebhookID, testID), placeholders)
  1789  				modelAppTemplateInput := fixModelAppTemplateUpdateInputWithPlaceholders("SAP app-template", appInputJSONString, placeholders)
  1790  
  1791  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1792  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(labels, nil).Once()
  1793  				appTemplateSvc.On("Update", txtest.CtxWithDBMatcher(), testID, *modelAppTemplateInput).Return(nil).Once()
  1794  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  1795  				return appTemplateSvc
  1796  			},
  1797  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1798  				placeholders := []model.ApplicationTemplatePlaceholder{
  1799  					{
  1800  						Name:        "name",
  1801  						Description: &testDescription,
  1802  						JSONPath:    &testJSONPath,
  1803  					},
  1804  					{
  1805  						Name:        "display-name",
  1806  						Description: &testDescription,
  1807  						JSONPath:    &testJSONPath,
  1808  					},
  1809  				}
  1810  				modelAppTemplate := fixModelAppTemplateWithAppInputJSONAndPlaceholders(testID, "SAP app-template", appInputJSONString, fixModelApplicationTemplateWebhooks(testWebhookID, testID), placeholders)
  1811  				modelAppTemplateInput := fixModelAppTemplateUpdateInputWithPlaceholders("SAP app-template", appInputJSONString, placeholders)
  1812  
  1813  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1814  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInput).Return(*modelAppTemplateInput, nil).Once()
  1815  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once()
  1816  				return appTemplateConv
  1817  			},
  1818  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  1819  				srm := &automock.SelfRegisterManager{}
  1820  				srm.On("IsSelfRegistrationFlow", txtest.CtxWithDBMatcher(), resultLabels).Return(true, nil).Once()
  1821  				return srm
  1822  			},
  1823  			WebhookConvFn:  UnusedWebhookConv,
  1824  			WebhookSvcFn:   SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1825  			Input:          gqlAppTemplateUpdateInput,
  1826  			ExpectedOutput: gqlAppTemplate,
  1827  		},
  1828  		{
  1829  			Name:             "Returns error when can't convert input from graphql",
  1830  			TxFn:             txGen.ThatDoesntExpectCommit,
  1831  			AppTemplateSvcFn: UnusedAppTemplateSvc,
  1832  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1833  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1834  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInput).Return(model.ApplicationTemplateUpdateInput{}, testError).Once()
  1835  				return appTemplateConv
  1836  			},
  1837  			SelfRegManagerFn: UnusedSelfRegManager,
  1838  			WebhookConvFn:    UnusedWebhookConv,
  1839  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1840  			Input:            gqlAppTemplateUpdateInput,
  1841  			ExpectedError:    testError,
  1842  		},
  1843  		{
  1844  			Name: "Returns error when updating application template failed",
  1845  			TxFn: txGen.ThatDoesntExpectCommit,
  1846  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1847  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1848  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(labels, nil).Once()
  1849  				appTemplateSvc.On("Update", txtest.CtxWithDBMatcher(), testID, *modelAppTemplateInput).Return(testError).Once()
  1850  				return appTemplateSvc
  1851  			},
  1852  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1853  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1854  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInput).Return(*modelAppTemplateInput, nil).Once()
  1855  				return appTemplateConv
  1856  			},
  1857  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  1858  				srm := &automock.SelfRegisterManager{}
  1859  				srm.On("IsSelfRegistrationFlow", txtest.CtxWithDBMatcher(), resultLabels).Return(false, nil).Once()
  1860  				return srm
  1861  			},
  1862  			WebhookConvFn: UnusedWebhookConv,
  1863  			WebhookSvcFn:  SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1864  			Input:         gqlAppTemplateUpdateInput,
  1865  			ExpectedError: testError,
  1866  		},
  1867  		{
  1868  			Name: "Returns error when getting application template failed",
  1869  			TxFn: txGen.ThatDoesntExpectCommit,
  1870  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1871  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1872  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(labels, nil).Once()
  1873  				appTemplateSvc.On("Update", txtest.CtxWithDBMatcher(), testID, *modelAppTemplateInput).Return(nil).Once()
  1874  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testError).Once()
  1875  				return appTemplateSvc
  1876  			},
  1877  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1878  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1879  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInput).Return(*modelAppTemplateInput, nil).Once()
  1880  				return appTemplateConv
  1881  			},
  1882  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  1883  				srm := &automock.SelfRegisterManager{}
  1884  				srm.On("IsSelfRegistrationFlow", txtest.CtxWithDBMatcher(), resultLabels).Return(false, nil).Once()
  1885  				return srm
  1886  			},
  1887  			WebhookConvFn: UnusedWebhookConv,
  1888  			WebhookSvcFn:  SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1889  			Input:         gqlAppTemplateUpdateInput,
  1890  			ExpectedError: testError,
  1891  		},
  1892  		{
  1893  			Name: "Returns error when list application template labels failed",
  1894  			TxFn: txGen.ThatDoesntExpectCommit,
  1895  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1896  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1897  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(nil, testError).Once()
  1898  				return appTemplateSvc
  1899  			},
  1900  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1901  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1902  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInput).Return(*modelAppTemplateInput, nil).Once()
  1903  				return appTemplateConv
  1904  			},
  1905  			SelfRegManagerFn: UnusedSelfRegManager,
  1906  			WebhookConvFn:    UnusedWebhookConv,
  1907  			WebhookSvcFn:     SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1908  			Input:            gqlAppTemplateUpdateInput,
  1909  			ExpectedError:    testError,
  1910  		},
  1911  		{
  1912  			Name: "Returns error when self registration flow check failed",
  1913  			TxFn: txGen.ThatDoesntExpectCommit,
  1914  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1915  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1916  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(labels, nil).Once()
  1917  				return appTemplateSvc
  1918  			},
  1919  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1920  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1921  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInput).Return(*modelAppTemplateInput, nil).Once()
  1922  				return appTemplateConv
  1923  			},
  1924  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  1925  				srm := &automock.SelfRegisterManager{}
  1926  				srm.On("IsSelfRegistrationFlow", txtest.CtxWithDBMatcher(), resultLabels).Return(false, testError).Once()
  1927  				return srm
  1928  			},
  1929  			WebhookConvFn: UnusedWebhookConv,
  1930  			WebhookSvcFn:  SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1931  			Input:         gqlAppTemplateUpdateInput,
  1932  			ExpectedError: testError,
  1933  		},
  1934  		{
  1935  			Name: "Returns error when appInputJSON name property is missing",
  1936  			TxFn: txGen.ThatDoesntExpectCommit,
  1937  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1938  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1939  				return appTemplateSvc
  1940  			},
  1941  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1942  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1943  				return appTemplateConv
  1944  			},
  1945  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  1946  				srm := &automock.SelfRegisterManager{}
  1947  				return srm
  1948  			},
  1949  			WebhookConvFn: UnusedWebhookConv,
  1950  			WebhookSvcFn:  SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1951  			Input:         gqlAppTemplateUpdateInputWithoutNameProperty,
  1952  			ExpectedError: errors.New("appInput: (name: cannot be blank.)"),
  1953  		},
  1954  		{
  1955  			Name: "Returns error when appInputJSON displayName label is missing",
  1956  			TxFn: txGen.ThatDoesntExpectCommit,
  1957  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1958  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1959  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(labels, nil).Once()
  1960  				return appTemplateSvc
  1961  			},
  1962  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1963  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1964  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInputWithoutDisplayNameLabel).Return(*fixModelAppTemplateUpdateInput(testName, appInputJSONWithoutDisplayNameLabelString), nil).Once()
  1965  				return appTemplateConv
  1966  			},
  1967  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  1968  				srm := &automock.SelfRegisterManager{}
  1969  				srm.On("IsSelfRegistrationFlow", txtest.CtxWithDBMatcher(), resultLabels).Return(true, nil).Once()
  1970  				return srm
  1971  			},
  1972  			WebhookConvFn: UnusedWebhookConv,
  1973  			WebhookSvcFn:  SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1974  			Input:         gqlAppTemplateUpdateInputWithoutDisplayNameLabel,
  1975  			ExpectedError: errors.New("applicationInputJSON name property or applicationInputJSON displayName label is missing. They must be present in order to proceed."),
  1976  		},
  1977  		{
  1978  			Name: "Returns error when appInputJSON displayName label is not string",
  1979  			TxFn: txGen.ThatDoesntExpectCommit,
  1980  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  1981  				appTemplateSvc := &automock.ApplicationTemplateService{}
  1982  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(labels, nil).Once()
  1983  				return appTemplateSvc
  1984  			},
  1985  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  1986  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  1987  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInputWithNonStringDisplayLabel).Return(*fixModelAppTemplateUpdateInput(testName, appInputJSONNonStringDisplayNameLabelString), nil).Once()
  1988  				return appTemplateConv
  1989  			},
  1990  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  1991  				srm := &automock.SelfRegisterManager{}
  1992  				srm.On("IsSelfRegistrationFlow", txtest.CtxWithDBMatcher(), resultLabels).Return(true, nil).Once()
  1993  				return srm
  1994  			},
  1995  			WebhookConvFn: UnusedWebhookConv,
  1996  			WebhookSvcFn:  SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  1997  			Input:         gqlAppTemplateUpdateInputWithNonStringDisplayLabel,
  1998  			ExpectedError: errors.New("\"displayName\" label value must be string"),
  1999  		},
  2000  		{
  2001  			Name:              "Returns error when validating app template name",
  2002  			TxFn:              txGen.ThatDoesntExpectCommit,
  2003  			AppTemplateSvcFn:  UnusedAppTemplateSvc,
  2004  			AppTemplateConvFn: UnusedAppTemplateConv,
  2005  			SelfRegManagerFn:  UnusedSelfRegManager,
  2006  			WebhookConvFn:     UnusedWebhookConv,
  2007  			WebhookSvcFn:      UnusedWebhookSvc,
  2008  			Input:             gqlAppTemplateUpdateInputWithProvider,
  2009  			ExpectedError:     errors.New("application template name \"bar\" does not comply with the following naming convention: \"SAP <product name>\""),
  2010  		},
  2011  		{
  2012  			Name:              "Returns error when beginning transaction",
  2013  			TxFn:              txGen.ThatFailsOnBegin,
  2014  			AppTemplateSvcFn:  UnusedAppTemplateSvc,
  2015  			AppTemplateConvFn: UnusedAppTemplateConv,
  2016  			SelfRegManagerFn:  UnusedSelfRegManager,
  2017  			WebhookConvFn:     UnusedWebhookConv,
  2018  			WebhookSvcFn:      UnusedWebhookSvc,
  2019  			Input:             gqlAppTemplateUpdateInput,
  2020  			ExpectedError:     testError,
  2021  		},
  2022  		{
  2023  			Name: "Returns error when committing transaction",
  2024  			TxFn: txGen.ThatFailsOnCommit,
  2025  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2026  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2027  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(labels, nil).Once()
  2028  				appTemplateSvc.On("Update", txtest.CtxWithDBMatcher(), testID, *modelAppTemplateInput).Return(nil).Once()
  2029  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2030  				return appTemplateSvc
  2031  			},
  2032  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2033  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2034  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInput).Return(*modelAppTemplateInput, nil).Once()
  2035  				return appTemplateConv
  2036  			},
  2037  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  2038  				srm := &automock.SelfRegisterManager{}
  2039  				srm.On("IsSelfRegistrationFlow", txtest.CtxWithDBMatcher(), resultLabels).Return(false, nil).Once()
  2040  				return srm
  2041  			},
  2042  			WebhookConvFn: UnusedWebhookConv,
  2043  			WebhookSvcFn:  SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  2044  			Input:         gqlAppTemplateUpdateInput,
  2045  			ExpectedError: testError,
  2046  		},
  2047  		{
  2048  			Name: "Returns error when can't convert application template to graphql",
  2049  			TxFn: txGen.ThatSucceeds,
  2050  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2051  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2052  				appTemplateSvc.On("ListLabels", txtest.CtxWithDBMatcher(), testID).Return(labels, nil).Once()
  2053  				appTemplateSvc.On("Update", txtest.CtxWithDBMatcher(), testID, *modelAppTemplateInput).Return(nil).Once()
  2054  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2055  				return appTemplateSvc
  2056  			},
  2057  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2058  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2059  				appTemplateConv.On("UpdateInputFromGraphQL", *gqlAppTemplateUpdateInput).Return(*modelAppTemplateInput, nil).Once()
  2060  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(nil, testError).Once()
  2061  				return appTemplateConv
  2062  			},
  2063  			SelfRegManagerFn: func() *automock.SelfRegisterManager {
  2064  				srm := &automock.SelfRegisterManager{}
  2065  				srm.On("IsSelfRegistrationFlow", txtest.CtxWithDBMatcher(), resultLabels).Return(false, nil).Once()
  2066  				return srm
  2067  			},
  2068  			WebhookConvFn: UnusedWebhookConv,
  2069  			WebhookSvcFn:  SuccessfulWebhookSvc(gqlAppTemplateUpdateInputWithProvider.Webhooks, gqlAppTemplateUpdateInputWithProvider.Webhooks),
  2070  			Input:         gqlAppTemplateUpdateInput,
  2071  			ExpectedError: testError,
  2072  		},
  2073  	}
  2074  
  2075  	for _, testCase := range testCases {
  2076  		t.Run(testCase.Name, func(t *testing.T) {
  2077  			persist, transact := testCase.TxFn()
  2078  			appTemplateSvc := testCase.AppTemplateSvcFn()
  2079  			appTemplateConv := testCase.AppTemplateConvFn()
  2080  			selfRegManager := testCase.SelfRegManagerFn()
  2081  			webhookSvc := testCase.WebhookSvcFn()
  2082  			webhookConverter := testCase.WebhookConvFn()
  2083  
  2084  			resolver := apptemplate.NewResolver(transact, nil, nil, appTemplateSvc, appTemplateConv, webhookSvc, webhookConverter, selfRegManager, nil, "")
  2085  
  2086  			// WHEN
  2087  			result, err := resolver.UpdateApplicationTemplate(ctx, testID, *testCase.Input)
  2088  
  2089  			// THEN
  2090  			if testCase.ExpectedError != nil {
  2091  				require.Error(t, err)
  2092  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
  2093  			} else {
  2094  				assert.NoError(t, err)
  2095  			}
  2096  			assert.Equal(t, testCase.ExpectedOutput, result)
  2097  
  2098  			mock.AssertExpectationsForObjects(t, persist, transact, appTemplateSvc, appTemplateConv, selfRegManager)
  2099  		})
  2100  	}
  2101  
  2102  	t.Run("Returns error when application template inputs url template has invalid method", func(t *testing.T) {
  2103  		gqlAppTemplateUpdateInputInvalid := fixGQLAppTemplateUpdateInputInvalidAppInput(testName)
  2104  		expectedError := errors.New("failed to parse webhook url template")
  2105  		_, transact := txGen.ThatSucceeds()
  2106  
  2107  		resolver := apptemplate.NewResolver(transact, nil, nil, nil, nil, nil, nil, nil, nil, "")
  2108  
  2109  		// WHEN
  2110  		_, err := resolver.UpdateApplicationTemplate(ctx, testID, *gqlAppTemplateUpdateInputInvalid)
  2111  
  2112  		// THEN
  2113  		require.Error(t, err)
  2114  		assert.Contains(t, err.Error(), expectedError.Error())
  2115  	})
  2116  }
  2117  
  2118  func TestResolver_DeleteApplicationTemplate(t *testing.T) {
  2119  	// GIVEN
  2120  	ctx := tenant.SaveToContext(context.TODO(), testTenant, testExternalTenant)
  2121  
  2122  	txGen := txtest.NewTransactionContextGenerator(testError)
  2123  
  2124  	uidSvcFn := func() *automock.UIDService {
  2125  		uidSvc := &automock.UIDService{}
  2126  		uidSvc.On("Generate").Return(testUUID)
  2127  		return uidSvc
  2128  	}
  2129  	modelAppTemplate := fixModelApplicationTemplate(testID, testName, fixModelApplicationTemplateWebhooks(testWebhookID, testID))
  2130  	gqlAppTemplate := fixGQLAppTemplate(testID, testName, fixGQLApplicationTemplateWebhooks(testWebhookID, testID))
  2131  
  2132  	label := &model.Label{Key: RegionKey, Value: "region-0"}
  2133  	badValueLabel := &model.Label{Key: RegionKey, Value: 1}
  2134  
  2135  	testCases := []struct {
  2136  		Name              string
  2137  		TxFn              func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
  2138  		AppTemplateSvcFn  func() *automock.ApplicationTemplateService
  2139  		AppTemplateConvFn func() *automock.ApplicationTemplateConverter
  2140  		WebhookSvcFn      func() *automock.WebhookService
  2141  		WebhookConvFn     func() *automock.WebhookConverter
  2142  		SelfRegManagerFn  func() *automock.SelfRegisterManager
  2143  		ExpectedOutput    *graphql.ApplicationTemplate
  2144  		ExpectedError     error
  2145  	}{
  2146  		{
  2147  			Name: "Success",
  2148  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  2149  				persistTx := &persistenceautomock.PersistenceTx{}
  2150  				persistTx.On("Commit").Return(nil).Times(2)
  2151  
  2152  				transact := &persistenceautomock.Transactioner{}
  2153  				transact.On("Begin").Return(persistTx, nil).Times(2)
  2154  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
  2155  
  2156  				return persistTx, transact
  2157  			},
  2158  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2159  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2160  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2161  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(label, nil).Once()
  2162  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, RegionKey).Return(label, nil).Once()
  2163  				appTemplateSvc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(nil).Once()
  2164  				return appTemplateSvc
  2165  			},
  2166  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2167  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2168  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(gqlAppTemplate, nil).Once()
  2169  				return appTemplateConv
  2170  			},
  2171  			WebhookConvFn:    UnusedWebhookConv,
  2172  			WebhookSvcFn:     UnusedWebhookSvc,
  2173  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesCleanupWithNoErrors,
  2174  			ExpectedOutput:   gqlAppTemplate,
  2175  		},
  2176  		{
  2177  			Name: "Returns error when getting application template failed",
  2178  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  2179  				persistTx := &persistenceautomock.PersistenceTx{}
  2180  				persistTx.AssertNotCalled(t, "Commit")
  2181  
  2182  				transact := &persistenceautomock.Transactioner{}
  2183  				transact.On("Begin").Return(persistTx, nil).Once()
  2184  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
  2185  
  2186  				return persistTx, transact
  2187  			},
  2188  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2189  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2190  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(nil, testError).Once()
  2191  				appTemplateSvc.AssertNotCalled(t, "GetLabel")
  2192  				appTemplateSvc.AssertNotCalled(t, "Delete")
  2193  				return appTemplateSvc
  2194  			},
  2195  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2196  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2197  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2198  				return appTemplateConv
  2199  			},
  2200  			WebhookConvFn:    UnusedWebhookConv,
  2201  			WebhookSvcFn:     UnusedWebhookSvc,
  2202  			SelfRegManagerFn: apptmpltest.NoopSelfRegManager,
  2203  			ExpectedError:    testError,
  2204  		},
  2205  		{
  2206  			Name: "Returns error when deleting application template failed",
  2207  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  2208  				persistTx := &persistenceautomock.PersistenceTx{}
  2209  				persistTx.On("Commit").Return(nil).Once()
  2210  
  2211  				transact := &persistenceautomock.Transactioner{}
  2212  				transact.On("Begin").Return(persistTx, nil).Times(2)
  2213  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
  2214  
  2215  				return persistTx, transact
  2216  			},
  2217  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2218  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2219  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2220  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(label, nil).Once()
  2221  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, RegionKey).Return(label, nil).Once()
  2222  				appTemplateSvc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(testError).Once()
  2223  				return appTemplateSvc
  2224  			},
  2225  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2226  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2227  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2228  				return appTemplateConv
  2229  			},
  2230  			WebhookConvFn:    UnusedWebhookConv,
  2231  			WebhookSvcFn:     UnusedWebhookSvc,
  2232  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesCleanupWithNoErrors,
  2233  			ExpectedError:    testError,
  2234  		},
  2235  		{
  2236  			Name: "Returns error when beginning transaction",
  2237  			TxFn: txGen.ThatFailsOnBegin,
  2238  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2239  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2240  				appTemplateSvc.AssertNotCalled(t, "Get")
  2241  				appTemplateSvc.AssertNotCalled(t, "GetLabel")
  2242  				appTemplateSvc.AssertNotCalled(t, "Delete")
  2243  				return appTemplateSvc
  2244  			},
  2245  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2246  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2247  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2248  				return appTemplateConv
  2249  			},
  2250  			WebhookConvFn:    UnusedWebhookConv,
  2251  			WebhookSvcFn:     UnusedWebhookSvc,
  2252  			SelfRegManagerFn: apptmpltest.NoopSelfRegManager,
  2253  			ExpectedError:    testError,
  2254  		},
  2255  		{
  2256  			Name: "Returns error when committing transaction for first time",
  2257  			TxFn: txGen.ThatFailsOnCommit,
  2258  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2259  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2260  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2261  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(label, nil).Once()
  2262  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, RegionKey).Return(label, nil).Once()
  2263  				appTemplateSvc.AssertNotCalled(t, "Delete")
  2264  				return appTemplateSvc
  2265  			},
  2266  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2267  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2268  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2269  				return appTemplateConv
  2270  			},
  2271  			WebhookConvFn:    UnusedWebhookConv,
  2272  			WebhookSvcFn:     UnusedWebhookSvc,
  2273  			SelfRegManagerFn: apptmpltest.SelfRegManagerReturnsDistinguishingLabel,
  2274  			ExpectedError:    testError,
  2275  		},
  2276  		{
  2277  			Name: "Returns error when committing transaction for second time",
  2278  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  2279  				persistTx := &persistenceautomock.PersistenceTx{}
  2280  				persistTx.On("Commit").Return(nil).Once()
  2281  				persistTx.On("Commit").Return(testError).Once()
  2282  
  2283  				transact := &persistenceautomock.Transactioner{}
  2284  				transact.On("Begin").Return(persistTx, nil).Times(2)
  2285  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
  2286  
  2287  				return persistTx, transact
  2288  			},
  2289  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2290  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2291  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2292  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(label, nil).Once()
  2293  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, RegionKey).Return(label, nil).Once()
  2294  				appTemplateSvc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(nil).Once()
  2295  				return appTemplateSvc
  2296  			},
  2297  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2298  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2299  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2300  				return appTemplateConv
  2301  			},
  2302  			WebhookConvFn:    UnusedWebhookConv,
  2303  			WebhookSvcFn:     UnusedWebhookSvc,
  2304  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesCleanupWithNoErrors,
  2305  			ExpectedError:    testError,
  2306  		},
  2307  		{
  2308  			Name: "Returns error when can't convert application template to graphql",
  2309  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  2310  				persistTx := &persistenceautomock.PersistenceTx{}
  2311  				persistTx.On("Commit").Return(nil).Times(2)
  2312  
  2313  				transact := &persistenceautomock.Transactioner{}
  2314  				transact.On("Begin").Return(persistTx, nil).Times(2)
  2315  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
  2316  
  2317  				return persistTx, transact
  2318  			},
  2319  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2320  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2321  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2322  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(label, nil).Once()
  2323  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, RegionKey).Return(label, nil).Once()
  2324  				appTemplateSvc.On("Delete", txtest.CtxWithDBMatcher(), testID).Return(nil).Once()
  2325  				return appTemplateSvc
  2326  			},
  2327  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2328  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2329  				appTemplateConv.On("ToGraphQL", modelAppTemplate).Return(nil, testError).Once()
  2330  				return appTemplateConv
  2331  			},
  2332  			WebhookConvFn:    UnusedWebhookConv,
  2333  			WebhookSvcFn:     UnusedWebhookSvc,
  2334  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesCleanupWithNoErrors,
  2335  			ExpectedError:    testError,
  2336  		},
  2337  		{
  2338  			Name: "Returns error when getting label for first time",
  2339  			TxFn: txGen.ThatDoesntExpectCommit,
  2340  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2341  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2342  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2343  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(nil, testError).Once()
  2344  				appTemplateSvc.AssertNotCalled(t, "GetLabel")
  2345  				appTemplateSvc.AssertNotCalled(t, "Delete")
  2346  				return appTemplateSvc
  2347  			},
  2348  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2349  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2350  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2351  				return appTemplateConv
  2352  			},
  2353  			WebhookConvFn:    UnusedWebhookConv,
  2354  			WebhookSvcFn:     UnusedWebhookSvc,
  2355  			SelfRegManagerFn: apptmpltest.SelfRegManagerReturnsDistinguishingLabel,
  2356  			ExpectedError:    testError,
  2357  		},
  2358  		{
  2359  			Name: "Returns error when getting label for second time",
  2360  			TxFn: txGen.ThatDoesntExpectCommit,
  2361  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2362  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2363  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2364  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(label, nil).Once()
  2365  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, RegionKey).Return(nil, testError).Once()
  2366  				appTemplateSvc.AssertNotCalled(t, "Delete")
  2367  				return appTemplateSvc
  2368  			},
  2369  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2370  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2371  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2372  				return appTemplateConv
  2373  			},
  2374  			WebhookConvFn:    UnusedWebhookConv,
  2375  			WebhookSvcFn:     UnusedWebhookSvc,
  2376  			SelfRegManagerFn: apptmpltest.SelfRegManagerReturnsDistinguishingLabel,
  2377  			ExpectedError:    testError,
  2378  		},
  2379  		{
  2380  			Name: "Success but couldn't cast region label value to string",
  2381  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  2382  				persistTx := &persistenceautomock.PersistenceTx{}
  2383  				persistTx.On("Commit").Return(nil).Once()
  2384  				persistTx.AssertNotCalled(t, "Commit")
  2385  
  2386  				transact := &persistenceautomock.Transactioner{}
  2387  				transact.On("Begin").Return(persistTx, nil).Once()
  2388  				transact.AssertNotCalled(t, "Begin")
  2389  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
  2390  
  2391  				return persistTx, transact
  2392  			},
  2393  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2394  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2395  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2396  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(label, nil).Once()
  2397  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, RegionKey).Return(badValueLabel, nil).Once()
  2398  				appTemplateSvc.AssertNotCalled(t, "Delete")
  2399  				return appTemplateSvc
  2400  			},
  2401  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2402  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2403  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2404  				return appTemplateConv
  2405  			},
  2406  			WebhookConvFn:    UnusedWebhookConv,
  2407  			WebhookSvcFn:     UnusedWebhookSvc,
  2408  			SelfRegManagerFn: apptmpltest.SelfRegManagerReturnsDistinguishingLabel,
  2409  			ExpectedOutput:   nil,
  2410  		},
  2411  		{
  2412  			Name: "Returns error when CleanUpSelfRegistration fails",
  2413  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  2414  				persistTx := &persistenceautomock.PersistenceTx{}
  2415  				persistTx.On("Commit").Return(nil).Once()
  2416  				persistTx.AssertNotCalled(t, "Commit")
  2417  
  2418  				transact := &persistenceautomock.Transactioner{}
  2419  				transact.On("Begin").Return(persistTx, nil).Once()
  2420  				transact.AssertNotCalled(t, "Begin")
  2421  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
  2422  
  2423  				return persistTx, transact
  2424  			},
  2425  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2426  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2427  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2428  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(label, nil).Once()
  2429  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, RegionKey).Return(label, nil).Once()
  2430  				appTemplateSvc.AssertNotCalled(t, "Delete")
  2431  				return appTemplateSvc
  2432  			},
  2433  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2434  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2435  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2436  				return appTemplateConv
  2437  			},
  2438  			WebhookConvFn:    UnusedWebhookConv,
  2439  			WebhookSvcFn:     UnusedWebhookSvc,
  2440  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatReturnsErrorOnCleanup,
  2441  			ExpectedError:    errors.New(apptmpltest.SelfRegErrorMsg),
  2442  		},
  2443  		{
  2444  			Name: "Returns error when beginning transaction for second time",
  2445  			TxFn: func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) {
  2446  				persistTx := &persistenceautomock.PersistenceTx{}
  2447  				persistTx.On("Commit").Return(nil).Once()
  2448  				persistTx.AssertNotCalled(t, "Commit")
  2449  
  2450  				transact := &persistenceautomock.Transactioner{}
  2451  				transact.On("Begin").Return(persistTx, nil).Once()
  2452  				transact.On("Begin").Return(persistTx, testError).Once()
  2453  				transact.On("RollbackUnlessCommitted", mock.Anything, persistTx).Return(false).Once()
  2454  
  2455  				return persistTx, transact
  2456  			},
  2457  			AppTemplateSvcFn: func() *automock.ApplicationTemplateService {
  2458  				appTemplateSvc := &automock.ApplicationTemplateService{}
  2459  				appTemplateSvc.On("Get", txtest.CtxWithDBMatcher(), testID).Return(modelAppTemplate, nil).Once()
  2460  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, apptmpltest.TestDistinguishLabel).Return(label, nil).Once()
  2461  				appTemplateSvc.On("GetLabel", txtest.CtxWithDBMatcher(), testID, RegionKey).Return(label, nil).Once()
  2462  				appTemplateSvc.AssertNotCalled(t, "Delete")
  2463  				return appTemplateSvc
  2464  			},
  2465  			AppTemplateConvFn: func() *automock.ApplicationTemplateConverter {
  2466  				appTemplateConv := &automock.ApplicationTemplateConverter{}
  2467  				appTemplateConv.AssertNotCalled(t, "ToGraphQL")
  2468  				return appTemplateConv
  2469  			},
  2470  			WebhookConvFn:    UnusedWebhookConv,
  2471  			WebhookSvcFn:     UnusedWebhookSvc,
  2472  			SelfRegManagerFn: apptmpltest.SelfRegManagerThatDoesCleanupWithNoErrors,
  2473  			ExpectedError:    testError,
  2474  		},
  2475  	}
  2476  
  2477  	for _, testCase := range testCases {
  2478  		t.Run(testCase.Name, func(t *testing.T) {
  2479  			persist, transact := testCase.TxFn()
  2480  			appTemplateSvc := testCase.AppTemplateSvcFn()
  2481  			appTemplateConv := testCase.AppTemplateConvFn()
  2482  			webhookSvc := testCase.WebhookSvcFn()
  2483  			webhookConverter := testCase.WebhookConvFn()
  2484  			selfRegManager := testCase.SelfRegManagerFn()
  2485  			uuidSvc := uidSvcFn()
  2486  
  2487  			resolver := apptemplate.NewResolver(transact, nil, nil, appTemplateSvc, appTemplateConv, webhookSvc, webhookConverter, selfRegManager, uuidSvc, "")
  2488  
  2489  			// WHEN
  2490  			result, err := resolver.DeleteApplicationTemplate(ctx, testID)
  2491  
  2492  			// THEN
  2493  			if testCase.ExpectedError != nil {
  2494  				require.Error(t, err)
  2495  				assert.Contains(t, err.Error(), testCase.ExpectedError.Error())
  2496  			} else {
  2497  				assert.NoError(t, err)
  2498  			}
  2499  			assert.Equal(t, testCase.ExpectedOutput, result)
  2500  
  2501  			persist.AssertExpectations(t)
  2502  			transact.AssertExpectations(t)
  2503  			appTemplateSvc.AssertExpectations(t)
  2504  			appTemplateConv.AssertExpectations(t)
  2505  			selfRegManager.AssertExpectations(t)
  2506  		})
  2507  	}
  2508  }
  2509  
  2510  func UnusedAppTemplateSvc() *automock.ApplicationTemplateService {
  2511  	return &automock.ApplicationTemplateService{}
  2512  }
  2513  
  2514  func UnusedAppTemplateConv() *automock.ApplicationTemplateConverter {
  2515  	return &automock.ApplicationTemplateConverter{}
  2516  }
  2517  
  2518  func UnusedAppSvc() *automock.ApplicationService {
  2519  	return &automock.ApplicationService{}
  2520  }
  2521  
  2522  func UnusedAppConv() *automock.ApplicationConverter {
  2523  	return &automock.ApplicationConverter{}
  2524  }
  2525  
  2526  func UnusedSelfRegManager() *automock.SelfRegisterManager {
  2527  	return &automock.SelfRegisterManager{}
  2528  }
  2529  
  2530  func UnusedWebhookConv() *automock.WebhookConverter {
  2531  	return &automock.WebhookConverter{}
  2532  }
  2533  
  2534  func UnusedWebhookSvc() *automock.WebhookService {
  2535  	return &automock.WebhookService{}
  2536  }
  2537  
  2538  func SuccessfulWebhookSvc(webhooksInput, enriched []*graphql.WebhookInput) func() *automock.WebhookService {
  2539  	return func() *automock.WebhookService {
  2540  		svc := &automock.WebhookService{}
  2541  		svc.On("EnrichWebhooksWithTenantMappingWebhooks", webhooksInput).Return(enriched, nil)
  2542  		return svc
  2543  	}
  2544  }