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

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