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

     1  package eventdef_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/kyma-incubator/compass/components/director/internal/uid"
     9  
    10  	"github.com/kyma-incubator/compass/components/director/pkg/str"
    11  
    12  	event "github.com/kyma-incubator/compass/components/director/internal/domain/eventdef"
    13  	"github.com/kyma-incubator/compass/components/director/internal/domain/eventdef/automock"
    14  	"github.com/kyma-incubator/compass/components/director/internal/domain/tenant"
    15  	"github.com/kyma-incubator/compass/components/director/internal/model"
    16  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
    17  	"github.com/kyma-incubator/compass/components/director/pkg/pagination"
    18  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
    19  	"github.com/pkg/errors"
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/stretchr/testify/mock"
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  func TestService_Get(t *testing.T) {
    26  	// GIVEN
    27  	testErr := errors.New("Test error")
    28  
    29  	id := "foo"
    30  	name := "foo"
    31  
    32  	eventDefinition := fixEventDefinitionModel(id, name)
    33  
    34  	ctx := context.TODO()
    35  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
    36  
    37  	testCases := []struct {
    38  		Name               string
    39  		RepositoryFn       func() *automock.EventAPIRepository
    40  		Input              model.EventDefinitionInput
    41  		InputID            string
    42  		ExpectedDocument   *model.EventDefinition
    43  		ExpectedErrMessage string
    44  	}{
    45  		{
    46  			Name: "Success",
    47  			RepositoryFn: func() *automock.EventAPIRepository {
    48  				repo := &automock.EventAPIRepository{}
    49  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinition, nil).Once()
    50  				return repo
    51  			},
    52  			InputID:            id,
    53  			ExpectedDocument:   eventDefinition,
    54  			ExpectedErrMessage: "",
    55  		},
    56  		{
    57  			Name: "Returns error when EventDefinition retrieval failed",
    58  			RepositoryFn: func() *automock.EventAPIRepository {
    59  				repo := &automock.EventAPIRepository{}
    60  				repo.On("GetByID", ctx, tenantID, id).Return(nil, testErr).Once()
    61  				return repo
    62  			},
    63  			InputID:            id,
    64  			ExpectedDocument:   eventDefinition,
    65  			ExpectedErrMessage: testErr.Error(),
    66  		},
    67  	}
    68  
    69  	for _, testCase := range testCases {
    70  		t.Run(testCase.Name, func(t *testing.T) {
    71  			repo := testCase.RepositoryFn()
    72  			svc := event.NewService(repo, nil, nil, nil)
    73  
    74  			// WHEN
    75  			document, err := svc.Get(ctx, testCase.InputID)
    76  
    77  			// then
    78  			if testCase.ExpectedErrMessage == "" {
    79  				require.NoError(t, err)
    80  				assert.Equal(t, testCase.ExpectedDocument, document)
    81  			} else {
    82  				require.Error(t, err)
    83  				assert.Contains(t, err.Error(), testCase.ExpectedErrMessage)
    84  			}
    85  
    86  			repo.AssertExpectations(t)
    87  		})
    88  	}
    89  	t.Run("Error when tenant not in context", func(t *testing.T) {
    90  		svc := event.NewService(nil, nil, nil, nil)
    91  		// WHEN
    92  		_, err := svc.Get(context.TODO(), "")
    93  		// THEN
    94  		require.Error(t, err)
    95  		assert.Contains(t, err.Error(), "cannot read tenant from context")
    96  	})
    97  }
    98  
    99  func TestService_GetForBundle(t *testing.T) {
   100  	// GIVEN
   101  	testErr := errors.New("Test error")
   102  
   103  	id := "foo"
   104  	bndlID := "foobar"
   105  	name := "foo"
   106  
   107  	eventDefinition := fixEventDefinitionModel(id, name)
   108  
   109  	ctx := context.TODO()
   110  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
   111  
   112  	testCases := []struct {
   113  		Name               string
   114  		RepositoryFn       func() *automock.EventAPIRepository
   115  		Input              model.EventDefinitionInput
   116  		InputID            string
   117  		BundleID           string
   118  		ExpectedEvent      *model.EventDefinition
   119  		ExpectedErrMessage string
   120  	}{
   121  		{
   122  			Name: "Success",
   123  			RepositoryFn: func() *automock.EventAPIRepository {
   124  				repo := &automock.EventAPIRepository{}
   125  				repo.On("GetForBundle", ctx, tenantID, id, bndlID).Return(eventDefinition, nil).Once()
   126  				return repo
   127  			},
   128  			InputID:            id,
   129  			BundleID:           bndlID,
   130  			ExpectedEvent:      eventDefinition,
   131  			ExpectedErrMessage: "",
   132  		},
   133  		{
   134  			Name: "Returns error when EventDefinition retrieval failed",
   135  			RepositoryFn: func() *automock.EventAPIRepository {
   136  				repo := &automock.EventAPIRepository{}
   137  				repo.On("GetForBundle", ctx, tenantID, id, bndlID).Return(nil, testErr).Once()
   138  				return repo
   139  			},
   140  			InputID:            id,
   141  			BundleID:           bndlID,
   142  			ExpectedEvent:      nil,
   143  			ExpectedErrMessage: testErr.Error(),
   144  		},
   145  	}
   146  
   147  	for _, testCase := range testCases {
   148  		t.Run(testCase.Name, func(t *testing.T) {
   149  			repo := testCase.RepositoryFn()
   150  			svc := event.NewService(repo, nil, nil, nil)
   151  
   152  			// WHEN
   153  			eventDef, err := svc.GetForBundle(ctx, testCase.InputID, testCase.BundleID)
   154  
   155  			// then
   156  			if testCase.ExpectedErrMessage == "" {
   157  				require.NoError(t, err)
   158  				assert.Equal(t, testCase.ExpectedEvent, eventDef)
   159  			} else {
   160  				require.Error(t, err)
   161  				assert.Contains(t, err.Error(), testCase.ExpectedErrMessage)
   162  			}
   163  
   164  			repo.AssertExpectations(t)
   165  		})
   166  	}
   167  	t.Run("Error when tenant not in context", func(t *testing.T) {
   168  		svc := event.NewService(nil, nil, nil, nil)
   169  		// WHEN
   170  		_, err := svc.GetForBundle(context.TODO(), "", "")
   171  		// THEN
   172  		require.Error(t, err)
   173  		assert.Contains(t, err.Error(), "cannot read tenant from context")
   174  	})
   175  }
   176  
   177  func TestService_ListByBundleIDs(t *testing.T) {
   178  	// GIVEN
   179  	testErr := errors.New("Test error")
   180  
   181  	firstEventID := "foo"
   182  	secondEventID := "foo2"
   183  	firstBundleID := "bar"
   184  	secondBundleID := "bar2"
   185  	name := "foo"
   186  	numberOfEventsInFirstBundle := 1
   187  	numberOfEventsInSecondBundle := 1
   188  	bundleIDs := []string{firstBundleID, secondBundleID}
   189  
   190  	eventFirstBundle := fixEventDefinitionModel(firstEventID, name)
   191  	eventSecondBundle := fixEventDefinitionModel(secondEventID, name)
   192  
   193  	eventFirstBundleReference := fixModelBundleReference(firstBundleID, firstEventID)
   194  	eventSecondBundleReference := fixModelBundleReference(secondBundleID, secondEventID)
   195  	bundleRefs := []*model.BundleReference{eventFirstBundleReference, eventSecondBundleReference}
   196  	totalCounts := map[string]int{firstBundleID: numberOfEventsInFirstBundle, secondBundleID: numberOfEventsInSecondBundle}
   197  
   198  	eventsFirstBundle := []*model.EventDefinition{eventFirstBundle}
   199  	eventsSecondBundle := []*model.EventDefinition{eventSecondBundle}
   200  
   201  	eventPageFirstBundle := &model.EventDefinitionPage{
   202  		Data:       eventsFirstBundle,
   203  		TotalCount: len(eventsFirstBundle),
   204  		PageInfo: &pagination.Page{
   205  			HasNextPage: false,
   206  			EndCursor:   "end",
   207  			StartCursor: "start",
   208  		},
   209  	}
   210  	eventPageSecondBundle := &model.EventDefinitionPage{
   211  		Data:       eventsSecondBundle,
   212  		TotalCount: len(eventsSecondBundle),
   213  		PageInfo: &pagination.Page{
   214  			HasNextPage: false,
   215  			EndCursor:   "end",
   216  			StartCursor: "start",
   217  		},
   218  	}
   219  
   220  	eventPages := []*model.EventDefinitionPage{eventPageFirstBundle, eventPageSecondBundle}
   221  
   222  	after := "test"
   223  
   224  	ctx := context.TODO()
   225  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
   226  
   227  	testCases := []struct {
   228  		Name               string
   229  		PageSize           int
   230  		RepositoryFn       func() *automock.EventAPIRepository
   231  		BundleRefSvcFn     func() *automock.BundleReferenceService
   232  		ExpectedResult     []*model.EventDefinitionPage
   233  		ExpectedErrMessage string
   234  	}{
   235  		{
   236  			Name: "Success",
   237  			BundleRefSvcFn: func() *automock.BundleReferenceService {
   238  				svc := &automock.BundleReferenceService{}
   239  				svc.On("ListByBundleIDs", ctx, model.BundleEventReference, bundleIDs, 2, after).Return(bundleRefs, totalCounts, nil).Once()
   240  				return svc
   241  			},
   242  			RepositoryFn: func() *automock.EventAPIRepository {
   243  				repo := &automock.EventAPIRepository{}
   244  				repo.On("ListByBundleIDs", ctx, tenantID, bundleIDs, bundleRefs, totalCounts, 2, after).Return(eventPages, nil).Once()
   245  				return repo
   246  			},
   247  			PageSize:           2,
   248  			ExpectedResult:     eventPages,
   249  			ExpectedErrMessage: "",
   250  		},
   251  		{
   252  			Name: "Return error when page size is less than 1",
   253  			BundleRefSvcFn: func() *automock.BundleReferenceService {
   254  				svc := &automock.BundleReferenceService{}
   255  				return svc
   256  			},
   257  			RepositoryFn: func() *automock.EventAPIRepository {
   258  				repo := &automock.EventAPIRepository{}
   259  				return repo
   260  			},
   261  			PageSize:           0,
   262  			ExpectedResult:     eventPages,
   263  			ExpectedErrMessage: "page size must be between 1 and 200",
   264  		},
   265  		{
   266  			Name: "Return error when page size is bigger than 200",
   267  			BundleRefSvcFn: func() *automock.BundleReferenceService {
   268  				svc := &automock.BundleReferenceService{}
   269  				return svc
   270  			},
   271  			RepositoryFn: func() *automock.EventAPIRepository {
   272  				repo := &automock.EventAPIRepository{}
   273  				return repo
   274  			},
   275  			PageSize:           201,
   276  			ExpectedResult:     eventPages,
   277  			ExpectedErrMessage: "page size must be between 1 and 200",
   278  		},
   279  		{
   280  			Name: "Returns error when EventDefinition BundleReferences listing failed",
   281  			BundleRefSvcFn: func() *automock.BundleReferenceService {
   282  				svc := &automock.BundleReferenceService{}
   283  				svc.On("ListByBundleIDs", ctx, model.BundleEventReference, bundleIDs, 2, after).Return(nil, nil, testErr).Once()
   284  				return svc
   285  			},
   286  			RepositoryFn: func() *automock.EventAPIRepository {
   287  				repo := &automock.EventAPIRepository{}
   288  				return repo
   289  			},
   290  			PageSize:           2,
   291  			ExpectedResult:     nil,
   292  			ExpectedErrMessage: testErr.Error(),
   293  		},
   294  		{
   295  			Name: "Returns error when EventDefinition listing failed",
   296  			BundleRefSvcFn: func() *automock.BundleReferenceService {
   297  				svc := &automock.BundleReferenceService{}
   298  				svc.On("ListByBundleIDs", ctx, model.BundleEventReference, bundleIDs, 2, after).Return(bundleRefs, totalCounts, nil).Once()
   299  				return svc
   300  			},
   301  			RepositoryFn: func() *automock.EventAPIRepository {
   302  				repo := &automock.EventAPIRepository{}
   303  				repo.On("ListByBundleIDs", ctx, tenantID, bundleIDs, bundleRefs, totalCounts, 2, after).Return(nil, testErr).Once()
   304  				return repo
   305  			},
   306  			PageSize:           2,
   307  			ExpectedResult:     nil,
   308  			ExpectedErrMessage: testErr.Error(),
   309  		},
   310  	}
   311  
   312  	for _, testCase := range testCases {
   313  		t.Run(testCase.Name, func(t *testing.T) {
   314  			repo := testCase.RepositoryFn()
   315  			bndlRefSvc := testCase.BundleRefSvcFn()
   316  
   317  			svc := event.NewService(repo, nil, nil, bndlRefSvc)
   318  
   319  			// WHEN
   320  			events, err := svc.ListByBundleIDs(ctx, bundleIDs, testCase.PageSize, after)
   321  
   322  			// then
   323  			if testCase.ExpectedErrMessage == "" {
   324  				require.NoError(t, err)
   325  				assert.Equal(t, testCase.ExpectedResult, events)
   326  			} else {
   327  				require.Error(t, err)
   328  				assert.Contains(t, err.Error(), testCase.ExpectedErrMessage)
   329  			}
   330  
   331  			repo.AssertExpectations(t)
   332  		})
   333  	}
   334  	t.Run("Error when tenant not in context", func(t *testing.T) {
   335  		svc := event.NewService(nil, nil, nil, nil)
   336  		// WHEN
   337  		_, err := svc.ListByBundleIDs(context.TODO(), nil, 5, "")
   338  		// THEN
   339  		require.Error(t, err)
   340  		assert.Contains(t, err.Error(), "cannot read tenant from context")
   341  	})
   342  }
   343  
   344  func TestService_ListByApplicationID(t *testing.T) {
   345  	// GIVEN
   346  	testErr := errors.New("Test error")
   347  
   348  	id := "foo"
   349  	name := "foo"
   350  
   351  	apiDefinitions := []*model.EventDefinition{
   352  		fixEventDefinitionModel(id, name),
   353  		fixEventDefinitionModel(id, name),
   354  		fixEventDefinitionModel(id, name),
   355  	}
   356  
   357  	ctx := context.TODO()
   358  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
   359  
   360  	testCases := []struct {
   361  		Name               string
   362  		RepositoryFn       func() *automock.EventAPIRepository
   363  		ExpectedResult     []*model.EventDefinition
   364  		ExpectedErrMessage string
   365  	}{
   366  		{
   367  			Name: "Success",
   368  			RepositoryFn: func() *automock.EventAPIRepository {
   369  				repo := &automock.EventAPIRepository{}
   370  				repo.On("ListByResourceID", ctx, tenantID, appID, resource.Application).Return(apiDefinitions, nil).Once()
   371  				return repo
   372  			},
   373  			ExpectedResult:     apiDefinitions,
   374  			ExpectedErrMessage: "",
   375  		},
   376  		{
   377  			Name: "Returns error when EventDefinition listing failed",
   378  			RepositoryFn: func() *automock.EventAPIRepository {
   379  				repo := &automock.EventAPIRepository{}
   380  				repo.On("ListByResourceID", ctx, tenantID, appID, resource.Application).Return(nil, testErr).Once()
   381  				return repo
   382  			},
   383  			ExpectedResult:     nil,
   384  			ExpectedErrMessage: testErr.Error(),
   385  		},
   386  	}
   387  
   388  	for _, testCase := range testCases {
   389  		t.Run(testCase.Name, func(t *testing.T) {
   390  			repo := testCase.RepositoryFn()
   391  
   392  			svc := event.NewService(repo, nil, nil, nil)
   393  
   394  			// WHEN
   395  			docs, err := svc.ListByApplicationID(ctx, appID)
   396  
   397  			// then
   398  			if testCase.ExpectedErrMessage == "" {
   399  				require.NoError(t, err)
   400  				assert.Equal(t, testCase.ExpectedResult, docs)
   401  			} else {
   402  				require.Error(t, err)
   403  				assert.Contains(t, err.Error(), testCase.ExpectedErrMessage)
   404  			}
   405  
   406  			repo.AssertExpectations(t)
   407  		})
   408  	}
   409  	t.Run("Error when tenant not in context", func(t *testing.T) {
   410  		svc := event.NewService(nil, nil, nil, nil)
   411  		// WHEN
   412  		_, err := svc.ListByApplicationID(context.TODO(), "")
   413  		// THEN
   414  		require.Error(t, err)
   415  		assert.Contains(t, err.Error(), "cannot read tenant from context")
   416  	})
   417  }
   418  
   419  func TestService_ListByApplicationTemplateVersionID(t *testing.T) {
   420  	// GIVEN
   421  	testErr := errors.New("Test error")
   422  
   423  	id := "foo"
   424  	name := "foo"
   425  
   426  	apiDefinitions := []*model.EventDefinition{
   427  		fixEventDefinitionModel(id, name),
   428  		fixEventDefinitionModel(id, name),
   429  		fixEventDefinitionModel(id, name),
   430  	}
   431  
   432  	ctx := context.TODO()
   433  
   434  	testCases := []struct {
   435  		Name               string
   436  		RepositoryFn       func() *automock.EventAPIRepository
   437  		ExpectedResult     []*model.EventDefinition
   438  		ExpectedErrMessage string
   439  	}{
   440  		{
   441  			Name: "Success",
   442  			RepositoryFn: func() *automock.EventAPIRepository {
   443  				repo := &automock.EventAPIRepository{}
   444  				repo.On("ListByResourceID", ctx, "", appTemplateVersionID, resource.ApplicationTemplateVersion).Return(apiDefinitions, nil).Once()
   445  				return repo
   446  			},
   447  			ExpectedResult:     apiDefinitions,
   448  			ExpectedErrMessage: "",
   449  		},
   450  		{
   451  			Name: "Returns error when EventDefinition listing failed",
   452  			RepositoryFn: func() *automock.EventAPIRepository {
   453  				repo := &automock.EventAPIRepository{}
   454  				repo.On("ListByResourceID", ctx, "", appTemplateVersionID, resource.ApplicationTemplateVersion).Return(nil, testErr).Once()
   455  				return repo
   456  			},
   457  			ExpectedResult:     nil,
   458  			ExpectedErrMessage: testErr.Error(),
   459  		},
   460  	}
   461  
   462  	for _, testCase := range testCases {
   463  		t.Run(testCase.Name, func(t *testing.T) {
   464  			repo := testCase.RepositoryFn()
   465  
   466  			svc := event.NewService(repo, nil, nil, nil)
   467  
   468  			// WHEN
   469  			docs, err := svc.ListByApplicationTemplateVersionID(ctx, appTemplateVersionID)
   470  
   471  			// then
   472  			if testCase.ExpectedErrMessage == "" {
   473  				require.NoError(t, err)
   474  				assert.Equal(t, testCase.ExpectedResult, docs)
   475  			} else {
   476  				require.Error(t, err)
   477  				assert.Contains(t, err.Error(), testCase.ExpectedErrMessage)
   478  			}
   479  
   480  			repo.AssertExpectations(t)
   481  		})
   482  	}
   483  }
   484  
   485  func TestService_ListByApplicationIDPage(t *testing.T) {
   486  	// GIVEN
   487  	testErr := errors.New("Test error")
   488  
   489  	id := "foo"
   490  	name := "foo"
   491  	pageSize := 1
   492  	invalidPageSize := 0
   493  	cursor := ""
   494  
   495  	eventDefinitions := []*model.EventDefinition{
   496  		fixEventDefinitionModel(id, name),
   497  		fixEventDefinitionModel(id, name),
   498  		fixEventDefinitionModel(id, name),
   499  	}
   500  
   501  	eventDefinitionsPage := &model.EventDefinitionPage{
   502  		Data: eventDefinitions,
   503  		PageInfo: &pagination.Page{
   504  			StartCursor: "",
   505  			EndCursor:   "",
   506  			HasNextPage: false,
   507  		},
   508  		TotalCount: len(eventDefinitions),
   509  	}
   510  
   511  	ctx := context.TODO()
   512  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
   513  
   514  	testCases := []struct {
   515  		Name               string
   516  		PageSize           int
   517  		RepositoryFn       func() *automock.EventAPIRepository
   518  		ExpectedResult     *model.EventDefinitionPage
   519  		ExpectedErrMessage string
   520  	}{
   521  		{
   522  			Name:     "Success",
   523  			PageSize: pageSize,
   524  			RepositoryFn: func() *automock.EventAPIRepository {
   525  				repo := &automock.EventAPIRepository{}
   526  				repo.On("ListByApplicationIDPage", ctx, tenantID, appID, pageSize, cursor).Return(eventDefinitionsPage, nil).Once()
   527  				return repo
   528  			},
   529  			ExpectedResult:     eventDefinitionsPage,
   530  			ExpectedErrMessage: "",
   531  		},
   532  		{
   533  			Name:     "Returns error when EventDefinition paging failed",
   534  			PageSize: pageSize,
   535  			RepositoryFn: func() *automock.EventAPIRepository {
   536  				repo := &automock.EventAPIRepository{}
   537  				repo.On("ListByApplicationIDPage", ctx, tenantID, appID, pageSize, cursor).Return(nil, testErr).Once()
   538  				return repo
   539  			},
   540  			ExpectedResult:     nil,
   541  			ExpectedErrMessage: testErr.Error(),
   542  		},
   543  		{
   544  			Name:     "Returns error when pageSize is out of the range 1-200",
   545  			PageSize: invalidPageSize,
   546  			RepositoryFn: func() *automock.EventAPIRepository {
   547  				repo := &automock.EventAPIRepository{}
   548  				return repo
   549  			},
   550  			ExpectedResult:     nil,
   551  			ExpectedErrMessage: "page size must be between 1 and 200",
   552  		},
   553  	}
   554  
   555  	for _, testCase := range testCases {
   556  		t.Run(testCase.Name, func(t *testing.T) {
   557  			repo := testCase.RepositoryFn()
   558  
   559  			svc := event.NewService(repo, nil, nil, nil)
   560  
   561  			// WHEN
   562  			docs, err := svc.ListByApplicationIDPage(ctx, appID, testCase.PageSize, cursor)
   563  
   564  			// THEN
   565  			if testCase.ExpectedErrMessage == "" {
   566  				require.NoError(t, err)
   567  				assert.Equal(t, testCase.ExpectedResult, docs)
   568  			} else {
   569  				require.Error(t, err)
   570  				assert.Contains(t, err.Error(), testCase.ExpectedErrMessage)
   571  			}
   572  
   573  			repo.AssertExpectations(t)
   574  		})
   575  	}
   576  	t.Run("Error when tenant not in context", func(t *testing.T) {
   577  		svc := event.NewService(nil, nil, nil, nil)
   578  		// WHEN
   579  		_, err := svc.ListByApplicationID(context.TODO(), "")
   580  		// THEN
   581  		require.Error(t, err)
   582  		assert.Contains(t, err.Error(), "cannot read tenant from context")
   583  	})
   584  }
   585  
   586  func TestService_Create(t *testing.T) {
   587  	// GIVEN
   588  	testErr := errors.New("Test error")
   589  
   590  	id := "foo"
   591  	bundleID := "bndlid"
   592  	bundleID2 := "bndlid2"
   593  	packageID := packageID
   594  	name := "Foo"
   595  
   596  	timestamp := time.Now()
   597  	frURL := "foo.bar"
   598  	spec := "test"
   599  	spec2 := "test2"
   600  
   601  	modelInput := model.EventDefinitionInput{
   602  		Name:         name,
   603  		VersionInput: &model.VersionInput{},
   604  	}
   605  
   606  	modelSpecsInput := []*model.SpecInput{
   607  		{
   608  			Data: &spec,
   609  			FetchRequest: &model.FetchRequestInput{
   610  				URL: frURL,
   611  			},
   612  		},
   613  		{
   614  			Data: &spec2,
   615  			FetchRequest: &model.FetchRequestInput{
   616  				URL: frURL,
   617  			},
   618  		},
   619  	}
   620  
   621  	modelEventDefinition := &model.EventDefinition{
   622  		PackageID:     &packageID,
   623  		ApplicationID: &appID,
   624  		Name:          name,
   625  		Version:       &model.Version{},
   626  		BaseEntity: &model.BaseEntity{
   627  			ID:    id,
   628  			Ready: true,
   629  		},
   630  	}
   631  
   632  	bundleReferenceInput := &model.BundleReferenceInput{}
   633  	isDefault := true
   634  	bundleReferenceInputWithDefaultBundle := &model.BundleReferenceInput{IsDefaultBundle: &isDefault}
   635  	bundleIDs := []string{bundleID, bundleID2}
   636  
   637  	ctx := context.TODO()
   638  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
   639  
   640  	testCases := []struct {
   641  		Name              string
   642  		RepositoryFn      func() *automock.EventAPIRepository
   643  		UIDServiceFn      func() *automock.UIDService
   644  		SpecServiceFn     func() *automock.SpecService
   645  		BundleReferenceFn func() *automock.BundleReferenceService
   646  		Input             model.EventDefinitionInput
   647  		SpecsInput        []*model.SpecInput
   648  		BundleIDs         []string
   649  		DefaultBundleID   string
   650  		ResourceType      resource.Type
   651  		ResourceID        string
   652  		ExpectedErr       error
   653  	}{
   654  		{
   655  			Name: "Success",
   656  			RepositoryFn: func() *automock.EventAPIRepository {
   657  				repo := &automock.EventAPIRepository{}
   658  				repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once()
   659  				return repo
   660  			},
   661  			UIDServiceFn: func() *automock.UIDService {
   662  				svc := &automock.UIDService{}
   663  				svc.On("Generate").Return(id).Once()
   664  				return svc
   665  			},
   666  			SpecServiceFn: func() *automock.SpecService {
   667  				svc := &automock.SpecService{}
   668  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
   669  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[1], resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
   670  				return svc
   671  			},
   672  			BundleReferenceFn: func() *automock.BundleReferenceService {
   673  				svc := &automock.BundleReferenceService{}
   674  				svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID)).Return(nil).Once()
   675  				return svc
   676  			},
   677  			Input:        modelInput,
   678  			SpecsInput:   modelSpecsInput,
   679  			ResourceType: resource.Application,
   680  			ResourceID:   appID,
   681  		},
   682  		{
   683  			Name: "Success in ORD scenario where many bundle ids are passed",
   684  			RepositoryFn: func() *automock.EventAPIRepository {
   685  				repo := &automock.EventAPIRepository{}
   686  				repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once()
   687  				return repo
   688  			},
   689  			UIDServiceFn: func() *automock.UIDService {
   690  				svc := &automock.UIDService{}
   691  				svc.On("Generate").Return(id).Once()
   692  				return svc
   693  			},
   694  			SpecServiceFn: func() *automock.SpecService {
   695  				svc := &automock.SpecService{}
   696  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
   697  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[1], resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
   698  				return svc
   699  			},
   700  			BundleReferenceFn: func() *automock.BundleReferenceService {
   701  				svc := &automock.BundleReferenceService{}
   702  				svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInputWithDefaultBundle, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID)).Return(nil).Once()
   703  				svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID2)).Return(nil).Once()
   704  				return svc
   705  			},
   706  			Input:           modelInput,
   707  			SpecsInput:      modelSpecsInput,
   708  			BundleIDs:       bundleIDs,
   709  			DefaultBundleID: bundleID,
   710  			ResourceID:      appID,
   711  			ResourceType:    resource.Application,
   712  		},
   713  		{
   714  			Name: "Error - Event Creation",
   715  			RepositoryFn: func() *automock.EventAPIRepository {
   716  				repo := &automock.EventAPIRepository{}
   717  				repo.On("Create", ctx, tenantID, modelEventDefinition).Return(testErr).Once()
   718  				return repo
   719  			},
   720  			UIDServiceFn: func() *automock.UIDService {
   721  				svc := &automock.UIDService{}
   722  				svc.On("Generate").Return(id).Once()
   723  				return svc
   724  			},
   725  			SpecServiceFn: emptySpecService,
   726  			BundleReferenceFn: func() *automock.BundleReferenceService {
   727  				return &automock.BundleReferenceService{}
   728  			},
   729  			Input:        modelInput,
   730  			SpecsInput:   modelSpecsInput,
   731  			ResourceID:   appID,
   732  			ResourceType: resource.Application,
   733  			ExpectedErr:  testErr,
   734  		},
   735  		{
   736  			Name: "Error - Spec Creation",
   737  			RepositoryFn: func() *automock.EventAPIRepository {
   738  				repo := &automock.EventAPIRepository{}
   739  				repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once()
   740  				return repo
   741  			},
   742  			UIDServiceFn: func() *automock.UIDService {
   743  				svc := &automock.UIDService{}
   744  				svc.On("Generate").Return(id).Once()
   745  				return svc
   746  			},
   747  			SpecServiceFn: func() *automock.SpecService {
   748  				svc := &automock.SpecService{}
   749  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("", testErr).Once()
   750  				return svc
   751  			},
   752  			BundleReferenceFn: func() *automock.BundleReferenceService {
   753  				return &automock.BundleReferenceService{}
   754  			},
   755  			Input:        modelInput,
   756  			SpecsInput:   modelSpecsInput,
   757  			ResourceID:   appID,
   758  			ResourceType: resource.Application,
   759  			ExpectedErr:  testErr,
   760  		},
   761  		{
   762  			Name: "Error - BundleReference Event Creation",
   763  			RepositoryFn: func() *automock.EventAPIRepository {
   764  				repo := &automock.EventAPIRepository{}
   765  				repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once()
   766  				return repo
   767  			},
   768  			UIDServiceFn: func() *automock.UIDService {
   769  				svc := &automock.UIDService{}
   770  				svc.On("Generate").Return(id).Once()
   771  				return svc
   772  			},
   773  			SpecServiceFn: func() *automock.SpecService {
   774  				svc := &automock.SpecService{}
   775  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
   776  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[1], resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
   777  				return svc
   778  			},
   779  			BundleReferenceFn: func() *automock.BundleReferenceService {
   780  				svc := &automock.BundleReferenceService{}
   781  				svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID)).Return(testErr).Once()
   782  				return svc
   783  			},
   784  			Input:        modelInput,
   785  			SpecsInput:   modelSpecsInput,
   786  			ResourceID:   appID,
   787  			ResourceType: resource.Application,
   788  			ExpectedErr:  testErr,
   789  		},
   790  		{
   791  			Name: "Error in ORD scenario - BundleReference Event Creation",
   792  			RepositoryFn: func() *automock.EventAPIRepository {
   793  				repo := &automock.EventAPIRepository{}
   794  				repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once()
   795  				return repo
   796  			},
   797  			UIDServiceFn: func() *automock.UIDService {
   798  				svc := &automock.UIDService{}
   799  				svc.On("Generate").Return(id).Once()
   800  				return svc
   801  			},
   802  			SpecServiceFn: func() *automock.SpecService {
   803  				svc := &automock.SpecService{}
   804  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
   805  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[1], resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
   806  				return svc
   807  			},
   808  			BundleReferenceFn: func() *automock.BundleReferenceService {
   809  				svc := &automock.BundleReferenceService{}
   810  				svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID)).Return(nil).Once()
   811  				svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInput, model.BundleEventReference, str.Ptr(id), str.Ptr(bundleID2)).Return(testErr).Once()
   812  				return svc
   813  			},
   814  			Input:        modelInput,
   815  			SpecsInput:   modelSpecsInput,
   816  			BundleIDs:    bundleIDs,
   817  			ResourceID:   appID,
   818  			ResourceType: resource.Application,
   819  			ExpectedErr:  testErr,
   820  		},
   821  	}
   822  
   823  	for _, testCase := range testCases {
   824  		t.Run(testCase.Name, func(t *testing.T) {
   825  			// GIVEN
   826  			repo := testCase.RepositoryFn()
   827  			uidService := testCase.UIDServiceFn()
   828  			specService := testCase.SpecServiceFn()
   829  			bundleReferenceService := testCase.BundleReferenceFn()
   830  
   831  			svc := event.NewService(repo, uidService, specService, bundleReferenceService)
   832  			svc.SetTimestampGen(func() time.Time { return timestamp })
   833  
   834  			// WHEN
   835  			result, err := svc.Create(ctx, testCase.ResourceType, testCase.ResourceID, &bundleID, &packageID, testCase.Input, testCase.SpecsInput, testCase.BundleIDs, 0, testCase.DefaultBundleID)
   836  
   837  			// then
   838  			if testCase.ExpectedErr != nil {
   839  				require.Error(t, err)
   840  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
   841  			} else {
   842  				assert.IsType(t, "string", result)
   843  			}
   844  
   845  			repo.AssertExpectations(t)
   846  			specService.AssertExpectations(t)
   847  			uidService.AssertExpectations(t)
   848  			bundleReferenceService.AssertExpectations(t)
   849  		})
   850  	}
   851  	t.Run("Error when tenant not in context", func(t *testing.T) {
   852  		svc := event.NewService(nil, fixUIDSvc(), nil, nil)
   853  		// WHEN
   854  		_, err := svc.Create(context.TODO(), resource.Application, "", nil, nil, model.EventDefinitionInput{}, []*model.SpecInput{}, []string{}, 0, "")
   855  		// THEN
   856  		require.Error(t, err)
   857  		assert.Contains(t, err.Error(), "cannot read tenant from context")
   858  	})
   859  }
   860  
   861  func TestService_CreateInApplication(t *testing.T) {
   862  	// GIVEN
   863  	testErr := errors.New("Test error")
   864  
   865  	id := "foo"
   866  	name := "Foo"
   867  
   868  	timestamp := time.Now()
   869  	frURL := "foo.bar"
   870  	spec := "test"
   871  
   872  	modelInput := model.EventDefinitionInput{
   873  		Name:         name,
   874  		VersionInput: &model.VersionInput{},
   875  	}
   876  
   877  	modelSpecInput := &model.SpecInput{
   878  		Data: &spec,
   879  		FetchRequest: &model.FetchRequestInput{
   880  			URL: frURL,
   881  		},
   882  	}
   883  
   884  	modelSpecsInput := []*model.SpecInput{
   885  		modelSpecInput,
   886  	}
   887  
   888  	modelEventDefinition := &model.EventDefinition{
   889  		ApplicationID: &appID,
   890  		Name:          name,
   891  		Version:       &model.Version{},
   892  		BaseEntity: &model.BaseEntity{
   893  			ID:    id,
   894  			Ready: true,
   895  		},
   896  	}
   897  
   898  	ctx := context.TODO()
   899  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
   900  
   901  	testCases := []struct {
   902  		Name                      string
   903  		RepositoryFn              func() *automock.EventAPIRepository
   904  		UIDServiceFn              func() *automock.UIDService
   905  		SpecServiceFn             func() *automock.SpecService
   906  		Input                     model.EventDefinitionInput
   907  		SpecsInput                *model.SpecInput
   908  		DefaultTargetURLPerBundle map[string]string
   909  		DefaultBundleID           string
   910  		ExpectedErr               error
   911  	}{
   912  		{
   913  			Name: "Success",
   914  			RepositoryFn: func() *automock.EventAPIRepository {
   915  				repo := &automock.EventAPIRepository{}
   916  				repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once()
   917  				return repo
   918  			},
   919  			UIDServiceFn: func() *automock.UIDService {
   920  				svc := &automock.UIDService{}
   921  				svc.On("Generate").Return(id).Once()
   922  				return svc
   923  			},
   924  			SpecServiceFn: func() *automock.SpecService {
   925  				svc := &automock.SpecService{}
   926  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
   927  				return svc
   928  			},
   929  			Input:      modelInput,
   930  			SpecsInput: modelSpecInput,
   931  		},
   932  		{
   933  			Name: "Error - API Creation",
   934  			RepositoryFn: func() *automock.EventAPIRepository {
   935  				repo := &automock.EventAPIRepository{}
   936  				repo.On("Create", ctx, tenantID, modelEventDefinition).Return(testErr).Once()
   937  				return repo
   938  			},
   939  			UIDServiceFn: func() *automock.UIDService {
   940  				svc := &automock.UIDService{}
   941  				svc.On("Generate").Return(id).Once()
   942  				return svc
   943  			},
   944  			SpecServiceFn: emptySpecService,
   945  			Input:         modelInput,
   946  			SpecsInput:    modelSpecInput,
   947  			ExpectedErr:   testErr,
   948  		},
   949  		{
   950  			Name: "Error - Spec Creation",
   951  			RepositoryFn: func() *automock.EventAPIRepository {
   952  				repo := &automock.EventAPIRepository{}
   953  				repo.On("Create", ctx, tenantID, modelEventDefinition).Return(nil).Once()
   954  				return repo
   955  			},
   956  			UIDServiceFn: func() *automock.UIDService {
   957  				svc := &automock.UIDService{}
   958  				svc.On("Generate").Return(id).Once()
   959  				return svc
   960  			},
   961  			SpecServiceFn: func() *automock.SpecService {
   962  				svc := &automock.SpecService{}
   963  				svc.On("CreateByReferenceObjectID", ctx, *modelSpecsInput[0], resource.Application, model.EventSpecReference, id).Return("", testErr).Once()
   964  				return svc
   965  			},
   966  			Input:       modelInput,
   967  			SpecsInput:  modelSpecInput,
   968  			ExpectedErr: testErr,
   969  		},
   970  	}
   971  
   972  	for _, testCase := range testCases {
   973  		t.Run(testCase.Name, func(t *testing.T) {
   974  			// GIVEN
   975  			repo := testCase.RepositoryFn()
   976  			uidService := testCase.UIDServiceFn()
   977  			specService := testCase.SpecServiceFn()
   978  			defer mock.AssertExpectationsForObjects(t, repo, uidService, specService)
   979  
   980  			svc := event.NewService(repo, uidService, specService, nil)
   981  			svc.SetTimestampGen(func() time.Time { return timestamp })
   982  
   983  			// WHEN
   984  			result, err := svc.CreateInApplication(ctx, appID, testCase.Input, testCase.SpecsInput)
   985  
   986  			// THEN
   987  			if testCase.ExpectedErr != nil {
   988  				require.Error(t, err)
   989  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
   990  			} else {
   991  				assert.IsType(t, "string", result)
   992  			}
   993  		})
   994  	}
   995  	t.Run("Error when tenant not in context", func(t *testing.T) {
   996  		svc := event.NewService(nil, uid.NewService(), nil, nil)
   997  		// WHEN
   998  		_, err := svc.CreateInApplication(context.TODO(), "", model.EventDefinitionInput{}, &model.SpecInput{})
   999  		// THEN
  1000  		require.Error(t, err)
  1001  		assert.Contains(t, err.Error(), "cannot read tenant from context")
  1002  	})
  1003  }
  1004  
  1005  func TestService_Update(t *testing.T) {
  1006  	// GIVEN
  1007  	testErr := errors.New("Test error")
  1008  
  1009  	id := "foo"
  1010  	timestamp := time.Now()
  1011  	frURL := "foo.bar"
  1012  	spec := "spec"
  1013  
  1014  	modelInput := model.EventDefinitionInput{
  1015  		Name:         "Foo",
  1016  		VersionInput: &model.VersionInput{},
  1017  	}
  1018  
  1019  	modelSpecInput := model.SpecInput{
  1020  		Data: &spec,
  1021  		FetchRequest: &model.FetchRequestInput{
  1022  			URL: frURL,
  1023  		},
  1024  	}
  1025  
  1026  	modelSpec := &model.Spec{
  1027  		ID:         id,
  1028  		ObjectType: model.EventSpecReference,
  1029  		ObjectID:   id,
  1030  		Data:       &spec,
  1031  	}
  1032  
  1033  	inputEventDefinitionModel := mock.MatchedBy(func(event *model.EventDefinition) bool {
  1034  		return event.Name == modelInput.Name
  1035  	})
  1036  
  1037  	eventDefinitionModelForApp := &model.EventDefinition{
  1038  		Name:          "Bar",
  1039  		Version:       &model.Version{},
  1040  		ApplicationID: &appID,
  1041  	}
  1042  
  1043  	eventDefinitionModelForAppTemplateVersion := &model.EventDefinition{
  1044  		Name:                         "Bar",
  1045  		Version:                      &model.Version{},
  1046  		ApplicationTemplateVersionID: &appTemplateVersionID,
  1047  	}
  1048  
  1049  	ctx := context.TODO()
  1050  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
  1051  
  1052  	testCases := []struct {
  1053  		Name          string
  1054  		RepositoryFn  func() *automock.EventAPIRepository
  1055  		SpecServiceFn func() *automock.SpecService
  1056  		Input         model.EventDefinitionInput
  1057  		InputID       string
  1058  		SpecInput     *model.SpecInput
  1059  		ResourceType  resource.Type
  1060  		ExpectedErr   error
  1061  	}{
  1062  		{
  1063  			Name: "Success When Spec is Found should update it for Application Template Version",
  1064  			RepositoryFn: func() *automock.EventAPIRepository {
  1065  				repo := &automock.EventAPIRepository{}
  1066  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModelForAppTemplateVersion, nil).Once()
  1067  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1068  				return repo
  1069  			},
  1070  			SpecServiceFn: func() *automock.SpecService {
  1071  				svc := &automock.SpecService{}
  1072  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once()
  1073  				svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once()
  1074  				return svc
  1075  			},
  1076  			InputID:      "foo",
  1077  			Input:        modelInput,
  1078  			SpecInput:    &modelSpecInput,
  1079  			ResourceType: resource.Application,
  1080  			ExpectedErr:  nil,
  1081  		},
  1082  		{
  1083  			Name: "Success When Spec is Found should update it for Application",
  1084  			RepositoryFn: func() *automock.EventAPIRepository {
  1085  				repo := &automock.EventAPIRepository{}
  1086  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModelForApp, nil).Once()
  1087  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1088  				return repo
  1089  			},
  1090  			SpecServiceFn: func() *automock.SpecService {
  1091  				svc := &automock.SpecService{}
  1092  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once()
  1093  				svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once()
  1094  				return svc
  1095  			},
  1096  			InputID:      "foo",
  1097  			Input:        modelInput,
  1098  			SpecInput:    &modelSpecInput,
  1099  			ResourceType: resource.Application,
  1100  			ExpectedErr:  nil,
  1101  		},
  1102  		{
  1103  			Name: "Success When Spec is not found should create in",
  1104  			RepositoryFn: func() *automock.EventAPIRepository {
  1105  				repo := &automock.EventAPIRepository{}
  1106  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModelForApp, nil).Once()
  1107  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1108  				return repo
  1109  			},
  1110  			SpecServiceFn: func() *automock.SpecService {
  1111  				svc := &automock.SpecService{}
  1112  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, nil).Once()
  1113  				svc.On("CreateByReferenceObjectID", ctx, modelSpecInput, resource.Application, model.EventSpecReference, id).Return("id", nil).Once()
  1114  				return svc
  1115  			},
  1116  			InputID:      "foo",
  1117  			Input:        modelInput,
  1118  			SpecInput:    &modelSpecInput,
  1119  			ResourceType: resource.Application,
  1120  			ExpectedErr:  nil,
  1121  		},
  1122  		{
  1123  			Name: "Update Error",
  1124  			RepositoryFn: func() *automock.EventAPIRepository {
  1125  				repo := &automock.EventAPIRepository{}
  1126  				repo.On("GetByID", ctx, tenantID, "foo").Return(eventDefinitionModelForApp, nil).Once()
  1127  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(testErr).Once()
  1128  				return repo
  1129  			},
  1130  			SpecServiceFn: emptySpecService,
  1131  			InputID:       "foo",
  1132  			Input:         modelInput,
  1133  			SpecInput:     &modelSpecInput,
  1134  			ResourceType:  resource.Application,
  1135  			ExpectedErr:   testErr,
  1136  		},
  1137  		{
  1138  			Name: "Get Spec Error",
  1139  			RepositoryFn: func() *automock.EventAPIRepository {
  1140  				repo := &automock.EventAPIRepository{}
  1141  				repo.On("GetByID", ctx, tenantID, "foo").Return(eventDefinitionModelForApp, nil).Once()
  1142  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1143  				return repo
  1144  			},
  1145  			SpecServiceFn: func() *automock.SpecService {
  1146  				svc := &automock.SpecService{}
  1147  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, testErr).Once()
  1148  				return svc
  1149  			},
  1150  			InputID:      "foo",
  1151  			Input:        modelInput,
  1152  			SpecInput:    &modelSpecInput,
  1153  			ResourceType: resource.Application,
  1154  			ExpectedErr:  testErr,
  1155  		},
  1156  		{
  1157  			Name: "Spec Creation Error",
  1158  			RepositoryFn: func() *automock.EventAPIRepository {
  1159  				repo := &automock.EventAPIRepository{}
  1160  				repo.On("GetByID", ctx, tenantID, "foo").Return(eventDefinitionModelForApp, nil).Once()
  1161  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1162  				return repo
  1163  			},
  1164  			SpecServiceFn: func() *automock.SpecService {
  1165  				svc := &automock.SpecService{}
  1166  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, nil).Once()
  1167  				svc.On("CreateByReferenceObjectID", ctx, modelSpecInput, resource.Application, model.EventSpecReference, id).Return("", testErr).Once()
  1168  				return svc
  1169  			},
  1170  			InputID:      "foo",
  1171  			Input:        modelInput,
  1172  			SpecInput:    &modelSpecInput,
  1173  			ResourceType: resource.Application,
  1174  			ExpectedErr:  testErr,
  1175  		},
  1176  		{
  1177  			Name: "Spec Update Error",
  1178  			RepositoryFn: func() *automock.EventAPIRepository {
  1179  				repo := &automock.EventAPIRepository{}
  1180  				repo.On("GetByID", ctx, tenantID, "foo").Return(eventDefinitionModelForApp, nil).Once()
  1181  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1182  				return repo
  1183  			},
  1184  			SpecServiceFn: func() *automock.SpecService {
  1185  				svc := &automock.SpecService{}
  1186  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once()
  1187  				svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(testErr).Once()
  1188  				return svc
  1189  			},
  1190  			InputID:      "foo",
  1191  			Input:        modelInput,
  1192  			SpecInput:    &modelSpecInput,
  1193  			ResourceType: resource.Application,
  1194  			ExpectedErr:  testErr,
  1195  		},
  1196  	}
  1197  
  1198  	for _, testCase := range testCases {
  1199  		t.Run(testCase.Name, func(t *testing.T) {
  1200  			// GIVEN
  1201  			repo := testCase.RepositoryFn()
  1202  			specSvc := testCase.SpecServiceFn()
  1203  
  1204  			svc := event.NewService(repo, nil, specSvc, nil)
  1205  			svc.SetTimestampGen(func() time.Time { return timestamp })
  1206  
  1207  			// WHEN
  1208  			err := svc.Update(ctx, testCase.ResourceType, testCase.InputID, testCase.Input, testCase.SpecInput)
  1209  
  1210  			// then
  1211  			if testCase.ExpectedErr == nil {
  1212  				require.NoError(t, err)
  1213  			} else {
  1214  				require.Error(t, err)
  1215  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1216  			}
  1217  
  1218  			repo.AssertExpectations(t)
  1219  			specSvc.AssertExpectations(t)
  1220  		})
  1221  	}
  1222  	t.Run("Error when tenant not in context", func(t *testing.T) {
  1223  		svc := event.NewService(nil, nil, nil, nil)
  1224  		// WHEN
  1225  		err := svc.Update(context.TODO(), resource.Application, "", model.EventDefinitionInput{}, &model.SpecInput{})
  1226  		// THEN
  1227  		require.Error(t, err)
  1228  		assert.Contains(t, err.Error(), "cannot read tenant from context")
  1229  	})
  1230  }
  1231  
  1232  func TestService_UpdateManyBundles(t *testing.T) {
  1233  	// GIVEN
  1234  	testErr := errors.New("Test error")
  1235  
  1236  	id := "foo"
  1237  	bndlID1 := "id1"
  1238  	bndlID2 := "id2"
  1239  	bndlID3 := "id3"
  1240  	bndlID4 := "id4"
  1241  	bndlID5 := "id5"
  1242  	timestamp := time.Now()
  1243  	frURL := "foo.bar"
  1244  	spec := "spec"
  1245  
  1246  	modelInput := model.EventDefinitionInput{
  1247  		Name:         "Foo",
  1248  		VersionInput: &model.VersionInput{},
  1249  	}
  1250  
  1251  	modelSpecInput := model.SpecInput{
  1252  		Data: &spec,
  1253  		FetchRequest: &model.FetchRequestInput{
  1254  			URL: frURL,
  1255  		},
  1256  	}
  1257  
  1258  	modelSpec := &model.Spec{
  1259  		ID:         id,
  1260  		ObjectType: model.EventSpecReference,
  1261  		ObjectID:   id,
  1262  		Data:       &spec,
  1263  	}
  1264  
  1265  	inputEventDefinitionModel := mock.MatchedBy(func(event *model.EventDefinition) bool {
  1266  		return event.Name == modelInput.Name
  1267  	})
  1268  
  1269  	eventDefinitionModel := &model.EventDefinition{
  1270  		Name:    "Bar",
  1271  		Version: &model.Version{},
  1272  	}
  1273  
  1274  	isDefault := true
  1275  	bundleReferenceInputWithDefaultBundle := &model.BundleReferenceInput{
  1276  		IsDefaultBundle: &isDefault,
  1277  	}
  1278  
  1279  	bundleIDsForCreation := []string{bndlID1, bndlID2}
  1280  	bundleIDsForDeletion := []string{bndlID3, bndlID4}
  1281  	bundleIDsFromBundleReference := []string{bndlID5}
  1282  
  1283  	ctx := context.TODO()
  1284  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
  1285  
  1286  	testCases := []struct {
  1287  		Name                         string
  1288  		RepositoryFn                 func() *automock.EventAPIRepository
  1289  		SpecServiceFn                func() *automock.SpecService
  1290  		BundleReferenceServiceFn     func() *automock.BundleReferenceService
  1291  		Input                        model.EventDefinitionInput
  1292  		InputID                      string
  1293  		SpecInput                    *model.SpecInput
  1294  		BundleIDsForCreation         []string
  1295  		BundleIDsForDeletion         []string
  1296  		BundleIDsFromBundleReference []string
  1297  		DefaultBundleID              string
  1298  		ResourceType                 resource.Type
  1299  		ExpectedErr                  error
  1300  	}{
  1301  		{
  1302  			Name: "Success in ORD case",
  1303  			RepositoryFn: func() *automock.EventAPIRepository {
  1304  				repo := &automock.EventAPIRepository{}
  1305  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1306  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1307  				return repo
  1308  			},
  1309  			SpecServiceFn: func() *automock.SpecService {
  1310  				svc := &automock.SpecService{}
  1311  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once()
  1312  				svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once()
  1313  				return svc
  1314  			},
  1315  			BundleReferenceServiceFn: func() *automock.BundleReferenceService {
  1316  				svc := &automock.BundleReferenceService{}
  1317  				svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID1).Return(nil).Once()
  1318  				svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID2).Return(nil).Once()
  1319  				svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID3).Return(nil).Once()
  1320  				svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID4).Return(nil).Once()
  1321  				svc.On("UpdateByReferenceObjectID", ctx, *bundleReferenceInputWithDefaultBundle, model.BundleEventReference, &id, &bndlID5).Return(nil).Once()
  1322  				return svc
  1323  			},
  1324  			InputID:                      "foo",
  1325  			Input:                        modelInput,
  1326  			SpecInput:                    &modelSpecInput,
  1327  			BundleIDsForCreation:         bundleIDsForCreation,
  1328  			BundleIDsForDeletion:         bundleIDsForDeletion,
  1329  			BundleIDsFromBundleReference: bundleIDsFromBundleReference,
  1330  			DefaultBundleID:              bndlID5,
  1331  			ResourceType:                 resource.Application,
  1332  			ExpectedErr:                  nil,
  1333  		},
  1334  		{
  1335  			Name: "Success in ORD case when there is defaultBundle for BundleReference that has to be created",
  1336  			RepositoryFn: func() *automock.EventAPIRepository {
  1337  				repo := &automock.EventAPIRepository{}
  1338  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1339  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1340  				return repo
  1341  			},
  1342  			SpecServiceFn: func() *automock.SpecService {
  1343  				svc := &automock.SpecService{}
  1344  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once()
  1345  				svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once()
  1346  				return svc
  1347  			},
  1348  			BundleReferenceServiceFn: func() *automock.BundleReferenceService {
  1349  				svc := &automock.BundleReferenceService{}
  1350  				svc.On("CreateByReferenceObjectID", ctx, *bundleReferenceInputWithDefaultBundle, model.BundleEventReference, &id, &bndlID1).Return(nil).Once()
  1351  				svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID2).Return(nil).Once()
  1352  				svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID3).Return(nil).Once()
  1353  				svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID4).Return(nil).Once()
  1354  				svc.On("UpdateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID5).Return(nil).Once()
  1355  				return svc
  1356  			},
  1357  			InputID:                      "foo",
  1358  			Input:                        modelInput,
  1359  			SpecInput:                    &modelSpecInput,
  1360  			BundleIDsForCreation:         bundleIDsForCreation,
  1361  			BundleIDsForDeletion:         bundleIDsForDeletion,
  1362  			BundleIDsFromBundleReference: bundleIDsFromBundleReference,
  1363  			DefaultBundleID:              bndlID1,
  1364  			ResourceType:                 resource.Application,
  1365  			ExpectedErr:                  nil,
  1366  		},
  1367  		{
  1368  			Name: "Error on BundleReference creation",
  1369  			RepositoryFn: func() *automock.EventAPIRepository {
  1370  				repo := &automock.EventAPIRepository{}
  1371  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1372  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1373  				return repo
  1374  			},
  1375  			SpecServiceFn: emptySpecService,
  1376  			BundleReferenceServiceFn: func() *automock.BundleReferenceService {
  1377  				svc := &automock.BundleReferenceService{}
  1378  				svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID1).Return(nil).Once()
  1379  				svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID2).Return(testErr).Once()
  1380  				return svc
  1381  			},
  1382  			InputID:              "foo",
  1383  			Input:                modelInput,
  1384  			SpecInput:            &modelSpecInput,
  1385  			BundleIDsForCreation: bundleIDsForCreation,
  1386  			BundleIDsForDeletion: bundleIDsForDeletion,
  1387  			ResourceType:         resource.Application,
  1388  			ExpectedErr:          testErr,
  1389  		},
  1390  		{
  1391  			Name: "Error on BundleReference deletion",
  1392  			RepositoryFn: func() *automock.EventAPIRepository {
  1393  				repo := &automock.EventAPIRepository{}
  1394  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1395  				repo.On("Update", ctx, tenantID, inputEventDefinitionModel).Return(nil).Once()
  1396  				return repo
  1397  			},
  1398  			SpecServiceFn: emptySpecService,
  1399  			BundleReferenceServiceFn: func() *automock.BundleReferenceService {
  1400  				svc := &automock.BundleReferenceService{}
  1401  				svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID1).Return(nil).Once()
  1402  				svc.On("CreateByReferenceObjectID", ctx, model.BundleReferenceInput{}, model.BundleEventReference, &id, &bndlID2).Return(nil).Once()
  1403  				svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID3).Return(nil).Once()
  1404  				svc.On("DeleteByReferenceObjectID", ctx, model.BundleEventReference, &id, &bndlID4).Return(testErr).Once()
  1405  				return svc
  1406  			},
  1407  			InputID:              "foo",
  1408  			Input:                modelInput,
  1409  			SpecInput:            &modelSpecInput,
  1410  			BundleIDsForCreation: bundleIDsForCreation,
  1411  			BundleIDsForDeletion: bundleIDsForDeletion,
  1412  			ResourceType:         resource.Application,
  1413  			ExpectedErr:          testErr,
  1414  		},
  1415  	}
  1416  
  1417  	for _, testCase := range testCases {
  1418  		t.Run(testCase.Name, func(t *testing.T) {
  1419  			// GIVEN
  1420  			repo := testCase.RepositoryFn()
  1421  			specSvc := testCase.SpecServiceFn()
  1422  			bndlRefSvc := testCase.BundleReferenceServiceFn()
  1423  
  1424  			svc := event.NewService(repo, nil, specSvc, bndlRefSvc)
  1425  			svc.SetTimestampGen(func() time.Time { return timestamp })
  1426  
  1427  			// WHEN
  1428  			err := svc.UpdateInManyBundles(ctx, testCase.ResourceType, testCase.InputID, testCase.Input, testCase.SpecInput, testCase.BundleIDsFromBundleReference, testCase.BundleIDsForCreation, testCase.BundleIDsForDeletion, 0, testCase.DefaultBundleID)
  1429  
  1430  			// then
  1431  			if testCase.ExpectedErr == nil {
  1432  				require.NoError(t, err)
  1433  			} else {
  1434  				require.Error(t, err)
  1435  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1436  			}
  1437  
  1438  			repo.AssertExpectations(t)
  1439  			specSvc.AssertExpectations(t)
  1440  			bndlRefSvc.AssertExpectations(t)
  1441  		})
  1442  	}
  1443  	t.Run("Error when tenant not in context", func(t *testing.T) {
  1444  		svc := event.NewService(nil, uid.NewService(), nil, nil)
  1445  		// WHEN
  1446  		err := svc.UpdateInManyBundles(context.TODO(), resource.Application, "", model.EventDefinitionInput{}, &model.SpecInput{}, []string{}, []string{}, []string{}, 0, "")
  1447  		// THEN
  1448  		require.Error(t, err)
  1449  		assert.Contains(t, err.Error(), "cannot read tenant from context")
  1450  	})
  1451  }
  1452  
  1453  func TestService_UpdateForApplication(t *testing.T) {
  1454  	// GIVEN
  1455  	testErr := errors.New("Test error")
  1456  
  1457  	id := "foo"
  1458  	timestamp := time.Now()
  1459  	frURL := "foo.bar"
  1460  	spec := "spec"
  1461  
  1462  	modelInput := model.EventDefinitionInput{
  1463  		Name:         "Foo",
  1464  		VersionInput: &model.VersionInput{},
  1465  	}
  1466  
  1467  	modelSpecInput := model.SpecInput{
  1468  		Data: &spec,
  1469  		FetchRequest: &model.FetchRequestInput{
  1470  			URL: frURL,
  1471  		},
  1472  	}
  1473  
  1474  	modelSpec := &model.Spec{
  1475  		ID:         id,
  1476  		ObjectType: model.EventSpecReference,
  1477  		ObjectID:   id,
  1478  		Data:       &spec,
  1479  	}
  1480  
  1481  	inputAPIDefinitionModel := mock.MatchedBy(func(api *model.EventDefinition) bool {
  1482  		return api.Name == modelInput.Name
  1483  	})
  1484  
  1485  	eventDefinitionModel := &model.EventDefinition{
  1486  		Name:    "Bar",
  1487  		Version: &model.Version{},
  1488  	}
  1489  
  1490  	ctx := context.TODO()
  1491  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
  1492  
  1493  	testCases := []struct {
  1494  		Name              string
  1495  		RepositoryFn      func() *automock.EventAPIRepository
  1496  		SpecServiceFn     func() *automock.SpecService
  1497  		BundleReferenceFn func() *automock.BundleReferenceService
  1498  		SpecInput         *model.SpecInput
  1499  		Input             model.EventDefinitionInput
  1500  		InputID           string
  1501  		ExpectedErr       error
  1502  	}{
  1503  		{
  1504  			Name: "Success with spec update",
  1505  			RepositoryFn: func() *automock.EventAPIRepository {
  1506  				repo := &automock.EventAPIRepository{}
  1507  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1508  				repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once()
  1509  				return repo
  1510  			},
  1511  			SpecServiceFn: func() *automock.SpecService {
  1512  				svc := &automock.SpecService{}
  1513  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once()
  1514  				svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(nil).Once()
  1515  				return svc
  1516  			},
  1517  			SpecInput:   &modelSpecInput,
  1518  			InputID:     "foo",
  1519  			Input:       modelInput,
  1520  			ExpectedErr: nil,
  1521  		},
  1522  		{
  1523  			Name: "Success with spec create",
  1524  			RepositoryFn: func() *automock.EventAPIRepository {
  1525  				repo := &automock.EventAPIRepository{}
  1526  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1527  				repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once()
  1528  				return repo
  1529  			},
  1530  			SpecServiceFn: func() *automock.SpecService {
  1531  				svc := &automock.SpecService{}
  1532  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, nil).Once()
  1533  				svc.On("CreateByReferenceObjectID", ctx, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(specID, nil).Once()
  1534  				return svc
  1535  			},
  1536  			SpecInput:   &modelSpecInput,
  1537  			InputID:     "foo",
  1538  			Input:       modelInput,
  1539  			ExpectedErr: nil,
  1540  		},
  1541  		{
  1542  			Name: "Success without specs",
  1543  			RepositoryFn: func() *automock.EventAPIRepository {
  1544  				repo := &automock.EventAPIRepository{}
  1545  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1546  				repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once()
  1547  				return repo
  1548  			},
  1549  			SpecServiceFn: emptySpecService,
  1550  			SpecInput:     nil,
  1551  			InputID:       "foo",
  1552  			Input:         modelInput,
  1553  			ExpectedErr:   nil,
  1554  		},
  1555  		{
  1556  			Name: "Error when getting Event",
  1557  			RepositoryFn: func() *automock.EventAPIRepository {
  1558  				repo := &automock.EventAPIRepository{}
  1559  				repo.On("GetByID", ctx, tenantID, id).Return(nil, testErr).Once()
  1560  				return repo
  1561  			},
  1562  			SpecServiceFn: emptySpecService,
  1563  			SpecInput:     &modelSpecInput,
  1564  			InputID:       "foo",
  1565  			Input:         modelInput,
  1566  			ExpectedErr:   testErr,
  1567  		},
  1568  		{
  1569  			Name: "Error when updating Event",
  1570  			RepositoryFn: func() *automock.EventAPIRepository {
  1571  				repo := &automock.EventAPIRepository{}
  1572  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1573  				repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(testErr).Once()
  1574  				return repo
  1575  			},
  1576  			SpecServiceFn: emptySpecService,
  1577  			SpecInput:     &modelSpecInput,
  1578  			InputID:       "foo",
  1579  			Input:         modelInput,
  1580  			ExpectedErr:   testErr,
  1581  		},
  1582  		{
  1583  			Name: "Error when getting specs after Event update",
  1584  			RepositoryFn: func() *automock.EventAPIRepository {
  1585  				repo := &automock.EventAPIRepository{}
  1586  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1587  				repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once()
  1588  				return repo
  1589  			},
  1590  			SpecServiceFn: func() *automock.SpecService {
  1591  				svc := &automock.SpecService{}
  1592  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, testErr).Once()
  1593  				return svc
  1594  			},
  1595  			SpecInput:   &modelSpecInput,
  1596  			InputID:     "foo",
  1597  			Input:       modelInput,
  1598  			ExpectedErr: testErr,
  1599  		},
  1600  		{
  1601  			Name: "Error when creating specs after API update",
  1602  			RepositoryFn: func() *automock.EventAPIRepository {
  1603  				repo := &automock.EventAPIRepository{}
  1604  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1605  				repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once()
  1606  				return repo
  1607  			},
  1608  			SpecServiceFn: func() *automock.SpecService {
  1609  				svc := &automock.SpecService{}
  1610  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(nil, nil).Once()
  1611  				svc.On("CreateByReferenceObjectID", ctx, modelSpecInput, resource.Application, model.EventSpecReference, id).Return("", testErr).Once()
  1612  				return svc
  1613  			},
  1614  			SpecInput:   &modelSpecInput,
  1615  			InputID:     "foo",
  1616  			Input:       modelInput,
  1617  			ExpectedErr: testErr,
  1618  		},
  1619  		{
  1620  			Name: "Error when updating specs after API update",
  1621  			RepositoryFn: func() *automock.EventAPIRepository {
  1622  				repo := &automock.EventAPIRepository{}
  1623  				repo.On("GetByID", ctx, tenantID, id).Return(eventDefinitionModel, nil).Once()
  1624  				repo.On("Update", ctx, tenantID, inputAPIDefinitionModel).Return(nil).Once()
  1625  				return repo
  1626  			},
  1627  			SpecServiceFn: func() *automock.SpecService {
  1628  				svc := &automock.SpecService{}
  1629  				svc.On("GetByReferenceObjectID", ctx, resource.Application, model.EventSpecReference, id).Return(modelSpec, nil).Once()
  1630  				svc.On("UpdateByReferenceObjectID", ctx, id, modelSpecInput, resource.Application, model.EventSpecReference, id).Return(testErr).Once()
  1631  				return svc
  1632  			},
  1633  			SpecInput:   &modelSpecInput,
  1634  			InputID:     "foo",
  1635  			Input:       modelInput,
  1636  			ExpectedErr: testErr,
  1637  		},
  1638  	}
  1639  
  1640  	for _, testCase := range testCases {
  1641  		t.Run(testCase.Name, func(t *testing.T) {
  1642  			// GIVEN
  1643  			repo := testCase.RepositoryFn()
  1644  			specSvc := testCase.SpecServiceFn()
  1645  			defer mock.AssertExpectationsForObjects(t, repo, specSvc)
  1646  
  1647  			svc := event.NewService(repo, nil, specSvc, nil)
  1648  			svc.SetTimestampGen(func() time.Time { return timestamp })
  1649  
  1650  			// WHEN
  1651  			err := svc.UpdateForApplication(ctx, testCase.InputID, testCase.Input, testCase.SpecInput)
  1652  
  1653  			// then
  1654  			if testCase.ExpectedErr == nil {
  1655  				require.NoError(t, err)
  1656  			} else {
  1657  				require.Error(t, err)
  1658  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1659  			}
  1660  		})
  1661  	}
  1662  	t.Run("Error when tenant not in context", func(t *testing.T) {
  1663  		svc := event.NewService(nil, nil, nil, nil)
  1664  		// WHEN
  1665  		err := svc.UpdateForApplication(context.TODO(), "", model.EventDefinitionInput{}, &model.SpecInput{})
  1666  		// THEN
  1667  		require.Error(t, err)
  1668  		assert.Contains(t, err.Error(), "cannot read tenant from context")
  1669  	})
  1670  }
  1671  
  1672  func TestService_Delete(t *testing.T) {
  1673  	// GIVEN
  1674  	testErr := errors.New("Test error")
  1675  
  1676  	id := "foo"
  1677  
  1678  	ctx := context.TODO()
  1679  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
  1680  
  1681  	testCases := []struct {
  1682  		Name         string
  1683  		RepositoryFn func() *automock.EventAPIRepository
  1684  		Input        model.EventDefinitionInput
  1685  		InputID      string
  1686  		ResourceType resource.Type
  1687  		ExpectedErr  error
  1688  	}{
  1689  		{
  1690  			Name: "Success for Application",
  1691  			RepositoryFn: func() *automock.EventAPIRepository {
  1692  				repo := &automock.EventAPIRepository{}
  1693  				repo.On("Delete", ctx, tenantID, id).Return(nil).Once()
  1694  				return repo
  1695  			},
  1696  			InputID:      id,
  1697  			ResourceType: resource.Application,
  1698  			ExpectedErr:  nil,
  1699  		},
  1700  		{
  1701  			Name: "Success for Application Template Version",
  1702  			RepositoryFn: func() *automock.EventAPIRepository {
  1703  				repo := &automock.EventAPIRepository{}
  1704  				repo.On("DeleteGlobal", ctx, id).Return(nil).Once()
  1705  				return repo
  1706  			},
  1707  			InputID:      id,
  1708  			ResourceType: resource.ApplicationTemplateVersion,
  1709  			ExpectedErr:  nil,
  1710  		},
  1711  		{
  1712  			Name: "Delete Error for Application",
  1713  			RepositoryFn: func() *automock.EventAPIRepository {
  1714  				repo := &automock.EventAPIRepository{}
  1715  				repo.On("Delete", ctx, tenantID, id).Return(testErr).Once()
  1716  				return repo
  1717  			},
  1718  			InputID:      id,
  1719  			ResourceType: resource.Application,
  1720  			ExpectedErr:  testErr,
  1721  		},
  1722  		{
  1723  			Name: "Delete Error for Application Template Version",
  1724  			RepositoryFn: func() *automock.EventAPIRepository {
  1725  				repo := &automock.EventAPIRepository{}
  1726  				repo.On("DeleteGlobal", ctx, id).Return(testErr).Once()
  1727  				return repo
  1728  			},
  1729  			InputID:      id,
  1730  			ResourceType: resource.ApplicationTemplateVersion,
  1731  			ExpectedErr:  testErr,
  1732  		},
  1733  	}
  1734  
  1735  	for _, testCase := range testCases {
  1736  		t.Run(testCase.Name, func(t *testing.T) {
  1737  			// GIVEN
  1738  			repo := testCase.RepositoryFn()
  1739  
  1740  			svc := event.NewService(repo, nil, nil, nil)
  1741  
  1742  			// WHEN
  1743  			err := svc.Delete(ctx, testCase.ResourceType, testCase.InputID)
  1744  
  1745  			// then
  1746  			if testCase.ExpectedErr == nil {
  1747  				require.NoError(t, err)
  1748  			} else {
  1749  				require.Error(t, err)
  1750  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1751  			}
  1752  
  1753  			repo.AssertExpectations(t)
  1754  		})
  1755  	}
  1756  	t.Run("Error when tenant not in context", func(t *testing.T) {
  1757  		svc := event.NewService(nil, nil, nil, nil)
  1758  		// WHEN
  1759  		err := svc.Delete(context.TODO(), resource.Application, "")
  1760  		// THEN
  1761  		require.Error(t, err)
  1762  		assert.Contains(t, err.Error(), "cannot read tenant from context")
  1763  	})
  1764  }
  1765  
  1766  func TestService_DeleteAllByBundleID(t *testing.T) {
  1767  	// GIVEN
  1768  	testErr := errors.New("Test error")
  1769  	id := "foo"
  1770  
  1771  	ctx := context.TODO()
  1772  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
  1773  
  1774  	testCases := []struct {
  1775  		Name         string
  1776  		RepositoryFn func() *automock.EventAPIRepository
  1777  		Input        model.EventDefinitionInput
  1778  		InputID      string
  1779  		ExpectedErr  error
  1780  	}{
  1781  		{
  1782  			Name: "Success",
  1783  			RepositoryFn: func() *automock.EventAPIRepository {
  1784  				repo := &automock.EventAPIRepository{}
  1785  				repo.On("DeleteAllByBundleID", ctx, tenantID, id).Return(nil).Once()
  1786  				return repo
  1787  			},
  1788  			InputID:     id,
  1789  			ExpectedErr: nil,
  1790  		},
  1791  		{
  1792  			Name: "Delete Error",
  1793  			RepositoryFn: func() *automock.EventAPIRepository {
  1794  				repo := &automock.EventAPIRepository{}
  1795  				repo.On("DeleteAllByBundleID", ctx, tenantID, id).Return(testErr).Once()
  1796  				return repo
  1797  			},
  1798  			InputID:     id,
  1799  			ExpectedErr: testErr,
  1800  		},
  1801  	}
  1802  
  1803  	for _, testCase := range testCases {
  1804  		t.Run(testCase.Name, func(t *testing.T) {
  1805  			// GIVEN
  1806  			repo := testCase.RepositoryFn()
  1807  
  1808  			svc := event.NewService(repo, nil, nil, nil)
  1809  
  1810  			// WHEN
  1811  			err := svc.DeleteAllByBundleID(ctx, testCase.InputID)
  1812  
  1813  			// then
  1814  			if testCase.ExpectedErr == nil {
  1815  				require.NoError(t, err)
  1816  			} else {
  1817  				require.Error(t, err)
  1818  				assert.Contains(t, err.Error(), testCase.ExpectedErr.Error())
  1819  			}
  1820  
  1821  			repo.AssertExpectations(t)
  1822  		})
  1823  	}
  1824  	t.Run("Error when tenant not in context", func(t *testing.T) {
  1825  		svc := event.NewService(nil, nil, nil, nil)
  1826  		// WHEN
  1827  		err := svc.DeleteAllByBundleID(context.TODO(), "")
  1828  		// THEN
  1829  		require.Error(t, err)
  1830  		assert.Contains(t, err.Error(), "cannot read tenant from context")
  1831  	})
  1832  }
  1833  
  1834  func TestService_ListFetchRequests(t *testing.T) {
  1835  	// GIVEN
  1836  	ctx := context.TODO()
  1837  	ctx = tenant.SaveToContext(ctx, tenantID, externalTenantID)
  1838  
  1839  	testErr := errors.New("Test error")
  1840  
  1841  	frURL := "foo.bar"
  1842  	firstFRID := "frID"
  1843  	secondFRID := "frID2"
  1844  	firstSpecID := "specID"
  1845  	secondSpecID := "specID2"
  1846  	specIDs := []string{firstSpecID, secondSpecID}
  1847  	timestamp := time.Now()
  1848  
  1849  	firstFetchRequest := fixModelFetchRequest(firstFRID, frURL, timestamp)
  1850  	secondFetchRequest := fixModelFetchRequest(secondFRID, frURL, timestamp)
  1851  	fetchRequests := []*model.FetchRequest{firstFetchRequest, secondFetchRequest}
  1852  
  1853  	testCases := []struct {
  1854  		Name                  string
  1855  		SpecServiceFn         func() *automock.SpecService
  1856  		ExpectedFetchRequests []*model.FetchRequest
  1857  		ExpectedErrMessage    string
  1858  	}{
  1859  		{
  1860  			Name: "Success",
  1861  			SpecServiceFn: func() *automock.SpecService {
  1862  				svc := &automock.SpecService{}
  1863  				svc.On("ListFetchRequestsByReferenceObjectIDs", ctx, tenantID, specIDs, model.EventSpecReference).Return(fetchRequests, nil).Once()
  1864  				return svc
  1865  			},
  1866  			ExpectedFetchRequests: fetchRequests,
  1867  		},
  1868  		{
  1869  			Name: "Success - Fetch Request Not Found",
  1870  			SpecServiceFn: func() *automock.SpecService {
  1871  				svc := &automock.SpecService{}
  1872  				svc.On("ListFetchRequestsByReferenceObjectIDs", ctx, tenantID, specIDs, model.EventSpecReference).Return(nil, apperrors.NewNotFoundError(resource.FetchRequest, "")).Once()
  1873  				return svc
  1874  			},
  1875  			ExpectedFetchRequests: nil,
  1876  		},
  1877  		{
  1878  			Name: "Error while listing Fetch Requests",
  1879  			SpecServiceFn: func() *automock.SpecService {
  1880  				svc := &automock.SpecService{}
  1881  				svc.On("ListFetchRequestsByReferenceObjectIDs", ctx, tenantID, specIDs, model.EventSpecReference).Return(nil, testErr).Once()
  1882  				return svc
  1883  			},
  1884  			ExpectedFetchRequests: nil,
  1885  			ExpectedErrMessage:    testErr.Error(),
  1886  		},
  1887  	}
  1888  
  1889  	for _, testCase := range testCases {
  1890  		t.Run(testCase.Name, func(t *testing.T) {
  1891  			specService := testCase.SpecServiceFn()
  1892  
  1893  			svc := event.NewService(nil, nil, specService, nil)
  1894  
  1895  			// WHEN
  1896  			frs, err := svc.ListFetchRequests(ctx, specIDs)
  1897  
  1898  			// then
  1899  			if testCase.ExpectedErrMessage == "" {
  1900  				require.NoError(t, err)
  1901  				assert.Equal(t, frs, testCase.ExpectedFetchRequests)
  1902  			} else {
  1903  				require.Error(t, err)
  1904  				assert.Contains(t, err.Error(), testCase.ExpectedErrMessage)
  1905  			}
  1906  
  1907  			specService.AssertExpectations(t)
  1908  		})
  1909  	}
  1910  	t.Run("Returns error on loading tenant", func(t *testing.T) {
  1911  		svc := event.NewService(nil, nil, nil, nil)
  1912  		// WHEN
  1913  		_, err := svc.ListFetchRequests(context.TODO(), nil)
  1914  		assert.True(t, apperrors.IsCannotReadTenant(err))
  1915  	})
  1916  }
  1917  
  1918  func fixUIDSvc() *automock.UIDService {
  1919  	svc := &automock.UIDService{}
  1920  	svc.On("Generate").Return(eventID)
  1921  	return svc
  1922  }
  1923  
  1924  func emptySpecService() *automock.SpecService {
  1925  	svc := &automock.SpecService{}
  1926  	return svc
  1927  }