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

     1  package scenarioassignment_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/kyma-incubator/compass/components/director/internal/domain/scenarioassignment"
     9  	"github.com/kyma-incubator/compass/components/director/internal/domain/scenarioassignment/automock"
    10  	"github.com/kyma-incubator/compass/components/director/internal/model"
    11  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    12  	persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock"
    13  	"github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest"
    14  	"github.com/pkg/errors"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/mock"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  func TestResolver_GetAutomaticScenarioAssignmentByScenario(t *testing.T) {
    21  	txGen := txtest.NewTransactionContextGenerator(errors.New("some persistence error"))
    22  	expectedOutput := fixGQL()
    23  
    24  	t.Run("happy path", func(t *testing.T) {
    25  		tx, transact := txGen.ThatSucceeds()
    26  
    27  		mockConverter := &automock.GqlConverter{}
    28  		mockConverter.On("ToGraphQL", fixModel(), externalTargetTenantID).Return(expectedOutput).Once()
    29  
    30  		mockSvc := &automock.AsaService{}
    31  		mockSvc.On("GetForScenarioName", txtest.CtxWithDBMatcher(), scenarioName).Return(fixModel(), nil).Once()
    32  
    33  		tenantSvc := &automock.TenantService{}
    34  		tenantSvc.On("GetExternalTenant", mock.Anything, targetTenantID).Return(externalTargetTenantID, nil).Once()
    35  
    36  		sut := scenarioassignment.NewResolver(transact, mockSvc, mockConverter, tenantSvc)
    37  
    38  		// WHEN
    39  		actual, err := sut.GetAutomaticScenarioAssignmentForScenarioName(context.TODO(), scenarioName)
    40  
    41  		// THEN
    42  		require.NoError(t, err)
    43  		assert.Equal(t, &expectedOutput, actual)
    44  		mock.AssertExpectationsForObjects(t, tx, transact, mockSvc, mockConverter, tenantSvc)
    45  	})
    46  
    47  	t.Run("error when GetExternalTenant fail", func(t *testing.T) {
    48  		tx, transact := txGen.ThatDoesntExpectCommit()
    49  
    50  		mockSvc := &automock.AsaService{}
    51  		mockSvc.On("GetForScenarioName", txtest.CtxWithDBMatcher(), scenarioName).Return(fixModel(), nil).Once()
    52  
    53  		tenantSvc := &automock.TenantService{}
    54  		tenantSvc.On("GetExternalTenant", mock.Anything, targetTenantID).Return("", fixError()).Once()
    55  
    56  		sut := scenarioassignment.NewResolver(transact, mockSvc, nil, tenantSvc)
    57  
    58  		// WHEN
    59  		_, err := sut.GetAutomaticScenarioAssignmentForScenarioName(context.TODO(), scenarioName)
    60  
    61  		// THEN
    62  		require.Error(t, err)
    63  		require.Contains(t, err.Error(), fixError().Error())
    64  		mock.AssertExpectationsForObjects(t, tx, transact, mockSvc, tenantSvc)
    65  	})
    66  
    67  	t.Run("error on starting transaction", func(t *testing.T) {
    68  		tx, transact := txGen.ThatFailsOnBegin()
    69  		defer mock.AssertExpectationsForObjects(t, tx, transact)
    70  
    71  		sut := scenarioassignment.NewResolver(transact, nil, nil, nil)
    72  
    73  		// WHEN
    74  		_, err := sut.GetAutomaticScenarioAssignmentForScenarioName(context.TODO(), scenarioName)
    75  
    76  		// THEN
    77  		assert.EqualError(t, err, "while beginning transaction: some persistence error")
    78  	})
    79  
    80  	t.Run("error on receiving assignment by service", func(t *testing.T) {
    81  		tx, transact := txGen.ThatDoesntExpectCommit()
    82  		mockSvc := &automock.AsaService{}
    83  		mockSvc.On("GetForScenarioName", txtest.CtxWithDBMatcher(), scenarioName).Return(model.AutomaticScenarioAssignment{}, fixError()).Once()
    84  		defer mock.AssertExpectationsForObjects(t, tx, transact, mockSvc)
    85  
    86  		sut := scenarioassignment.NewResolver(transact, mockSvc, nil, nil)
    87  
    88  		// WHEN
    89  		_, err := sut.GetAutomaticScenarioAssignmentForScenarioName(context.TODO(), scenarioName)
    90  
    91  		// THEN
    92  		assert.EqualError(t, err, fmt.Sprintf("while getting Assignment: %s", errMsg))
    93  	})
    94  
    95  	t.Run("error on committing transaction", func(t *testing.T) {
    96  		tx, transact := txGen.ThatFailsOnCommit()
    97  		mockSvc := &automock.AsaService{}
    98  		mockSvc.On("GetForScenarioName", txtest.CtxWithDBMatcher(), scenarioName).Return(fixModel(), nil).Once()
    99  
   100  		tenantSvc := &automock.TenantService{}
   101  		tenantSvc.On("GetExternalTenant", mock.Anything, targetTenantID).Return(externalTargetTenantID, nil).Once()
   102  
   103  		sut := scenarioassignment.NewResolver(transact, mockSvc, nil, tenantSvc)
   104  
   105  		// WHEN
   106  		_, err := sut.GetAutomaticScenarioAssignmentForScenarioName(context.TODO(), scenarioName)
   107  
   108  		// THEN
   109  		assert.EqualError(t, err, "while committing transaction: some persistence error")
   110  		mock.AssertExpectationsForObjects(t, tx, transact, mockSvc, tenantSvc)
   111  	})
   112  }
   113  
   114  func TestResolver_AutomaticScenarioAssignmentsForSelector(t *testing.T) {
   115  	givenInput := graphql.LabelSelectorInput{
   116  		Key:   scenarioassignment.SubaccountIDKey,
   117  		Value: externalTargetTenantID,
   118  	}
   119  
   120  	expectedModels := []*model.AutomaticScenarioAssignment{
   121  		{
   122  			ScenarioName:   scenarioName,
   123  			TargetTenantID: targetTenantID,
   124  		},
   125  		{
   126  			ScenarioName:   "scenario-B",
   127  			TargetTenantID: targetTenantID,
   128  		},
   129  	}
   130  
   131  	expectedOutput := []*graphql.AutomaticScenarioAssignment{
   132  		{
   133  			ScenarioName: scenarioName,
   134  			Selector: &graphql.Label{
   135  				Key:   scenarioassignment.SubaccountIDKey,
   136  				Value: externalTargetTenantID,
   137  			},
   138  		},
   139  		{
   140  			ScenarioName: "scenario-B",
   141  			Selector: &graphql.Label{
   142  				Key:   scenarioassignment.SubaccountIDKey,
   143  				Value: externalTargetTenantID,
   144  			},
   145  		},
   146  	}
   147  
   148  	txGen := txtest.NewTransactionContextGenerator(errors.New("some persistence error"))
   149  
   150  	t.Run("happy path", func(t *testing.T) {
   151  		tx, transact := txGen.ThatSucceeds()
   152  
   153  		mockConverter := &automock.GqlConverter{}
   154  		mockConverter.On("ToGraphQL", *expectedModels[0], externalTargetTenantID).Return(*expectedOutput[0]).Once()
   155  		mockConverter.On("ToGraphQL", *expectedModels[1], externalTargetTenantID).Return(*expectedOutput[1]).Once()
   156  
   157  		mockSvc := &automock.AsaService{}
   158  		mockSvc.On("ListForTargetTenant", mock.Anything, targetTenantID).Return(expectedModels, nil).Once()
   159  
   160  		tenantSvc := &automock.TenantService{}
   161  		tenantSvc.On("GetInternalTenant", mock.Anything, externalTargetTenantID).Return(targetTenantID, nil).Once()
   162  
   163  		sut := scenarioassignment.NewResolver(transact, mockSvc, mockConverter, tenantSvc)
   164  
   165  		// WHEN
   166  		actual, err := sut.AutomaticScenarioAssignmentsForSelector(fixCtxWithTenant(), givenInput)
   167  
   168  		// THEN
   169  		require.NoError(t, err)
   170  		assert.Equal(t, expectedOutput, actual)
   171  		mock.AssertExpectationsForObjects(t, tx, transact, mockSvc, mockConverter, tenantSvc)
   172  	})
   173  
   174  	t.Run("error on starting transaction", func(t *testing.T) {
   175  		tx, transact := txGen.ThatFailsOnBegin()
   176  		defer mock.AssertExpectationsForObjects(t, tx, transact)
   177  
   178  		sut := scenarioassignment.NewResolver(transact, nil, nil, nil)
   179  
   180  		// WHEN
   181  		_, err := sut.AutomaticScenarioAssignmentsForSelector(context.TODO(), graphql.LabelSelectorInput{})
   182  
   183  		// THEN
   184  		assert.EqualError(t, err, "while beginning transaction: some persistence error")
   185  	})
   186  
   187  	t.Run("error on getting assignments by service", func(t *testing.T) {
   188  		tx, transact := txGen.ThatDoesntExpectCommit()
   189  
   190  		tenantSvc := &automock.TenantService{}
   191  		tenantSvc.On("GetInternalTenant", mock.Anything, externalTargetTenantID).Return(targetTenantID, nil).Once()
   192  
   193  		mockSvc := &automock.AsaService{}
   194  		mockSvc.On("ListForTargetTenant", mock.Anything, targetTenantID).Return(nil, fixError()).Once()
   195  
   196  		sut := scenarioassignment.NewResolver(transact, mockSvc, nil, tenantSvc)
   197  
   198  		// WHEN
   199  		actual, err := sut.AutomaticScenarioAssignmentsForSelector(fixCtxWithTenant(), givenInput)
   200  
   201  		// THEN
   202  		require.Nil(t, actual)
   203  		require.EqualError(t, err, "while getting the assignments: some error")
   204  		mock.AssertExpectationsForObjects(t, tx, transact, mockSvc, tenantSvc)
   205  	})
   206  
   207  	t.Run("error on getting assignments by service", func(t *testing.T) {
   208  		tx, transact := txGen.ThatDoesntExpectCommit()
   209  
   210  		tenantSvc := &automock.TenantService{}
   211  		tenantSvc.On("GetInternalTenant", mock.Anything, externalTargetTenantID).Return("", fixError()).Once()
   212  
   213  		sut := scenarioassignment.NewResolver(transact, nil, nil, tenantSvc)
   214  
   215  		// WHEN
   216  		actual, err := sut.AutomaticScenarioAssignmentsForSelector(fixCtxWithTenant(), givenInput)
   217  
   218  		// THEN
   219  		require.Nil(t, actual)
   220  		require.EqualError(t, err, "while converting tenant: some error")
   221  		mock.AssertExpectationsForObjects(t, tx, transact, tenantSvc)
   222  	})
   223  
   224  	t.Run("error on committing transaction", func(t *testing.T) {
   225  		tx, transact := txGen.ThatFailsOnCommit()
   226  
   227  		mockSvc := &automock.AsaService{}
   228  		mockSvc.On("ListForTargetTenant", mock.Anything, targetTenantID).Return(expectedModels, nil).Once()
   229  
   230  		tenantSvc := &automock.TenantService{}
   231  		tenantSvc.On("GetInternalTenant", mock.Anything, externalTargetTenantID).Return(targetTenantID, nil).Once()
   232  
   233  		sut := scenarioassignment.NewResolver(transact, mockSvc, nil, tenantSvc)
   234  
   235  		// WHEN
   236  		actual, err := sut.AutomaticScenarioAssignmentsForSelector(fixCtxWithTenant(), givenInput)
   237  
   238  		// THEN
   239  		require.EqualError(t, err, "while committing transaction: some persistence error")
   240  		require.Nil(t, actual)
   241  		mock.AssertExpectationsForObjects(t, tx, transact, mockSvc, tenantSvc)
   242  	})
   243  }
   244  
   245  func TestResolver_AutomaticScenarioAssignments(t *testing.T) {
   246  	testErr := errors.New("test error")
   247  
   248  	mod1 := fixModelWithScenarioName("foo")
   249  	mod2 := fixModelWithScenarioName("bar")
   250  	modItems := []*model.AutomaticScenarioAssignment{
   251  		&mod1, &mod2,
   252  	}
   253  	modelPage := fixModelPageWithItems(modItems)
   254  
   255  	gql1 := fixGQLWithScenarioName("foo")
   256  	gql2 := fixGQLWithScenarioName("bar")
   257  	gqlItems := []*graphql.AutomaticScenarioAssignment{
   258  		&gql1, &gql2,
   259  	}
   260  	gqlPage := fixGQLPageWithItems(gqlItems)
   261  
   262  	txGen := txtest.NewTransactionContextGenerator(testErr)
   263  
   264  	first := 2
   265  	gqlAfter := graphql.PageCursor("test")
   266  	after := "test"
   267  
   268  	testCases := []struct {
   269  		Name            string
   270  		TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner)
   271  		ServiceFn       func() *automock.AsaService
   272  		TenantSvcFn     func() *automock.TenantService
   273  		ConverterFn     func() *automock.GqlConverter
   274  		ExpectedResult  *graphql.AutomaticScenarioAssignmentPage
   275  		ExpectedErr     error
   276  	}{
   277  		{
   278  			Name:            "Success",
   279  			TransactionerFn: txGen.ThatSucceeds,
   280  			ServiceFn: func() *automock.AsaService {
   281  				svc := &automock.AsaService{}
   282  				svc.On("List", txtest.CtxWithDBMatcher(), first, after).Return(&modelPage, nil).Once()
   283  				return svc
   284  			},
   285  			ConverterFn: func() *automock.GqlConverter {
   286  				conv := &automock.GqlConverter{}
   287  				conv.On("ToGraphQL", mod1, externalTargetTenantID).Return(gql1).Once()
   288  				conv.On("ToGraphQL", mod2, externalTargetTenantID).Return(gql2).Once()
   289  				return conv
   290  			},
   291  			TenantSvcFn: func() *automock.TenantService {
   292  				tenantSvc := &automock.TenantService{}
   293  				tenantSvc.On("GetExternalTenant", mock.Anything, targetTenantID).Return(externalTargetTenantID, nil).Once()
   294  				tenantSvc.On("GetExternalTenant", mock.Anything, targetTenantID).Return(externalTargetTenantID, nil).Once()
   295  				return tenantSvc
   296  			},
   297  			ExpectedResult: &gqlPage,
   298  			ExpectedErr:    nil,
   299  		},
   300  		{
   301  			Name:            "Returns error when transaction begin failed",
   302  			TransactionerFn: txGen.ThatFailsOnBegin,
   303  			ServiceFn: func() *automock.AsaService {
   304  				svc := &automock.AsaService{}
   305  				return svc
   306  			},
   307  			ConverterFn: func() *automock.GqlConverter {
   308  				conv := &automock.GqlConverter{}
   309  				return conv
   310  			},
   311  			TenantSvcFn: func() *automock.TenantService {
   312  				tenantSvc := &automock.TenantService{}
   313  				return tenantSvc
   314  			},
   315  			ExpectedResult: nil,
   316  			ExpectedErr:    testErr,
   317  		},
   318  		{
   319  			Name:            "Returns error when Assignments listing failed",
   320  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   321  			ServiceFn: func() *automock.AsaService {
   322  				svc := &automock.AsaService{}
   323  				svc.On("List", txtest.CtxWithDBMatcher(), first, after).Return(nil, testErr).Once()
   324  				return svc
   325  			},
   326  			ConverterFn: func() *automock.GqlConverter {
   327  				conv := &automock.GqlConverter{}
   328  				return conv
   329  			},
   330  			TenantSvcFn: func() *automock.TenantService {
   331  				tenantSvc := &automock.TenantService{}
   332  				return tenantSvc
   333  			},
   334  			ExpectedResult: nil,
   335  			ExpectedErr:    testErr,
   336  		},
   337  		{
   338  			Name:            "Returns error when GetExternalTenant failed",
   339  			TransactionerFn: txGen.ThatDoesntExpectCommit,
   340  			ServiceFn: func() *automock.AsaService {
   341  				svc := &automock.AsaService{}
   342  				svc.On("List", txtest.CtxWithDBMatcher(), first, after).Return(&modelPage, nil).Once()
   343  				return svc
   344  			},
   345  			ConverterFn: func() *automock.GqlConverter {
   346  				conv := &automock.GqlConverter{}
   347  				return conv
   348  			},
   349  			TenantSvcFn: func() *automock.TenantService {
   350  				tenantSvc := &automock.TenantService{}
   351  				tenantSvc.On("GetExternalTenant", mock.Anything, targetTenantID).Return("", testErr).Once()
   352  				return tenantSvc
   353  			},
   354  			ExpectedResult: nil,
   355  			ExpectedErr:    testErr,
   356  		},
   357  		{
   358  			Name:            "Returns error when transaction commit failed",
   359  			TransactionerFn: txGen.ThatFailsOnCommit,
   360  			ServiceFn: func() *automock.AsaService {
   361  				svc := &automock.AsaService{}
   362  				svc.On("List", txtest.CtxWithDBMatcher(), first, after).Return(&modelPage, nil).Once()
   363  				return svc
   364  			},
   365  			ConverterFn: func() *automock.GqlConverter {
   366  				conv := &automock.GqlConverter{}
   367  				conv.On("ToGraphQL", mod1, externalTargetTenantID).Return(gql1).Once()
   368  				conv.On("ToGraphQL", mod2, externalTargetTenantID).Return(gql2).Once()
   369  				return conv
   370  			},
   371  			TenantSvcFn: func() *automock.TenantService {
   372  				tenantSvc := &automock.TenantService{}
   373  				tenantSvc.On("GetExternalTenant", mock.Anything, targetTenantID).Return(externalTargetTenantID, nil).Once()
   374  				tenantSvc.On("GetExternalTenant", mock.Anything, targetTenantID).Return(externalTargetTenantID, nil).Once()
   375  				return tenantSvc
   376  			},
   377  			ExpectedResult: nil,
   378  			ExpectedErr:    testErr,
   379  		},
   380  	}
   381  
   382  	for _, testCase := range testCases {
   383  		t.Run(testCase.Name, func(t *testing.T) {
   384  			// GIVEN
   385  			persist, transact := testCase.TransactionerFn()
   386  			svc := testCase.ServiceFn()
   387  			converter := testCase.ConverterFn()
   388  			tenantSvc := testCase.TenantSvcFn()
   389  
   390  			resolver := scenarioassignment.NewResolver(transact, svc, converter, tenantSvc)
   391  
   392  			// WHEN
   393  			result, err := resolver.AutomaticScenarioAssignments(context.TODO(), &first, &gqlAfter)
   394  
   395  			// THEN
   396  			assert.Equal(t, testCase.ExpectedResult, result)
   397  			if testCase.ExpectedErr != nil {
   398  				require.Error(t, err)
   399  				assert.Contains(t, err.Error(), testErr.Error())
   400  			}
   401  
   402  			mock.AssertExpectationsForObjects(t, persist, transact, svc, converter, tenantSvc)
   403  		})
   404  	}
   405  }