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

     1  package bundle_test
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"encoding/json"
     6  	"regexp"
     7  	"testing"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/internal/repo"
    10  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
    11  
    12  	"github.com/kyma-incubator/compass/components/director/pkg/pagination"
    13  
    14  	"github.com/DATA-DOG/go-sqlmock"
    15  	"github.com/kyma-incubator/compass/components/director/internal/domain/bundle"
    16  	"github.com/kyma-incubator/compass/components/director/internal/domain/bundle/automock"
    17  	"github.com/kyma-incubator/compass/components/director/internal/model"
    18  	"github.com/kyma-incubator/compass/components/director/internal/repo/testdb"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func TestPgRepository_Create(t *testing.T) {
    23  	// GIVEN
    24  	name := "foo"
    25  	desc := "bar"
    26  
    27  	var nilBundleMode *model.Bundle
    28  	bndlModel := fixBundleModel(name, desc)
    29  	bndlEntity := fixEntityBundleWithAppID(bundleID, name, desc)
    30  
    31  	defAuth, err := json.Marshal(bndlModel.DefaultInstanceAuth)
    32  	require.NoError(t, err)
    33  
    34  	suite := testdb.RepoCreateTestSuite{
    35  		Name: "Create Bundle",
    36  		SQLQueryDetails: []testdb.SQLQueryDetails{
    37  			{
    38  				Query:    regexp.QuoteMeta("SELECT 1 FROM tenant_applications WHERE tenant_id = $1 AND id = $2 AND owner = $3"),
    39  				Args:     []driver.Value{tenantID, appID, true},
    40  				IsSelect: true,
    41  				ValidRowsProvider: func() []*sqlmock.Rows {
    42  					return []*sqlmock.Rows{testdb.RowWhenObjectExist()}
    43  				},
    44  				InvalidRowsProvider: func() []*sqlmock.Rows {
    45  					return []*sqlmock.Rows{testdb.RowWhenObjectDoesNotExist()}
    46  				},
    47  			},
    48  			{
    49  				Query:       `^INSERT INTO public.bundles \(.+\) VALUES \(.+\)$`,
    50  				Args:        fixBundleCreateArgsForApp(string(defAuth), *bndlModel.InstanceAuthRequestInputSchema, bndlModel),
    51  				ValidResult: sqlmock.NewResult(-1, 1),
    52  			},
    53  		},
    54  		ConverterMockProvider: func() testdb.Mock {
    55  			return &automock.EntityConverter{}
    56  		},
    57  		RepoConstructorFunc: bundle.NewRepository,
    58  		ModelEntity:         bndlModel,
    59  		DBEntity:            bndlEntity,
    60  		NilModelEntity:      nilBundleMode,
    61  		TenantID:            tenantID,
    62  	}
    63  
    64  	suite.Run(t)
    65  }
    66  
    67  func TestPgRepository_CreateGlobal(t *testing.T) {
    68  	// GIVEN
    69  	name := "foo"
    70  
    71  	var nilBundleMode *model.Bundle
    72  	bndlModel := fixBundleModelWithIDAndAppTemplateVersionID(bundleID, name, desc)
    73  	bndlEntity := fixEntityBundleWithAppTemplateVersionID(bundleID, name, desc)
    74  
    75  	defAuth, err := json.Marshal(bndlModel.DefaultInstanceAuth)
    76  	require.NoError(t, err)
    77  
    78  	suite := testdb.RepoCreateTestSuite{
    79  		Name: "Create Bundle Global",
    80  		SQLQueryDetails: []testdb.SQLQueryDetails{
    81  			{
    82  				Query:       `^INSERT INTO public.bundles \(.+\) VALUES \(.+\)$`,
    83  				Args:        fixBundleCreateArgsForAppTemplateVersion(string(defAuth), *bndlModel.InstanceAuthRequestInputSchema, bndlModel),
    84  				ValidResult: sqlmock.NewResult(-1, 1),
    85  			},
    86  		},
    87  		ConverterMockProvider: func() testdb.Mock {
    88  			return &automock.EntityConverter{}
    89  		},
    90  		RepoConstructorFunc: bundle.NewRepository,
    91  		ModelEntity:         bndlModel,
    92  		DBEntity:            bndlEntity,
    93  		NilModelEntity:      nilBundleMode,
    94  		IsGlobal:            true,
    95  		MethodName:          "CreateGlobal",
    96  	}
    97  
    98  	suite.Run(t)
    99  }
   100  
   101  func TestPgRepository_Update(t *testing.T) {
   102  	updateQuery := regexp.QuoteMeta(`UPDATE public.bundles SET name = ?, description = ?, version = ?, instance_auth_request_json_schema = ?, default_instance_auth = ?, ord_id = ?, local_tenant_id = ?, short_description = ?, links = ?, labels = ?, credential_exchange_strategies = ?, ready = ?, created_at = ?, updated_at = ?, deleted_at = ?, error = ?, correlation_ids = ?, tags = ?, resource_hash = ?, documentation_labels = ? WHERE id = ? AND (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = ? AND owner = true))`)
   103  
   104  	var nilBundleMode *model.Bundle
   105  	bndl := fixBundleModel("foo", "update")
   106  	entity := fixEntityBundleWithAppID(bundleID, "foo", "update")
   107  	entity.UpdatedAt = &fixedTimestamp
   108  	entity.DeletedAt = &fixedTimestamp // This is needed as workaround so that updatedAt timestamp is not updated
   109  
   110  	suite := testdb.RepoUpdateTestSuite{
   111  		Name: "Update Bundle",
   112  		SQLQueryDetails: []testdb.SQLQueryDetails{
   113  			{
   114  				Query:         updateQuery,
   115  				Args:          []driver.Value{entity.Name, entity.Description, entity.Version, entity.InstanceAuthRequestJSONSchema, entity.DefaultInstanceAuth, entity.OrdID, entity.LocalTenantID, entity.ShortDescription, entity.Links, entity.Labels, entity.CredentialExchangeStrategies, entity.Ready, entity.CreatedAt, entity.UpdatedAt, entity.DeletedAt, entity.Error, entity.CorrelationIDs, entity.Tags, entity.ResourceHash, entity.DocumentationLabels, entity.ID, tenantID},
   116  				ValidResult:   sqlmock.NewResult(-1, 1),
   117  				InvalidResult: sqlmock.NewResult(-1, 0),
   118  			},
   119  		},
   120  		ConverterMockProvider: func() testdb.Mock {
   121  			return &automock.EntityConverter{}
   122  		},
   123  		RepoConstructorFunc: bundle.NewRepository,
   124  		ModelEntity:         bndl,
   125  		DBEntity:            entity,
   126  		NilModelEntity:      nilBundleMode,
   127  		TenantID:            tenantID,
   128  	}
   129  
   130  	suite.Run(t)
   131  }
   132  
   133  func TestPgRepository_UpdateGlobal(t *testing.T) {
   134  	updateQuery := regexp.QuoteMeta(`UPDATE public.bundles SET name = ?, description = ?, version = ?, instance_auth_request_json_schema = ?, default_instance_auth = ?, ord_id = ?, local_tenant_id = ?, short_description = ?, links = ?, labels = ?, credential_exchange_strategies = ?, ready = ?, created_at = ?, updated_at = ?, deleted_at = ?, error = ?, correlation_ids = ?, tags = ?, resource_hash = ?, documentation_labels = ? WHERE id = ?`)
   135  
   136  	var nilBundleMode *model.Bundle
   137  	bndl := fixBundleModel("foo", "update")
   138  	entity := fixEntityBundleWithAppID(bundleID, "foo", "update")
   139  	entity.UpdatedAt = &fixedTimestamp
   140  	entity.DeletedAt = &fixedTimestamp // This is needed as workaround so that updatedAt timestamp is not updated
   141  
   142  	suite := testdb.RepoUpdateTestSuite{
   143  		Name: "Update Bundle Global",
   144  		SQLQueryDetails: []testdb.SQLQueryDetails{
   145  			{
   146  				Query:         updateQuery,
   147  				Args:          []driver.Value{entity.Name, entity.Description, entity.Version, entity.InstanceAuthRequestJSONSchema, entity.DefaultInstanceAuth, entity.OrdID, entity.LocalTenantID, entity.ShortDescription, entity.Links, entity.Labels, entity.CredentialExchangeStrategies, entity.Ready, entity.CreatedAt, entity.UpdatedAt, entity.DeletedAt, entity.Error, entity.CorrelationIDs, entity.Tags, entity.ResourceHash, entity.DocumentationLabels, entity.ID},
   148  				ValidResult:   sqlmock.NewResult(-1, 1),
   149  				InvalidResult: sqlmock.NewResult(-1, 0),
   150  			},
   151  		},
   152  		ConverterMockProvider: func() testdb.Mock {
   153  			return &automock.EntityConverter{}
   154  		},
   155  		RepoConstructorFunc: bundle.NewRepository,
   156  		ModelEntity:         bndl,
   157  		DBEntity:            entity,
   158  		NilModelEntity:      nilBundleMode,
   159  		IsGlobal:            true,
   160  		UpdateMethodName:    "UpdateGlobal",
   161  	}
   162  
   163  	suite.Run(t)
   164  }
   165  
   166  func TestPgRepository_Delete(t *testing.T) {
   167  	suite := testdb.RepoDeleteTestSuite{
   168  		Name: "Bundle Delete",
   169  		SQLQueryDetails: []testdb.SQLQueryDetails{
   170  			{
   171  				Query:         regexp.QuoteMeta(`DELETE FROM public.bundles WHERE id = $1 AND (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = $2 AND owner = true))`),
   172  				Args:          []driver.Value{bundleID, tenantID},
   173  				ValidResult:   sqlmock.NewResult(-1, 1),
   174  				InvalidResult: sqlmock.NewResult(-1, 2),
   175  			},
   176  		},
   177  		ConverterMockProvider: func() testdb.Mock {
   178  			return &automock.EntityConverter{}
   179  		},
   180  		RepoConstructorFunc: bundle.NewRepository,
   181  		MethodArgs:          []interface{}{tenantID, bundleID},
   182  	}
   183  
   184  	suite.Run(t)
   185  }
   186  
   187  func TestPgRepository_DeleteGlobal(t *testing.T) {
   188  	suite := testdb.RepoDeleteTestSuite{
   189  		Name: "Bundle Delete Global",
   190  		SQLQueryDetails: []testdb.SQLQueryDetails{
   191  			{
   192  				Query:         regexp.QuoteMeta(`DELETE FROM public.bundles WHERE id = $1`),
   193  				Args:          []driver.Value{bundleID},
   194  				ValidResult:   sqlmock.NewResult(-1, 1),
   195  				InvalidResult: sqlmock.NewResult(-1, 2),
   196  			},
   197  		},
   198  		ConverterMockProvider: func() testdb.Mock {
   199  			return &automock.EntityConverter{}
   200  		},
   201  		RepoConstructorFunc: bundle.NewRepository,
   202  		MethodArgs:          []interface{}{bundleID},
   203  		IsGlobal:            true,
   204  		MethodName:          "DeleteGlobal",
   205  	}
   206  
   207  	suite.Run(t)
   208  }
   209  
   210  func TestPgRepository_Exists(t *testing.T) {
   211  	suite := testdb.RepoExistTestSuite{
   212  		Name: "Bundle Exists",
   213  		SQLQueryDetails: []testdb.SQLQueryDetails{
   214  			{
   215  				Query:    regexp.QuoteMeta(`SELECT 1 FROM public.bundles WHERE id = $1 AND (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = $2))`),
   216  				Args:     []driver.Value{bundleID, tenantID},
   217  				IsSelect: true,
   218  				ValidRowsProvider: func() []*sqlmock.Rows {
   219  					return []*sqlmock.Rows{testdb.RowWhenObjectExist()}
   220  				},
   221  				InvalidRowsProvider: func() []*sqlmock.Rows {
   222  					return []*sqlmock.Rows{testdb.RowWhenObjectDoesNotExist()}
   223  				},
   224  			},
   225  		},
   226  		ConverterMockProvider: func() testdb.Mock {
   227  			return &automock.EntityConverter{}
   228  		},
   229  		RepoConstructorFunc: bundle.NewRepository,
   230  		TargetID:            bundleID,
   231  		TenantID:            tenantID,
   232  		MethodName:          "Exists",
   233  		MethodArgs:          []interface{}{tenantID, bundleID},
   234  	}
   235  
   236  	suite.Run(t)
   237  }
   238  
   239  func TestPgRepository_GetByID(t *testing.T) {
   240  	bndlEntity := fixEntityBundleWithAppID(bundleID, "foo", "bar")
   241  
   242  	suite := testdb.RepoGetTestSuite{
   243  		Name: "Get Bundle",
   244  		SQLQueryDetails: []testdb.SQLQueryDetails{
   245  			{
   246  				Query:    regexp.QuoteMeta(`SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema, default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies, ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM public.bundles WHERE id = $1 AND (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = $2))`),
   247  				Args:     []driver.Value{bundleID, tenantID},
   248  				IsSelect: true,
   249  				ValidRowsProvider: func() []*sqlmock.Rows {
   250  					return []*sqlmock.Rows{
   251  						sqlmock.NewRows(fixBundleColumns()).
   252  							AddRow(fixBundleRowWithAppID(bundleID)...),
   253  					}
   254  				},
   255  				InvalidRowsProvider: func() []*sqlmock.Rows {
   256  					return []*sqlmock.Rows{
   257  						sqlmock.NewRows(fixBundleColumns()),
   258  					}
   259  				},
   260  			},
   261  		},
   262  		ConverterMockProvider: func() testdb.Mock {
   263  			return &automock.EntityConverter{}
   264  		},
   265  		RepoConstructorFunc: bundle.NewRepository,
   266  		ExpectedModelEntity: fixBundleModel("foo", "bar"),
   267  		ExpectedDBEntity:    bndlEntity,
   268  		MethodArgs:          []interface{}{tenantID, bundleID},
   269  	}
   270  
   271  	suite.Run(t)
   272  }
   273  
   274  func TestPgRepository_GetByIDGlobal(t *testing.T) {
   275  	bndlEntity := fixEntityBundleWithAppTemplateVersionID(bundleID, "foo", "bar")
   276  
   277  	suite := testdb.RepoGetTestSuite{
   278  		Name: "Get Bundle Global",
   279  		SQLQueryDetails: []testdb.SQLQueryDetails{
   280  			{
   281  				Query:    regexp.QuoteMeta(`SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema, default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies, ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM public.bundles WHERE id = $1`),
   282  				Args:     []driver.Value{bundleID},
   283  				IsSelect: true,
   284  				ValidRowsProvider: func() []*sqlmock.Rows {
   285  					return []*sqlmock.Rows{
   286  						sqlmock.NewRows(fixBundleColumns()).
   287  							AddRow(fixBundleRowWithAppTemplateVersionID(bundleID)...),
   288  					}
   289  				},
   290  				InvalidRowsProvider: func() []*sqlmock.Rows {
   291  					return []*sqlmock.Rows{
   292  						sqlmock.NewRows(fixBundleColumns()),
   293  					}
   294  				},
   295  			},
   296  		},
   297  		ConverterMockProvider: func() testdb.Mock {
   298  			return &automock.EntityConverter{}
   299  		},
   300  		RepoConstructorFunc: bundle.NewRepository,
   301  		ExpectedModelEntity: fixBundleModel("foo", "bar"),
   302  		ExpectedDBEntity:    bndlEntity,
   303  		MethodArgs:          []interface{}{bundleID},
   304  		MethodName:          "GetByIDGlobal",
   305  	}
   306  
   307  	suite.Run(t)
   308  }
   309  
   310  func TestPgRepository_GetForApplication(t *testing.T) {
   311  	bndlEntity := fixEntityBundleWithAppID(bundleID, "foo", "bar")
   312  
   313  	suite := testdb.RepoGetTestSuite{
   314  		Name: "Get Bundle For Application",
   315  		SQLQueryDetails: []testdb.SQLQueryDetails{
   316  			{
   317  				Query:    regexp.QuoteMeta(`SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema, default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies, ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM public.bundles WHERE id = $1 AND app_id = $2 AND (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = $3))`),
   318  				Args:     []driver.Value{bundleID, appID, tenantID},
   319  				IsSelect: true,
   320  				ValidRowsProvider: func() []*sqlmock.Rows {
   321  					return []*sqlmock.Rows{
   322  						sqlmock.NewRows(fixBundleColumns()).
   323  							AddRow(fixBundleRowWithAppID(bundleID)...),
   324  					}
   325  				},
   326  				InvalidRowsProvider: func() []*sqlmock.Rows {
   327  					return []*sqlmock.Rows{
   328  						sqlmock.NewRows(fixBundleColumns()),
   329  					}
   330  				},
   331  			},
   332  		},
   333  		ConverterMockProvider: func() testdb.Mock {
   334  			return &automock.EntityConverter{}
   335  		},
   336  		RepoConstructorFunc: bundle.NewRepository,
   337  		ExpectedModelEntity: fixBundleModel("foo", "bar"),
   338  		ExpectedDBEntity:    bndlEntity,
   339  		MethodArgs:          []interface{}{tenantID, bundleID, appID},
   340  		MethodName:          "GetForApplication",
   341  	}
   342  
   343  	suite.Run(t)
   344  }
   345  
   346  func TestPgRepository_ListByApplicationIDs(t *testing.T) {
   347  	pageSize := 1
   348  	cursor := ""
   349  
   350  	emptyPageAppID := "emptyPageAppID"
   351  
   352  	onePageAppID := "onePageAppID"
   353  	firstBundleID := "111111111-1111-1111-1111-111111111111"
   354  	firstBundleEntity := fixEntityBundleWithAppID(firstBundleID, "foo", "bar")
   355  	firstBundleEntity.ApplicationID = repo.NewValidNullableString(onePageAppID)
   356  	firstBndlModel := fixBundleModelWithIDAndAppID(firstBundleID, "foo", desc)
   357  	firstBndlModel.ApplicationID = &onePageAppID
   358  
   359  	multiplePagesAppID := "multiplePagesAppID"
   360  
   361  	secondBundleID := "222222222-2222-2222-2222-222222222222"
   362  	secondBundleEntity := fixEntityBundleWithAppID(secondBundleID, "foo", "bar")
   363  	secondBundleEntity.ApplicationID = repo.NewValidNullableString(multiplePagesAppID)
   364  	secondBndlModel := fixBundleModelWithIDAndAppID(secondBundleID, "foo", desc)
   365  	secondBndlModel.ApplicationID = &multiplePagesAppID
   366  
   367  	suite := testdb.RepoListPageableTestSuite{
   368  		Name: "List Bundles for multiple Applications with paging",
   369  		SQLQueryDetails: []testdb.SQLQueryDetails{
   370  			{
   371  				Query: regexp.QuoteMeta(`(SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema, default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies, ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM public.bundles WHERE (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = $1)) AND app_id = $2 ORDER BY app_id ASC, id ASC LIMIT $3 OFFSET $4)
   372  												UNION
   373  												(SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema, default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies, ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM public.bundles WHERE (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = $5)) AND app_id = $6 ORDER BY app_id ASC, id ASC LIMIT $7 OFFSET $8)
   374  												UNION
   375  												(SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema, default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies, ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM public.bundles WHERE (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = $9)) AND app_id = $10 ORDER BY app_id ASC, id ASC LIMIT $11 OFFSET $12)`),
   376  
   377  				Args:     []driver.Value{tenantID, emptyPageAppID, pageSize, 0, tenantID, onePageAppID, pageSize, 0, tenantID, multiplePagesAppID, pageSize, 0},
   378  				IsSelect: true,
   379  				ValidRowsProvider: func() []*sqlmock.Rows {
   380  					return []*sqlmock.Rows{sqlmock.NewRows(fixBundleColumns()).AddRow(fixBundleRowWithCustomAppID(firstBundleID, onePageAppID)...).AddRow(fixBundleRowWithCustomAppID(secondBundleID, multiplePagesAppID)...)}
   381  				},
   382  			},
   383  			{
   384  				Query:    regexp.QuoteMeta(`SELECT app_id AS id, COUNT(*) AS total_count FROM public.bundles WHERE (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = $1)) GROUP BY app_id ORDER BY app_id ASC`),
   385  				Args:     []driver.Value{tenantID},
   386  				IsSelect: true,
   387  				ValidRowsProvider: func() []*sqlmock.Rows {
   388  					return []*sqlmock.Rows{sqlmock.NewRows([]string{"id", "total_count"}).AddRow(emptyPageAppID, 0).AddRow(onePageAppID, 1).AddRow(multiplePagesAppID, 2)}
   389  				},
   390  			},
   391  		},
   392  		Pages: []testdb.PageDetails{
   393  			{
   394  				ExpectedModelEntities: nil,
   395  				ExpectedDBEntities:    nil,
   396  				ExpectedPage: &model.BundlePage{
   397  					Data: nil,
   398  					PageInfo: &pagination.Page{
   399  						StartCursor: "",
   400  						EndCursor:   "",
   401  						HasNextPage: false,
   402  					},
   403  					TotalCount: 0,
   404  				},
   405  			},
   406  			{
   407  				ExpectedModelEntities: []interface{}{firstBndlModel},
   408  				ExpectedDBEntities:    []interface{}{firstBundleEntity},
   409  				ExpectedPage: &model.BundlePage{
   410  					Data: []*model.Bundle{firstBndlModel},
   411  					PageInfo: &pagination.Page{
   412  						StartCursor: "",
   413  						EndCursor:   "",
   414  						HasNextPage: false,
   415  					},
   416  					TotalCount: 1,
   417  				},
   418  			},
   419  			{
   420  				ExpectedModelEntities: []interface{}{secondBndlModel},
   421  				ExpectedDBEntities:    []interface{}{secondBundleEntity},
   422  				ExpectedPage: &model.BundlePage{
   423  					Data: []*model.Bundle{secondBndlModel},
   424  					PageInfo: &pagination.Page{
   425  						StartCursor: "",
   426  						EndCursor:   pagination.EncodeNextOffsetCursor(0, pageSize),
   427  						HasNextPage: true,
   428  					},
   429  					TotalCount: 2,
   430  				},
   431  			},
   432  		},
   433  		ConverterMockProvider: func() testdb.Mock {
   434  			return &automock.EntityConverter{}
   435  		},
   436  		RepoConstructorFunc: bundle.NewRepository,
   437  		MethodName:          "ListByApplicationIDs",
   438  		MethodArgs:          []interface{}{tenantID, []string{emptyPageAppID, onePageAppID, multiplePagesAppID}, pageSize, cursor},
   439  	}
   440  
   441  	suite.Run(t)
   442  }
   443  
   444  func TestPgRepository_ListByResourceIDNoPaging(t *testing.T) {
   445  	firstBundleID := "111111111-1111-1111-1111-111111111111"
   446  	firstAppBundleEntity := fixEntityBundleWithAppID(firstBundleID, "foo", "bar")
   447  	firstAppTemplateVersionBundleEntity := fixEntityBundleWithAppTemplateVersionID(firstBundleID, "foo", "bar")
   448  	firstAppBndlModel := fixBundleModelWithIDAndAppID(firstBundleID, "foo", desc)
   449  	firstAppTemplateVersionBndlModel := fixBundleModelWithIDAndAppTemplateVersionID(firstBundleID, "foo", desc)
   450  	secondBundleID := "222222222-2222-2222-2222-222222222222"
   451  	secondAppBundleEntity := fixEntityBundleWithAppID(secondBundleID, "foo", "bar")
   452  	secondAppTemplateVersionBundleEntity := fixEntityBundleWithAppTemplateVersionID(secondBundleID, "foo", "bar")
   453  	secondAppBndlModel := fixBundleModelWithIDAndAppID(secondBundleID, "foo", desc)
   454  	secondAppTemplateVersionBndlModel := fixBundleModelWithIDAndAppTemplateVersionID(secondBundleID, "foo", desc)
   455  
   456  	suiteForApplication := testdb.RepoListTestSuite{
   457  		Name: "List Bundles No Paging",
   458  		SQLQueryDetails: []testdb.SQLQueryDetails{
   459  			{
   460  				Query:    regexp.QuoteMeta(`SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema, default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies, ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM public.bundles WHERE app_id = $1 AND (id IN (SELECT id FROM bundles_tenants WHERE tenant_id = $2)) FOR UPDATE`),
   461  				Args:     []driver.Value{appID, tenantID},
   462  				IsSelect: true,
   463  				ValidRowsProvider: func() []*sqlmock.Rows {
   464  					return []*sqlmock.Rows{sqlmock.NewRows(fixBundleColumns()).
   465  						AddRow(fixBundleRowWithAppID(firstBundleID)...).AddRow(fixBundleRowWithAppID(secondBundleID)...)}
   466  				},
   467  				InvalidRowsProvider: func() []*sqlmock.Rows {
   468  					return []*sqlmock.Rows{sqlmock.NewRows(fixBundleColumns())}
   469  				},
   470  			},
   471  		},
   472  		ConverterMockProvider: func() testdb.Mock {
   473  			return &automock.EntityConverter{}
   474  		},
   475  		RepoConstructorFunc:   bundle.NewRepository,
   476  		ExpectedModelEntities: []interface{}{firstAppBndlModel, secondAppBndlModel},
   477  		ExpectedDBEntities:    []interface{}{firstAppBundleEntity, secondAppBundleEntity},
   478  		MethodArgs:            []interface{}{tenantID, appID, resource.Application},
   479  		MethodName:            "ListByResourceIDNoPaging",
   480  	}
   481  
   482  	suiteForApplicationTemplateVersion := testdb.RepoListTestSuite{
   483  		Name: "List Bundles No Paging",
   484  		SQLQueryDetails: []testdb.SQLQueryDetails{
   485  			{
   486  				Query:    regexp.QuoteMeta(`SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema, default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies, ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM public.bundles WHERE app_template_version_id = $1 FOR UPDATE`),
   487  				Args:     []driver.Value{appTemplateVersionID},
   488  				IsSelect: true,
   489  				ValidRowsProvider: func() []*sqlmock.Rows {
   490  					return []*sqlmock.Rows{sqlmock.NewRows(fixBundleColumns()).
   491  						AddRow(fixBundleRowWithAppTemplateVersionID(firstBundleID)...).AddRow(fixBundleRowWithAppTemplateVersionID(secondBundleID)...)}
   492  				},
   493  				InvalidRowsProvider: func() []*sqlmock.Rows {
   494  					return []*sqlmock.Rows{sqlmock.NewRows(fixBundleColumns())}
   495  				},
   496  			},
   497  		},
   498  		ConverterMockProvider: func() testdb.Mock {
   499  			return &automock.EntityConverter{}
   500  		},
   501  		RepoConstructorFunc:   bundle.NewRepository,
   502  		ExpectedModelEntities: []interface{}{firstAppTemplateVersionBndlModel, secondAppTemplateVersionBndlModel},
   503  		ExpectedDBEntities:    []interface{}{firstAppTemplateVersionBundleEntity, secondAppTemplateVersionBundleEntity},
   504  		MethodArgs:            []interface{}{tenantID, appTemplateVersionID, resource.ApplicationTemplateVersion},
   505  		MethodName:            "ListByResourceIDNoPaging",
   506  	}
   507  
   508  	suiteForApplication.Run(t)
   509  	suiteForApplicationTemplateVersion.Run(t)
   510  }
   511  
   512  func TestPgRepository_ListByDestination(t *testing.T) {
   513  	bndlEntity := fixEntityBundleWithAppID(bundleID, "foo", "bar")
   514  	modelBundle := fixBundleModel("foo", "bar")
   515  
   516  	destinationWithSystemName := model.DestinationInput{
   517  		XSystemBaseURL:    "http://localhost",
   518  		XSystemTenantName: "system_name",
   519  		XCorrelationID:    "correlation_id",
   520  	}
   521  
   522  	suiteBySystemName := testdb.RepoListTestSuite{
   523  		Name: "List Bundles By Destination with system name",
   524  		SQLQueryDetails: []testdb.SQLQueryDetails{
   525  			{
   526  				Query: regexp.QuoteMeta(`SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema, 
   527  					default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies,
   528  					ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM 
   529  					public.bundles WHERE app_id IN (
   530  						SELECT id
   531  						FROM public.applications
   532  						WHERE id IN (
   533  							SELECT id
   534  							FROM tenant_applications
   535  							WHERE tenant_id=(SELECT parent FROM business_tenant_mappings WHERE id = $1 )
   536  						)
   537  						AND name = $2 AND base_url = $3
   538  				) AND correlation_ids ?| array[$4]`),
   539  				Args: []driver.Value{tenantID, destinationWithSystemName.XSystemTenantName,
   540  					destinationWithSystemName.XSystemBaseURL, destinationWithSystemName.XCorrelationID},
   541  				IsSelect: true,
   542  				ValidRowsProvider: func() []*sqlmock.Rows {
   543  					return []*sqlmock.Rows{sqlmock.NewRows(fixBundleColumns()).
   544  						AddRow(fixBundleRowWithAppID(bundleID)...),
   545  					}
   546  				},
   547  				InvalidRowsProvider: func() []*sqlmock.Rows {
   548  					return []*sqlmock.Rows{sqlmock.NewRows(fixBundleColumns())}
   549  				},
   550  			},
   551  		},
   552  		ConverterMockProvider: func() testdb.Mock {
   553  			return &automock.EntityConverter{}
   554  		},
   555  		RepoConstructorFunc:   bundle.NewRepository,
   556  		ExpectedModelEntities: []interface{}{modelBundle},
   557  		ExpectedDBEntities:    []interface{}{bndlEntity},
   558  		MethodArgs:            []interface{}{tenantID, destinationWithSystemName},
   559  		MethodName:            "ListByDestination",
   560  	}
   561  
   562  	suiteBySystemName.Run(t)
   563  
   564  	destinationWithSystemID := model.DestinationInput{
   565  		XSystemType:     "system_type",
   566  		XSystemTenantID: "system_id",
   567  		XCorrelationID:  "correlation_id",
   568  	}
   569  
   570  	suiteBySystemID := testdb.RepoListTestSuite{
   571  		Name: "List Bundles By Destination with system ID",
   572  		SQLQueryDetails: []testdb.SQLQueryDetails{
   573  			{
   574  				Query: regexp.QuoteMeta(`SELECT id, app_id, app_template_version_id, name, description, version, instance_auth_request_json_schema,
   575  					default_instance_auth, ord_id, local_tenant_id, short_description, links, labels, credential_exchange_strategies,
   576  					ready, created_at, updated_at, deleted_at, error, correlation_ids, tags, resource_hash, documentation_labels FROM
   577  					public.bundles WHERE app_id IN (
   578  						SELECT DISTINCT pa.id as id
   579  						FROM public.applications pa JOIN labels l ON pa.id=l.app_id
   580  						WHERE pa.id IN (
   581  							SELECT id
   582  							FROM tenant_applications
   583  							WHERE tenant_id=(SELECT parent FROM business_tenant_mappings WHERE id = $1 )
   584  						)
   585  						AND l.key='applicationType'
   586  						AND l.value ?| array[$2]
   587  						AND pa.local_tenant_id = $3
   588  				) AND correlation_ids ?| array[$4]`),
   589  				Args: []driver.Value{tenantID, destinationWithSystemID.XSystemType,
   590  					destinationWithSystemID.XSystemTenantID, destinationWithSystemID.XCorrelationID},
   591  				IsSelect: true,
   592  				ValidRowsProvider: func() []*sqlmock.Rows {
   593  					return []*sqlmock.Rows{sqlmock.NewRows(fixBundleColumns()).
   594  						AddRow(fixBundleRowWithAppID(bundleID)...),
   595  					}
   596  				},
   597  				InvalidRowsProvider: func() []*sqlmock.Rows {
   598  					return []*sqlmock.Rows{sqlmock.NewRows(fixBundleColumns())}
   599  				},
   600  			},
   601  		},
   602  		ConverterMockProvider: func() testdb.Mock {
   603  			return &automock.EntityConverter{}
   604  		},
   605  		RepoConstructorFunc:   bundle.NewRepository,
   606  		ExpectedModelEntities: []interface{}{modelBundle},
   607  		ExpectedDBEntities:    []interface{}{bndlEntity},
   608  		MethodArgs:            []interface{}{tenantID, destinationWithSystemID},
   609  		MethodName:            "ListByDestination",
   610  	}
   611  
   612  	suiteBySystemID.Run(t)
   613  }