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

     1  package apptemplate_test
     2  
     3  import (
     4  	"context"
     5  	"database/sql/driver"
     6  	"regexp"
     7  	"testing"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/internal/labelfilter"
    10  
    11  	"github.com/kyma-incubator/compass/components/director/internal/domain/apptemplate"
    12  
    13  	"github.com/kyma-incubator/compass/components/director/internal/domain/apptemplate/automock"
    14  	"github.com/kyma-incubator/compass/components/director/internal/model"
    15  	"github.com/kyma-incubator/compass/components/director/internal/repo/testdb"
    16  	"github.com/kyma-incubator/compass/components/director/pkg/persistence"
    17  
    18  	"github.com/DATA-DOG/go-sqlmock"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  func TestRepository_Create(t *testing.T) {
    24  	t.Run("Success", func(t *testing.T) {
    25  		// GIVEN
    26  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
    27  		appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
    28  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
    29  
    30  		mockConverter := &automock.EntityConverter{}
    31  		defer mockConverter.AssertExpectations(t)
    32  		mockConverter.On("ToEntity", appTemplateModel).Return(appTemplateEntity, nil).Once()
    33  		db, dbMock := testdb.MockDatabase(t)
    34  		defer dbMock.AssertExpectations(t)
    35  		dbMock.ExpectExec(regexp.QuoteMeta(`INSERT INTO public.app_templates ( id, name, description, application_namespace, application_input, placeholders, access_level ) VALUES ( ?, ?, ?, ?, ?, ?, ? )`)).
    36  			WithArgs(fixAppTemplateCreateArgs(*appTemplateEntity)...).
    37  			WillReturnResult(sqlmock.NewResult(-1, 1))
    38  
    39  		ctx := persistence.SaveToContext(context.TODO(), db)
    40  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
    41  
    42  		// WHEN
    43  		err := appTemplateRepo.Create(ctx, *appTemplateModel)
    44  
    45  		// THEN
    46  		require.NoError(t, err)
    47  	})
    48  
    49  	t.Run("Error when converting", func(t *testing.T) {
    50  		// GIVEN
    51  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
    52  		appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
    53  
    54  		mockConverter := &automock.EntityConverter{}
    55  		defer mockConverter.AssertExpectations(t)
    56  		mockConverter.On("ToEntity", appTemplateModel).Return(nil, testError).Once()
    57  
    58  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
    59  
    60  		// WHEN
    61  		err := appTemplateRepo.Create(context.TODO(), *appTemplateModel)
    62  
    63  		// THEN
    64  		require.Error(t, err)
    65  		assert.Contains(t, err.Error(), testError.Error())
    66  	})
    67  
    68  	t.Run("Error when creating", func(t *testing.T) {
    69  		// GIVEN
    70  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
    71  		appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
    72  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
    73  
    74  		mockConverter := &automock.EntityConverter{}
    75  		defer mockConverter.AssertExpectations(t)
    76  		mockConverter.On("ToEntity", appTemplateModel).Return(appTemplateEntity, nil).Once()
    77  		db, dbMock := testdb.MockDatabase(t)
    78  		defer dbMock.AssertExpectations(t)
    79  		dbMock.ExpectExec(regexp.QuoteMeta(`INSERT INTO public.app_templates ( id, name, description, application_namespace, application_input, placeholders, access_level ) VALUES ( ?, ?, ?, ?, ?, ?, ? )`)).
    80  			WithArgs(fixAppTemplateCreateArgs(*appTemplateEntity)...).
    81  			WillReturnError(testError)
    82  
    83  		ctx := persistence.SaveToContext(context.TODO(), db)
    84  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
    85  
    86  		// WHEN
    87  		err := appTemplateRepo.Create(ctx, *appTemplateModel)
    88  
    89  		// THEN
    90  		require.Error(t, err)
    91  		assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
    92  	})
    93  }
    94  
    95  func TestRepository_Get(t *testing.T) {
    96  	t.Run("Success", func(t *testing.T) {
    97  		// GIVEN
    98  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
    99  		appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
   100  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   101  
   102  		mockConverter := &automock.EntityConverter{}
   103  		defer mockConverter.AssertExpectations(t)
   104  		mockConverter.On("FromEntity", appTemplateEntity).Return(appTemplateModel, nil).Once()
   105  		db, dbMock := testdb.MockDatabase(t)
   106  		defer dbMock.AssertExpectations(t)
   107  
   108  		rowsToReturn := fixSQLRows([]apptemplate.Entity{*appTemplateEntity})
   109  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id = $1`)).
   110  			WithArgs(testID).
   111  			WillReturnRows(rowsToReturn)
   112  
   113  		ctx := persistence.SaveToContext(context.TODO(), db)
   114  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   115  
   116  		// WHEN
   117  		result, err := appTemplateRepo.Get(ctx, testID)
   118  
   119  		// THEN
   120  		require.NoError(t, err)
   121  		require.NotNil(t, result)
   122  		assert.Equal(t, appTemplateModel, result)
   123  	})
   124  
   125  	t.Run("Error when getting", func(t *testing.T) {
   126  		// GIVEN
   127  		mockConverter := &automock.EntityConverter{}
   128  		defer mockConverter.AssertExpectations(t)
   129  		db, dbMock := testdb.MockDatabase(t)
   130  		defer dbMock.AssertExpectations(t)
   131  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id = $1`)).
   132  			WithArgs(testID).
   133  			WillReturnError(testError)
   134  
   135  		ctx := persistence.SaveToContext(context.TODO(), db)
   136  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   137  
   138  		// WHEN
   139  		_, err := appTemplateRepo.Get(ctx, testID)
   140  
   141  		// THEN
   142  		require.Error(t, err)
   143  		assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   144  	})
   145  
   146  	t.Run("Error when converting", func(t *testing.T) {
   147  		// GIVEN
   148  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   149  
   150  		mockConverter := &automock.EntityConverter{}
   151  		defer mockConverter.AssertExpectations(t)
   152  		mockConverter.On("FromEntity", appTemplateEntity).Return(nil, testError).Once()
   153  		db, dbMock := testdb.MockDatabase(t)
   154  		defer dbMock.AssertExpectations(t)
   155  
   156  		rowsToReturn := fixSQLRows([]apptemplate.Entity{*appTemplateEntity})
   157  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id = $1`)).
   158  			WithArgs(testID).
   159  			WillReturnRows(rowsToReturn)
   160  
   161  		ctx := persistence.SaveToContext(context.TODO(), db)
   162  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   163  
   164  		// WHEN
   165  		_, err := appTemplateRepo.Get(ctx, testID)
   166  
   167  		// THEN
   168  		require.Error(t, err)
   169  		assert.Contains(t, err.Error(), testError.Error())
   170  	})
   171  }
   172  
   173  func TestRepository_ListByName(t *testing.T) {
   174  	t.Run("Success", func(t *testing.T) {
   175  		// GIVEN
   176  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
   177  		appTemplate := fixModelApplicationTemplate(testID, testName, webhooksModel)
   178  		appTemplates := []*model.ApplicationTemplate{appTemplate}
   179  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   180  
   181  		mockConverter := &automock.EntityConverter{}
   182  		defer mockConverter.AssertExpectations(t)
   183  		mockConverter.On("FromEntity", appTemplateEntity).Return(appTemplate, nil).Once()
   184  		db, dbMock := testdb.MockDatabase(t)
   185  		defer dbMock.AssertExpectations(t)
   186  
   187  		rowsToReturn := fixSQLRows([]apptemplate.Entity{*appTemplateEntity})
   188  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE name = $1`)).
   189  			WithArgs(testName).
   190  			WillReturnRows(rowsToReturn)
   191  
   192  		ctx := persistence.SaveToContext(context.TODO(), db)
   193  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   194  
   195  		// WHEN
   196  		result, err := appTemplateRepo.ListByName(ctx, testName)
   197  
   198  		// THEN
   199  		require.NoError(t, err)
   200  		require.NotNil(t, result)
   201  		assert.Equal(t, appTemplates, result)
   202  	})
   203  
   204  	t.Run("Error when getting", func(t *testing.T) {
   205  		// GIVEN
   206  		mockConverter := &automock.EntityConverter{}
   207  		defer mockConverter.AssertExpectations(t)
   208  		db, dbMock := testdb.MockDatabase(t)
   209  		defer dbMock.AssertExpectations(t)
   210  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE name = $1`)).
   211  			WithArgs(testName).
   212  			WillReturnError(testError)
   213  
   214  		ctx := persistence.SaveToContext(context.TODO(), db)
   215  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   216  
   217  		// WHEN
   218  		_, err := appTemplateRepo.ListByName(ctx, testName)
   219  
   220  		// THEN
   221  		require.Error(t, err)
   222  		assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   223  	})
   224  
   225  	t.Run("Error when converting", func(t *testing.T) {
   226  		// GIVEN
   227  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   228  
   229  		mockConverter := &automock.EntityConverter{}
   230  		defer mockConverter.AssertExpectations(t)
   231  		mockConverter.On("FromEntity", appTemplateEntity).Return(nil, testError).Once()
   232  		db, dbMock := testdb.MockDatabase(t)
   233  		defer dbMock.AssertExpectations(t)
   234  
   235  		rowsToReturn := fixSQLRows([]apptemplate.Entity{*appTemplateEntity})
   236  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE name = $1`)).
   237  			WithArgs(testName).
   238  			WillReturnRows(rowsToReturn)
   239  
   240  		ctx := persistence.SaveToContext(context.TODO(), db)
   241  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   242  
   243  		// WHEN
   244  		_, err := appTemplateRepo.ListByName(ctx, testName)
   245  
   246  		// THEN
   247  		require.Error(t, err)
   248  		assert.Contains(t, err.Error(), testError.Error())
   249  	})
   250  }
   251  
   252  func TestRepository_ListByFilters(t *testing.T) {
   253  	t.Run("Success", func(t *testing.T) {
   254  		// GIVEN
   255  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
   256  		appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
   257  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   258  
   259  		mockConverter := &automock.EntityConverter{}
   260  		defer mockConverter.AssertExpectations(t)
   261  		mockConverter.On("FromEntity", appTemplateEntity).Return(appTemplateModel, nil).Once()
   262  		db, dbMock := testdb.MockDatabase(t)
   263  		defer dbMock.AssertExpectations(t)
   264  
   265  		rowsToReturn := fixSQLRows([]apptemplate.Entity{*appTemplateEntity})
   266  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id IN (SELECT "app_template_id" FROM public.labels WHERE "app_template_id" IS NOT NULL AND "key" = $1)`)).
   267  			WithArgs("someKey").
   268  			WillReturnRows(rowsToReturn)
   269  
   270  		ctx := persistence.SaveToContext(context.TODO(), db)
   271  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   272  
   273  		// WHEN
   274  		filters := []*labelfilter.LabelFilter{labelfilter.NewForKey("someKey")}
   275  		result, err := appTemplateRepo.ListByFilters(ctx, filters)
   276  
   277  		// THEN
   278  		require.NoError(t, err)
   279  		require.NotNil(t, result)
   280  		assert.Equal(t, []*model.ApplicationTemplate{appTemplateModel}, result)
   281  	})
   282  
   283  	t.Run("Error when listing by filters", func(t *testing.T) {
   284  		// GIVEN
   285  		mockConverter := &automock.EntityConverter{}
   286  		defer mockConverter.AssertExpectations(t)
   287  		db, dbMock := testdb.MockDatabase(t)
   288  		defer dbMock.AssertExpectations(t)
   289  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id IN (SELECT "app_template_id" FROM public.labels WHERE "app_template_id" IS NOT NULL AND "key" = $1)`)).
   290  			WithArgs("someKey").
   291  			WillReturnError(testError)
   292  
   293  		ctx := persistence.SaveToContext(context.TODO(), db)
   294  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   295  
   296  		// WHEN
   297  		filters := []*labelfilter.LabelFilter{labelfilter.NewForKey("someKey")}
   298  		_, err := appTemplateRepo.ListByFilters(ctx, filters)
   299  
   300  		// THEN
   301  		require.Error(t, err)
   302  		assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   303  	})
   304  
   305  	t.Run("Error when converting", func(t *testing.T) {
   306  		// GIVEN
   307  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   308  
   309  		mockConverter := &automock.EntityConverter{}
   310  		defer mockConverter.AssertExpectations(t)
   311  		mockConverter.On("FromEntity", appTemplateEntity).Return(nil, testError).Once()
   312  		db, dbMock := testdb.MockDatabase(t)
   313  		defer dbMock.AssertExpectations(t)
   314  
   315  		rowsToReturn := fixSQLRows([]apptemplate.Entity{*appTemplateEntity})
   316  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id IN (SELECT "app_template_id" FROM public.labels WHERE "app_template_id" IS NOT NULL AND "key" = $1)`)).
   317  			WithArgs("someKey").
   318  			WillReturnRows(rowsToReturn)
   319  
   320  		ctx := persistence.SaveToContext(context.TODO(), db)
   321  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   322  
   323  		// WHEN
   324  		filters := []*labelfilter.LabelFilter{labelfilter.NewForKey("someKey")}
   325  		_, err := appTemplateRepo.ListByFilters(ctx, filters)
   326  
   327  		// THEN
   328  		require.Error(t, err)
   329  		assert.Contains(t, err.Error(), testError.Error())
   330  	})
   331  }
   332  
   333  func TestRepository_GetByFilters(t *testing.T) {
   334  	t.Run("Success", func(t *testing.T) {
   335  		// GIVEN
   336  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
   337  		appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
   338  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   339  
   340  		mockConverter := &automock.EntityConverter{}
   341  		defer mockConverter.AssertExpectations(t)
   342  		mockConverter.On("FromEntity", appTemplateEntity).Return(appTemplateModel, nil).Once()
   343  		db, dbMock := testdb.MockDatabase(t)
   344  		defer dbMock.AssertExpectations(t)
   345  
   346  		rowsToReturn := fixSQLRows([]apptemplate.Entity{*appTemplateEntity})
   347  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id IN (SELECT "app_template_id" FROM public.labels WHERE "app_template_id" IS NOT NULL AND "key" = $1)`)).
   348  			WithArgs("someKey").
   349  			WillReturnRows(rowsToReturn)
   350  
   351  		ctx := persistence.SaveToContext(context.TODO(), db)
   352  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   353  
   354  		// WHEN
   355  		filters := []*labelfilter.LabelFilter{labelfilter.NewForKey("someKey")}
   356  		result, err := appTemplateRepo.GetByFilters(ctx, filters)
   357  
   358  		// THEN
   359  		require.NoError(t, err)
   360  		require.NotNil(t, result)
   361  		assert.Equal(t, appTemplateModel, result)
   362  	})
   363  
   364  	t.Run("Error when getting", func(t *testing.T) {
   365  		// GIVEN
   366  		mockConverter := &automock.EntityConverter{}
   367  		defer mockConverter.AssertExpectations(t)
   368  		db, dbMock := testdb.MockDatabase(t)
   369  		defer dbMock.AssertExpectations(t)
   370  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id IN (SELECT "app_template_id" FROM public.labels WHERE "app_template_id" IS NOT NULL AND "key" = $1)`)).
   371  			WithArgs("someKey").
   372  			WillReturnError(testError)
   373  
   374  		ctx := persistence.SaveToContext(context.TODO(), db)
   375  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   376  
   377  		// WHEN
   378  		filters := []*labelfilter.LabelFilter{labelfilter.NewForKey("someKey")}
   379  		_, err := appTemplateRepo.GetByFilters(ctx, filters)
   380  
   381  		// THEN
   382  		require.Error(t, err)
   383  		assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   384  	})
   385  
   386  	t.Run("Error when converting", func(t *testing.T) {
   387  		// GIVEN
   388  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   389  
   390  		mockConverter := &automock.EntityConverter{}
   391  		defer mockConverter.AssertExpectations(t)
   392  		mockConverter.On("FromEntity", appTemplateEntity).Return(nil, testError).Once()
   393  		db, dbMock := testdb.MockDatabase(t)
   394  		defer dbMock.AssertExpectations(t)
   395  
   396  		rowsToReturn := fixSQLRows([]apptemplate.Entity{*appTemplateEntity})
   397  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id IN (SELECT "app_template_id" FROM public.labels WHERE "app_template_id" IS NOT NULL AND "key" = $1)`)).
   398  			WithArgs("someKey").
   399  			WillReturnRows(rowsToReturn)
   400  
   401  		ctx := persistence.SaveToContext(context.TODO(), db)
   402  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   403  
   404  		// WHEN
   405  		filters := []*labelfilter.LabelFilter{labelfilter.NewForKey("someKey")}
   406  		_, err := appTemplateRepo.GetByFilters(ctx, filters)
   407  
   408  		// THEN
   409  		require.Error(t, err)
   410  		assert.Contains(t, err.Error(), testError.Error())
   411  	})
   412  }
   413  
   414  func TestRepository_Exists(t *testing.T) {
   415  	t.Run("Success", func(t *testing.T) {
   416  		// GIVEN
   417  		db, dbMock := testdb.MockDatabase(t)
   418  		defer dbMock.AssertExpectations(t)
   419  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT 1 FROM public.app_templates WHERE id = $1`)).
   420  			WithArgs(testID).
   421  			WillReturnRows(testdb.RowWhenObjectExist())
   422  
   423  		ctx := persistence.SaveToContext(context.TODO(), db)
   424  		appTemplateRepo := apptemplate.NewRepository(nil)
   425  
   426  		// WHEN
   427  		result, err := appTemplateRepo.Exists(ctx, testID)
   428  
   429  		// THEN
   430  		require.NoError(t, err)
   431  		require.NotNil(t, result)
   432  		assert.True(t, result)
   433  	})
   434  
   435  	t.Run("Error when checking existence", func(t *testing.T) {
   436  		// GIVEN
   437  		db, dbMock := testdb.MockDatabase(t)
   438  		defer dbMock.AssertExpectations(t)
   439  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT 1 FROM public.app_templates WHERE id = $1`)).
   440  			WithArgs(testID).
   441  			WillReturnError(testError)
   442  
   443  		ctx := persistence.SaveToContext(context.TODO(), db)
   444  		appTemplateRepo := apptemplate.NewRepository(nil)
   445  
   446  		// WHEN
   447  		result, err := appTemplateRepo.Exists(ctx, testID)
   448  
   449  		// THEN
   450  		require.Error(t, err)
   451  		assert.Contains(t, err.Error(), "Internal Server Error: Unexpected error while executing SQL query")
   452  		assert.False(t, result)
   453  	})
   454  }
   455  
   456  func TestRepository_List(t *testing.T) {
   457  	t.Run("Success", func(t *testing.T) {
   458  		// GIVEN
   459  		webhooksModel := [][]*model.Webhook{
   460  			fixModelApplicationWebhooks("test-webhook-1", "id1"),
   461  			fixModelApplicationWebhooks("test-webhook-2", "id2"),
   462  			fixModelApplicationWebhooks("test-webhook-3", "id3"),
   463  		}
   464  
   465  		appTemplateModels := []*model.ApplicationTemplate{
   466  			fixModelApplicationTemplate("id1", "name1", webhooksModel[0]),
   467  			fixModelApplicationTemplate("id2", "name2", webhooksModel[1]),
   468  			fixModelApplicationTemplate("id3", "name3", webhooksModel[2]),
   469  		}
   470  
   471  		appTemplateEntities := []apptemplate.Entity{
   472  			*fixEntityApplicationTemplate(t, "id1", "name1"),
   473  			*fixEntityApplicationTemplate(t, "id2", "name2"),
   474  			*fixEntityApplicationTemplate(t, "id3", "name3"),
   475  		}
   476  
   477  		labelFilters := []*labelfilter.LabelFilter{labelfilter.NewForKeyWithQuery(RegionKey, "eu-1")}
   478  
   479  		mockConverter := &automock.EntityConverter{}
   480  		defer mockConverter.AssertExpectations(t)
   481  
   482  		for i := range appTemplateEntities {
   483  			mockConverter.On("FromEntity", &appTemplateEntities[i]).Return(appTemplateModels[i], nil).Once()
   484  		}
   485  		db, dbMock := testdb.MockDatabase(t)
   486  		defer dbMock.AssertExpectations(t)
   487  
   488  		rowsToReturn := fixSQLRows(appTemplateEntities)
   489  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id IN (SELECT "app_template_id" FROM public.labels WHERE "app_template_id" IS NOT NULL AND "key" = $1 AND "value" @> $2) ORDER BY id LIMIT 3 OFFSET 0`)).
   490  			WillReturnRows(rowsToReturn)
   491  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT COUNT(*) FROM public.app_templates`)).
   492  			WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(3))
   493  
   494  		ctx := persistence.SaveToContext(context.TODO(), db)
   495  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   496  
   497  		// WHEN
   498  		result, err := appTemplateRepo.List(ctx, labelFilters, testPageSize, testCursor)
   499  
   500  		// THEN
   501  		require.NoError(t, err)
   502  		require.NotNil(t, result)
   503  		assert.Equal(t, appTemplateModels, result.Data)
   504  	})
   505  
   506  	t.Run("Error when converting", func(t *testing.T) {
   507  		// GIVEN
   508  		appTemplateEntities := []apptemplate.Entity{
   509  			*fixEntityApplicationTemplate(t, "id1", "name1"),
   510  		}
   511  
   512  		labelFilters := []*labelfilter.LabelFilter{labelfilter.NewForKeyWithQuery(RegionKey, "eu-1")}
   513  
   514  		mockConverter := &automock.EntityConverter{}
   515  		defer mockConverter.AssertExpectations(t)
   516  
   517  		mockConverter.On("FromEntity", &appTemplateEntities[0]).Return(nil, testError).Once()
   518  		db, dbMock := testdb.MockDatabase(t)
   519  		defer dbMock.AssertExpectations(t)
   520  
   521  		rowsToReturn := fixSQLRows(appTemplateEntities)
   522  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id IN (SELECT "app_template_id" FROM public.labels WHERE "app_template_id" IS NOT NULL AND "key" = $1 AND "value" @> $2) ORDER BY id LIMIT 3 OFFSET 0`)).
   523  			WillReturnRows(rowsToReturn)
   524  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT COUNT(*) FROM public.app_templates`)).
   525  			WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(3))
   526  
   527  		ctx := persistence.SaveToContext(context.TODO(), db)
   528  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   529  
   530  		// WHEN
   531  		_, err := appTemplateRepo.List(ctx, labelFilters, testPageSize, testCursor)
   532  
   533  		// THEN
   534  		require.Error(t, err)
   535  		assert.Contains(t, err.Error(), testError.Error())
   536  	})
   537  
   538  	t.Run("Error when listing", func(t *testing.T) {
   539  		// GIVEN
   540  		mockConverter := &automock.EntityConverter{}
   541  		defer mockConverter.AssertExpectations(t)
   542  		db, dbMock := testdb.MockDatabase(t)
   543  		defer dbMock.AssertExpectations(t)
   544  		dbMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates ORDER BY id LIMIT 3 OFFSET 0`)).
   545  			WillReturnError(testError)
   546  
   547  		ctx := persistence.SaveToContext(context.TODO(), db)
   548  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   549  
   550  		// WHEN
   551  		_, err := appTemplateRepo.List(ctx, nil, testPageSize, testCursor)
   552  
   553  		// THEN
   554  		require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   555  	})
   556  }
   557  
   558  func TestRepository_Update(t *testing.T) {
   559  	t.Run("Success", func(t *testing.T) {
   560  		// GIVEN
   561  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
   562  		appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
   563  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   564  
   565  		mockConverter := &automock.EntityConverter{}
   566  		defer mockConverter.AssertExpectations(t)
   567  		mockConverter.On("ToEntity", appTemplateModel).Return(appTemplateEntity, nil).Once()
   568  		db, dbMock := testdb.MockDatabase(t)
   569  		defer dbMock.AssertExpectations(t)
   570  		dbMock.ExpectExec(regexp.QuoteMeta(`UPDATE public.app_templates SET name = ?, description = ?, application_namespace = ?, application_input = ?, placeholders = ?, access_level = ? WHERE id = ?`)).
   571  			WithArgs(appTemplateEntity.Name, appTemplateEntity.Description, appTemplateEntity.ApplicationNamespace, appTemplateEntity.ApplicationInputJSON, appTemplateEntity.PlaceholdersJSON, appTemplateEntity.AccessLevel, appTemplateEntity.ID).
   572  			WillReturnResult(sqlmock.NewResult(-1, 1))
   573  
   574  		ctx := persistence.SaveToContext(context.TODO(), db)
   575  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   576  
   577  		// WHEN
   578  		err := appTemplateRepo.Update(ctx, *appTemplateModel)
   579  
   580  		// THEN
   581  		require.NoError(t, err)
   582  	})
   583  
   584  	t.Run("Error when updating", func(t *testing.T) {
   585  		// GIVEN
   586  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
   587  		appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
   588  		appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   589  
   590  		mockConverter := &automock.EntityConverter{}
   591  		defer mockConverter.AssertExpectations(t)
   592  		mockConverter.On("ToEntity", appTemplateModel).Return(appTemplateEntity, nil).Once()
   593  		db, dbMock := testdb.MockDatabase(t)
   594  		defer dbMock.AssertExpectations(t)
   595  		dbMock.ExpectExec(regexp.QuoteMeta(`UPDATE public.app_templates SET name = ?, description = ?, application_namespace = ?, application_input = ?, placeholders = ?, access_level = ? WHERE id = ?`)).
   596  			WithArgs(appTemplateEntity.Name, appTemplateEntity.Description, appTemplateEntity.ApplicationNamespace, appTemplateEntity.ApplicationInputJSON, appTemplateEntity.PlaceholdersJSON, appTemplateEntity.AccessLevel, appTemplateEntity.ID).
   597  			WillReturnError(testError)
   598  
   599  		ctx := persistence.SaveToContext(context.TODO(), db)
   600  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   601  
   602  		// WHEN
   603  		err := appTemplateRepo.Update(ctx, *appTemplateModel)
   604  
   605  		// THEN
   606  		require.Error(t, err)
   607  		assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   608  	})
   609  
   610  	t.Run("Error when converting", func(t *testing.T) {
   611  		// GIVEN
   612  		webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
   613  		appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
   614  
   615  		mockConverter := &automock.EntityConverter{}
   616  		defer mockConverter.AssertExpectations(t)
   617  		mockConverter.On("ToEntity", appTemplateModel).Return(nil, testError).Once()
   618  
   619  		appTemplateRepo := apptemplate.NewRepository(mockConverter)
   620  
   621  		// WHEN
   622  		err := appTemplateRepo.Update(context.TODO(), *appTemplateModel)
   623  
   624  		// THEN
   625  		require.Error(t, err)
   626  		assert.Contains(t, err.Error(), testError.Error())
   627  	})
   628  }
   629  
   630  func TestRepository_Delete(t *testing.T) {
   631  	t.Run("Success", func(t *testing.T) {
   632  		// GIVEN
   633  		db, dbMock := testdb.MockDatabase(t)
   634  		defer dbMock.AssertExpectations(t)
   635  		dbMock.ExpectExec(regexp.QuoteMeta(`DELETE FROM public.app_templates WHERE id = $1`)).
   636  			WithArgs(testID).
   637  			WillReturnResult(sqlmock.NewResult(-1, 1))
   638  
   639  		ctx := persistence.SaveToContext(context.TODO(), db)
   640  		appTemplateRepo := apptemplate.NewRepository(nil)
   641  
   642  		// WHEN
   643  		err := appTemplateRepo.Delete(ctx, testID)
   644  
   645  		// THEN
   646  		require.NoError(t, err)
   647  	})
   648  
   649  	t.Run("Error when deleting", func(t *testing.T) {
   650  		// GIVEN
   651  		db, dbMock := testdb.MockDatabase(t)
   652  		defer dbMock.AssertExpectations(t)
   653  		dbMock.ExpectExec(regexp.QuoteMeta(`DELETE FROM public.app_templates WHERE id = $1`)).
   654  			WithArgs(testID).
   655  			WillReturnError(testError)
   656  
   657  		ctx := persistence.SaveToContext(context.TODO(), db)
   658  		appTemplateRepo := apptemplate.NewRepository(nil)
   659  
   660  		// WHEN
   661  		err := appTemplateRepo.Delete(ctx, testID)
   662  
   663  		// THEN
   664  		require.Error(t, err)
   665  		assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   666  	})
   667  }
   668  
   669  func TestRepository_ListByIDs(t *testing.T) {
   670  	webhooksModel := fixModelApplicationWebhooks(testWebhookID, testID)
   671  	appTemplateModel := fixModelApplicationTemplate(testID, testName, webhooksModel)
   672  	appTemplateEntity := fixEntityApplicationTemplate(t, testID, testName)
   673  	suite := testdb.RepoListTestSuite{
   674  		Name:       "Get Formation Template By ID",
   675  		MethodName: "ListByIDs",
   676  		SQLQueryDetails: []testdb.SQLQueryDetails{
   677  			{
   678  				Query:    regexp.QuoteMeta(`SELECT id, name, description, application_namespace, application_input, placeholders, access_level FROM public.app_templates WHERE id IN ($1)`),
   679  				IsSelect: true,
   680  				ValidRowsProvider: func() []*sqlmock.Rows {
   681  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns()).AddRow(appTemplateEntity.ID, appTemplateEntity.Name, appTemplateEntity.Description, appTemplateEntity.ApplicationNamespace, appTemplateEntity.ApplicationInputJSON, appTemplateEntity.PlaceholdersJSON, appTemplateEntity.AccessLevel)}
   682  				},
   683  				InvalidRowsProvider: func() []*sqlmock.Rows {
   684  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns())}
   685  				},
   686  				Args: []driver.Value{testID},
   687  			},
   688  		},
   689  		ExpectedModelEntities: []interface{}{appTemplateModel},
   690  		ExpectedDBEntities:    []interface{}{appTemplateEntity},
   691  		ConverterMockProvider: func() testdb.Mock {
   692  			return &automock.EntityConverter{}
   693  		},
   694  		RepoConstructorFunc:       apptemplate.NewRepository,
   695  		MethodArgs:                []interface{}{[]string{testID}},
   696  		DisableConverterErrorTest: false,
   697  	}
   698  
   699  	suite.Run(t)
   700  
   701  	// Additional test - empty slice because test suite returns empty result given valid query
   702  	t.Run("returns empty slice given no scenarios", func(t *testing.T) {
   703  		// GIVEN
   704  		ctx := context.TODO()
   705  		repository := apptemplate.NewRepository(nil)
   706  
   707  		// WHEN
   708  		actual, err := repository.ListByIDs(ctx, []string{})
   709  
   710  		// THEN
   711  		assert.NoError(t, err)
   712  		assert.Nil(t, actual)
   713  	})
   714  }