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

     1  package bundlereferences_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/kyma-incubator/compass/components/director/pkg/str"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/internal/domain/bundlereferences"
    10  	"github.com/kyma-incubator/compass/components/director/internal/domain/bundlereferences/automock"
    11  	"github.com/kyma-incubator/compass/components/director/internal/model"
    12  	"github.com/pkg/errors"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestService_GetForBundle(t *testing.T) {
    18  	testErr := errors.New("test err")
    19  
    20  	objectID := "id"
    21  	bundleID := "bundleID"
    22  	targetURL := "http://test.com"
    23  
    24  	bundleReferenceModel := &model.BundleReference{
    25  		BundleID:            &bundleID,
    26  		ObjectType:          model.BundleAPIReference,
    27  		ObjectID:            &objectID,
    28  		APIDefaultTargetURL: &targetURL,
    29  	}
    30  
    31  	ctx := context.TODO()
    32  
    33  	testCases := []struct {
    34  		Name         string
    35  		RepositoryFn func() *automock.BundleReferenceRepository
    36  		Expected     *model.BundleReference
    37  		ExpectedErr  error
    38  	}{
    39  		{
    40  			Name: "Success",
    41  			RepositoryFn: func() *automock.BundleReferenceRepository {
    42  				repo := &automock.BundleReferenceRepository{}
    43  				repo.On("GetByID", ctx, model.BundleAPIReference, &objectID, &bundleID).Return(bundleReferenceModel, nil).Once()
    44  				return repo
    45  			},
    46  			Expected: bundleReferenceModel,
    47  		},
    48  		{
    49  			Name: "Error on getting by id",
    50  			RepositoryFn: func() *automock.BundleReferenceRepository {
    51  				repo := &automock.BundleReferenceRepository{}
    52  				repo.On("GetByID", ctx, model.BundleAPIReference, &objectID, &bundleID).Return(nil, testErr).Once()
    53  				return repo
    54  			},
    55  			ExpectedErr: testErr,
    56  		},
    57  	}
    58  
    59  	for _, testCase := range testCases {
    60  		t.Run(testCase.Name, func(t *testing.T) {
    61  			// GIVEN
    62  			repo := testCase.RepositoryFn()
    63  			svc := bundlereferences.NewService(repo, nil)
    64  
    65  			// WHEN
    66  			bndlRef, err := svc.GetForBundle(ctx, model.BundleAPIReference, &objectID, &bundleID)
    67  
    68  			// THEN
    69  			if testCase.ExpectedErr != nil {
    70  				require.Error(t, err)
    71  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
    72  				assert.Equal(t, testCase.Expected, bndlRef)
    73  			}
    74  
    75  			repo.AssertExpectations(t)
    76  		})
    77  	}
    78  }
    79  
    80  func TestService_GetBundleIDsForObject(t *testing.T) {
    81  	testErr := errors.New("test err")
    82  
    83  	objectID := "id"
    84  	firstBundleID := "bundleID"
    85  	secondBundleID := "bundleID2"
    86  
    87  	bundleIDs := []string{firstBundleID, secondBundleID}
    88  
    89  	ctx := context.TODO()
    90  
    91  	testCases := []struct {
    92  		Name         string
    93  		RepositoryFn func() *automock.BundleReferenceRepository
    94  		Expected     []string
    95  		ExpectedErr  error
    96  	}{
    97  		{
    98  			Name: "Success",
    99  			RepositoryFn: func() *automock.BundleReferenceRepository {
   100  				repo := &automock.BundleReferenceRepository{}
   101  				repo.On("GetBundleIDsForObject", ctx, model.BundleAPIReference, &objectID).Return(bundleIDs, nil).Once()
   102  				return repo
   103  			},
   104  			Expected: bundleIDs,
   105  		},
   106  		{
   107  			Name: "Error on getting bundle ids",
   108  			RepositoryFn: func() *automock.BundleReferenceRepository {
   109  				repo := &automock.BundleReferenceRepository{}
   110  				repo.On("GetBundleIDsForObject", ctx, model.BundleAPIReference, &objectID).Return(nil, testErr).Once()
   111  				return repo
   112  			},
   113  			ExpectedErr: testErr,
   114  		},
   115  	}
   116  
   117  	for _, testCase := range testCases {
   118  		t.Run(testCase.Name, func(t *testing.T) {
   119  			// GIVEN
   120  			repo := testCase.RepositoryFn()
   121  			svc := bundlereferences.NewService(repo, nil)
   122  
   123  			// WHEN
   124  			bndlIDs, err := svc.GetBundleIDsForObject(ctx, model.BundleAPIReference, &objectID)
   125  
   126  			// THEN
   127  			if testCase.ExpectedErr != nil {
   128  				require.Error(t, err)
   129  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
   130  				assert.Equal(t, testCase.Expected, bndlIDs)
   131  			}
   132  
   133  			repo.AssertExpectations(t)
   134  		})
   135  	}
   136  }
   137  
   138  func TestService_CreateByReferenceObjectID(t *testing.T) {
   139  	testErr := errors.New("test err")
   140  
   141  	bundleRefID := "foo"
   142  	objectID := "id"
   143  	bundleID := "bundleID"
   144  	targetURL := "http://test.com"
   145  
   146  	ctx := context.TODO()
   147  
   148  	bundleReferenceInput := &model.BundleReferenceInput{
   149  		APIDefaultTargetURL: &targetURL,
   150  	}
   151  
   152  	bundleReferenceModel := &model.BundleReference{
   153  		ID:                  bundleRefID,
   154  		BundleID:            &bundleID,
   155  		ObjectType:          model.BundleAPIReference,
   156  		ObjectID:            &objectID,
   157  		APIDefaultTargetURL: &targetURL,
   158  	}
   159  
   160  	testCases := []struct {
   161  		Name         string
   162  		RepositoryFn func() *automock.BundleReferenceRepository
   163  		UIDServiceFn func() *automock.UIDService
   164  		Input        model.BundleReferenceInput
   165  		ExpectedErr  error
   166  	}{
   167  		{
   168  			Name: "Success",
   169  			RepositoryFn: func() *automock.BundleReferenceRepository {
   170  				repo := &automock.BundleReferenceRepository{}
   171  				repo.On("Create", ctx, bundleReferenceModel).Return(nil).Once()
   172  				return repo
   173  			},
   174  			UIDServiceFn: func() *automock.UIDService {
   175  				svc := &automock.UIDService{}
   176  				svc.On("Generate").Return(bundleRefID).Once()
   177  				return svc
   178  			},
   179  			Input: *bundleReferenceInput,
   180  		},
   181  		{
   182  			Name: "Error on creation",
   183  			RepositoryFn: func() *automock.BundleReferenceRepository {
   184  				repo := &automock.BundleReferenceRepository{}
   185  				repo.On("Create", ctx, bundleReferenceModel).Return(testErr).Once()
   186  				return repo
   187  			},
   188  			UIDServiceFn: func() *automock.UIDService {
   189  				svc := &automock.UIDService{}
   190  				svc.On("Generate").Return(bundleRefID).Once()
   191  				return svc
   192  			},
   193  			Input:       *bundleReferenceInput,
   194  			ExpectedErr: testErr,
   195  		},
   196  	}
   197  
   198  	for _, testCase := range testCases {
   199  		t.Run(testCase.Name, func(t *testing.T) {
   200  			// GIVEN
   201  			repo := testCase.RepositoryFn()
   202  			uidSvc := testCase.UIDServiceFn()
   203  			svc := bundlereferences.NewService(repo, uidSvc)
   204  
   205  			// WHEN
   206  			err := svc.CreateByReferenceObjectID(ctx, testCase.Input, model.BundleAPIReference, &objectID, &bundleID)
   207  
   208  			// THEN
   209  			if testCase.ExpectedErr != nil {
   210  				require.Error(t, err)
   211  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
   212  			}
   213  
   214  			repo.AssertExpectations(t)
   215  		})
   216  	}
   217  }
   218  
   219  func TestService_UpdateByReferenceObjectID(t *testing.T) {
   220  	testErr := errors.New("test err")
   221  
   222  	objectID := "id"
   223  	bundleID := "bundleID"
   224  	targetURL := "http://test.com"
   225  	updatedTargetURL := "http://test-updated.com"
   226  
   227  	ctx := context.TODO()
   228  
   229  	bundleReferenceInput := &model.BundleReferenceInput{
   230  		APIDefaultTargetURL: &updatedTargetURL,
   231  	}
   232  
   233  	bundleReferenceModelBefore := &model.BundleReference{
   234  		BundleID:            &bundleID,
   235  		ObjectType:          model.BundleAPIReference,
   236  		ObjectID:            &objectID,
   237  		APIDefaultTargetURL: &targetURL,
   238  	}
   239  
   240  	bundleReferenceModelAfter := &model.BundleReference{
   241  		BundleID:            &bundleID,
   242  		ObjectType:          model.BundleAPIReference,
   243  		ObjectID:            &objectID,
   244  		APIDefaultTargetURL: &updatedTargetURL,
   245  	}
   246  
   247  	testCases := []struct {
   248  		Name         string
   249  		RepositoryFn func() *automock.BundleReferenceRepository
   250  		Input        model.BundleReferenceInput
   251  		ExpectedErr  error
   252  	}{
   253  		{
   254  			Name: "Success",
   255  			RepositoryFn: func() *automock.BundleReferenceRepository {
   256  				repo := &automock.BundleReferenceRepository{}
   257  				repo.On("GetByID", ctx, model.BundleAPIReference, &objectID, &bundleID).Return(bundleReferenceModelBefore, nil).Once()
   258  				repo.On("Update", ctx, bundleReferenceModelAfter).Return(nil).Once()
   259  				return repo
   260  			},
   261  			Input: *bundleReferenceInput,
   262  		},
   263  		{
   264  			Name: "Error on getting by id",
   265  			RepositoryFn: func() *automock.BundleReferenceRepository {
   266  				repo := &automock.BundleReferenceRepository{}
   267  				repo.On("GetByID", ctx, model.BundleAPIReference, &objectID, &bundleID).Return(nil, testErr).Once()
   268  				return repo
   269  			},
   270  			Input:       *bundleReferenceInput,
   271  			ExpectedErr: testErr,
   272  		},
   273  		{
   274  			Name: "Error on update",
   275  			RepositoryFn: func() *automock.BundleReferenceRepository {
   276  				repo := &automock.BundleReferenceRepository{}
   277  				repo.On("GetByID", ctx, model.BundleAPIReference, &objectID, &bundleID).Return(bundleReferenceModelBefore, nil).Once()
   278  				repo.On("Update", ctx, bundleReferenceModelAfter).Return(testErr).Once()
   279  				return repo
   280  			},
   281  			Input:       *bundleReferenceInput,
   282  			ExpectedErr: testErr,
   283  		},
   284  	}
   285  
   286  	for _, testCase := range testCases {
   287  		t.Run(testCase.Name, func(t *testing.T) {
   288  			// GIVEN
   289  			repo := testCase.RepositoryFn()
   290  			svc := bundlereferences.NewService(repo, nil)
   291  
   292  			// WHEN
   293  			err := svc.UpdateByReferenceObjectID(ctx, testCase.Input, model.BundleAPIReference, &objectID, &bundleID)
   294  
   295  			// THEN
   296  			if testCase.ExpectedErr != nil {
   297  				require.Error(t, err)
   298  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
   299  			}
   300  
   301  			repo.AssertExpectations(t)
   302  		})
   303  	}
   304  }
   305  
   306  func TestService_DeleteByReferenceObjectID(t *testing.T) {
   307  	testErr := errors.New("test err")
   308  
   309  	objectID := "id"
   310  	bundleID := "bundleID"
   311  
   312  	ctx := context.TODO()
   313  
   314  	testCases := []struct {
   315  		Name         string
   316  		RepositoryFn func() *automock.BundleReferenceRepository
   317  		ExpectedErr  error
   318  	}{
   319  		{
   320  			Name: "Success",
   321  			RepositoryFn: func() *automock.BundleReferenceRepository {
   322  				repo := &automock.BundleReferenceRepository{}
   323  				repo.On("DeleteByReferenceObjectID", ctx, bundleID, model.BundleAPIReference, objectID).Return(nil).Once()
   324  				return repo
   325  			},
   326  		},
   327  		{
   328  			Name: "Error on deletion",
   329  			RepositoryFn: func() *automock.BundleReferenceRepository {
   330  				repo := &automock.BundleReferenceRepository{}
   331  				repo.On("DeleteByReferenceObjectID", ctx, bundleID, model.BundleAPIReference, objectID).Return(testErr).Once()
   332  				return repo
   333  			},
   334  			ExpectedErr: testErr,
   335  		},
   336  	}
   337  
   338  	for _, testCase := range testCases {
   339  		t.Run(testCase.Name, func(t *testing.T) {
   340  			// GIVEN
   341  			repo := testCase.RepositoryFn()
   342  			svc := bundlereferences.NewService(repo, nil)
   343  
   344  			// WHEN
   345  			err := svc.DeleteByReferenceObjectID(ctx, model.BundleAPIReference, &objectID, &bundleID)
   346  
   347  			// THEN
   348  			if testCase.ExpectedErr != nil {
   349  				require.Error(t, err)
   350  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
   351  			}
   352  
   353  			repo.AssertExpectations(t)
   354  		})
   355  	}
   356  }
   357  
   358  func TestService_ListByBundleIDs(t *testing.T) {
   359  	testErr := errors.New("test err")
   360  
   361  	firstAPIDefID := "apiID"
   362  	secondAPIDefID := "apiID2"
   363  	firstBundleID := "bundleID"
   364  	secondBundleID := "bundleID2"
   365  	bundleIDs := []string{firstBundleID, secondBundleID}
   366  
   367  	firstAPIDefBundleRef := fixAPIBundleReferenceModel()
   368  	firstAPIDefBundleRef.BundleID = str.Ptr(firstBundleID)
   369  	firstAPIDefBundleRef.ObjectID = str.Ptr(firstAPIDefID)
   370  
   371  	secondAPIDefBundleRef := fixAPIBundleReferenceModel()
   372  	secondAPIDefBundleRef.BundleID = str.Ptr(secondBundleID)
   373  	secondAPIDefBundleRef.ObjectID = str.Ptr(secondAPIDefID)
   374  	bundleRefs := []*model.BundleReference{&firstAPIDefBundleRef, &secondAPIDefBundleRef}
   375  
   376  	numberOfAPIsInFirstBundle := 1
   377  	numberOfAPIsInSecondBundle := 1
   378  	totalCounts := map[string]int{firstBundleID: numberOfAPIsInFirstBundle, secondBundleID: numberOfAPIsInSecondBundle}
   379  
   380  	after := "test"
   381  
   382  	ctx := context.TODO()
   383  
   384  	testCases := []struct {
   385  		Name                string
   386  		PageSize            int
   387  		RepositoryFn        func() *automock.BundleReferenceRepository
   388  		ExpectedBundleRefs  []*model.BundleReference
   389  		ExpectedTotalCounts map[string]int
   390  		ExpectedErrMessage  string
   391  	}{
   392  		{
   393  			Name: "Success",
   394  			RepositoryFn: func() *automock.BundleReferenceRepository {
   395  				repo := &automock.BundleReferenceRepository{}
   396  				repo.On("ListByBundleIDs", ctx, model.BundleAPIReference, bundleIDs, 2, after).Return(bundleRefs, totalCounts, nil).Once()
   397  				return repo
   398  			},
   399  			PageSize:            2,
   400  			ExpectedBundleRefs:  bundleRefs,
   401  			ExpectedTotalCounts: totalCounts,
   402  		},
   403  		{
   404  			Name: "Return error when page size is less than 1",
   405  			RepositoryFn: func() *automock.BundleReferenceRepository {
   406  				repo := &automock.BundleReferenceRepository{}
   407  				return repo
   408  			},
   409  			PageSize:           0,
   410  			ExpectedErrMessage: "page size must be between 1 and 200",
   411  		},
   412  		{
   413  			Name: "Return error when page size is more than 200",
   414  			RepositoryFn: func() *automock.BundleReferenceRepository {
   415  				repo := &automock.BundleReferenceRepository{}
   416  				return repo
   417  			},
   418  			PageSize:           201,
   419  			ExpectedErrMessage: "page size must be between 1 and 200",
   420  		},
   421  		{
   422  			Name: "Error on listing bundle references",
   423  			RepositoryFn: func() *automock.BundleReferenceRepository {
   424  				repo := &automock.BundleReferenceRepository{}
   425  				repo.On("ListByBundleIDs", ctx, model.BundleAPIReference, bundleIDs, 2, after).Return(nil, nil, testErr).Once()
   426  				return repo
   427  			},
   428  			PageSize:            2,
   429  			ExpectedBundleRefs:  nil,
   430  			ExpectedTotalCounts: nil,
   431  			ExpectedErrMessage:  testErr.Error(),
   432  		},
   433  	}
   434  
   435  	for _, testCase := range testCases {
   436  		t.Run(testCase.Name, func(t *testing.T) {
   437  			// GIVEN
   438  			repo := testCase.RepositoryFn()
   439  			svc := bundlereferences.NewService(repo, nil)
   440  
   441  			// WHEN
   442  			bndlRefs, counts, err := svc.ListByBundleIDs(ctx, model.BundleAPIReference, bundleIDs, testCase.PageSize, after)
   443  
   444  			// THEN
   445  			if testCase.ExpectedErrMessage == "" {
   446  				require.NoError(t, err)
   447  				assert.Equal(t, testCase.ExpectedBundleRefs, bndlRefs)
   448  				assert.Equal(t, testCase.ExpectedTotalCounts[firstBundleID], counts[firstBundleID])
   449  				assert.Equal(t, testCase.ExpectedTotalCounts[secondBundleID], counts[secondBundleID])
   450  			} else {
   451  				require.Error(t, err)
   452  				assert.Contains(t, err.Error(), testCase.ExpectedErrMessage)
   453  			}
   454  
   455  			repo.AssertExpectations(t)
   456  		})
   457  	}
   458  }