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

     1  package formationassignment_test
     2  
     3  import (
     4  	"context"
     5  	"database/sql/driver"
     6  	"regexp"
     7  	"testing"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/pkg/persistence"
    10  	"github.com/pkg/errors"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  
    14  	"github.com/DATA-DOG/go-sqlmock"
    15  	"github.com/kyma-incubator/compass/components/director/internal/domain/formationassignment"
    16  	"github.com/kyma-incubator/compass/components/director/internal/domain/formationassignment/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/kyma-incubator/compass/components/director/pkg/pagination"
    20  )
    21  
    22  func TestRepository_Create(t *testing.T) {
    23  	suite := testdb.RepoCreateTestSuite{
    24  		Name:       "Create Formation Assignment",
    25  		MethodName: "Create",
    26  		SQLQueryDetails: []testdb.SQLQueryDetails{
    27  			{
    28  				Query:       `^INSERT INTO public.formation_assignments \(.+\) VALUES \(.+\)$`,
    29  				Args:        []driver.Value{TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr},
    30  				ValidResult: sqlmock.NewResult(-1, 1),
    31  				InvalidRowsProvider: func() []*sqlmock.Rows {
    32  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
    33  				},
    34  			},
    35  		},
    36  		ConverterMockProvider: func() testdb.Mock {
    37  			return &automock.EntityConverter{}
    38  		},
    39  		RepoConstructorFunc:       formationassignment.NewRepository,
    40  		ModelEntity:               faModel,
    41  		DBEntity:                  faEntity,
    42  		NilModelEntity:            nilFormationAssignmentModel,
    43  		IsGlobal:                  true,
    44  		DisableConverterErrorTest: true,
    45  	}
    46  
    47  	suite.Run(t)
    48  }
    49  
    50  func TestRepository_Get(t *testing.T) {
    51  	suite := testdb.RepoGetTestSuite{
    52  		Name:       "Get Formation Assignment by ID",
    53  		MethodName: "Get",
    54  		SQLQueryDetails: []testdb.SQLQueryDetails{
    55  			{
    56  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND id = $2`),
    57  				Args:     []driver.Value{TestTenantID, TestID},
    58  				IsSelect: true,
    59  				ValidRowsProvider: func() []*sqlmock.Rows {
    60  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr)}
    61  				},
    62  				InvalidRowsProvider: func() []*sqlmock.Rows {
    63  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
    64  				},
    65  			},
    66  		},
    67  		ConverterMockProvider: func() testdb.Mock {
    68  			return &automock.EntityConverter{}
    69  		},
    70  		RepoConstructorFunc:       formationassignment.NewRepository,
    71  		ExpectedModelEntity:       fixFormationAssignmentModel(TestConfigValueRawJSON),
    72  		ExpectedDBEntity:          fixFormationAssignmentEntity(TestConfigValueStr),
    73  		MethodArgs:                []interface{}{TestID, TestTenantID},
    74  		DisableConverterErrorTest: true,
    75  	}
    76  
    77  	suite.Run(t)
    78  }
    79  
    80  func TestRepository_GetGlobalByID(t *testing.T) {
    81  	suite := testdb.RepoGetTestSuite{
    82  		Name:       "Get Formation Assignment Globally by ID",
    83  		MethodName: "GetGlobalByID",
    84  		SQLQueryDetails: []testdb.SQLQueryDetails{
    85  			{
    86  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE id = $1`),
    87  				Args:     []driver.Value{TestID},
    88  				IsSelect: true,
    89  				ValidRowsProvider: func() []*sqlmock.Rows {
    90  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr)}
    91  				},
    92  				InvalidRowsProvider: func() []*sqlmock.Rows {
    93  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
    94  				},
    95  			},
    96  		},
    97  		ConverterMockProvider: func() testdb.Mock {
    98  			return &automock.EntityConverter{}
    99  		},
   100  		RepoConstructorFunc:       formationassignment.NewRepository,
   101  		ExpectedModelEntity:       fixFormationAssignmentModel(TestConfigValueRawJSON),
   102  		ExpectedDBEntity:          fixFormationAssignmentEntity(TestConfigValueStr),
   103  		MethodArgs:                []interface{}{TestID},
   104  		DisableConverterErrorTest: true,
   105  	}
   106  
   107  	suite.Run(t)
   108  }
   109  
   110  func TestRepository_GetGlobalByIDAndFormationID(t *testing.T) {
   111  	suite := testdb.RepoGetTestSuite{
   112  		Name:       "Get Formation Assignment Globally by ID and Formation ID",
   113  		MethodName: "GetGlobalByIDAndFormationID",
   114  		SQLQueryDetails: []testdb.SQLQueryDetails{
   115  			{
   116  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE id = $1 AND formation_id = $2`),
   117  				Args:     []driver.Value{TestID, TestFormationID},
   118  				IsSelect: true,
   119  				ValidRowsProvider: func() []*sqlmock.Rows {
   120  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr)}
   121  				},
   122  				InvalidRowsProvider: func() []*sqlmock.Rows {
   123  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
   124  				},
   125  			},
   126  		},
   127  		ConverterMockProvider: func() testdb.Mock {
   128  			return &automock.EntityConverter{}
   129  		},
   130  		RepoConstructorFunc:       formationassignment.NewRepository,
   131  		ExpectedModelEntity:       fixFormationAssignmentModel(TestConfigValueRawJSON),
   132  		ExpectedDBEntity:          fixFormationAssignmentEntity(TestConfigValueStr),
   133  		MethodArgs:                []interface{}{TestID, TestFormationID},
   134  		DisableConverterErrorTest: true,
   135  	}
   136  
   137  	suite.Run(t)
   138  }
   139  
   140  func TestRepository_GetForFormation(t *testing.T) {
   141  	suite := testdb.RepoGetTestSuite{
   142  		Name: "Get Formation Assignment For Formation",
   143  		SQLQueryDetails: []testdb.SQLQueryDetails{
   144  			{
   145  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND id = $2 AND formation_id = $3`),
   146  				Args:     []driver.Value{TestTenantID, TestID, TestFormationID},
   147  				IsSelect: true,
   148  				ValidRowsProvider: func() []*sqlmock.Rows {
   149  					return []*sqlmock.Rows{
   150  						sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr),
   151  					}
   152  				},
   153  				InvalidRowsProvider: func() []*sqlmock.Rows {
   154  					return []*sqlmock.Rows{
   155  						sqlmock.NewRows(fixColumns),
   156  					}
   157  				},
   158  			},
   159  		},
   160  		ConverterMockProvider: func() testdb.Mock {
   161  			return &automock.EntityConverter{}
   162  		},
   163  		RepoConstructorFunc:       formationassignment.NewRepository,
   164  		ExpectedModelEntity:       faModel,
   165  		ExpectedDBEntity:          faEntity,
   166  		MethodArgs:                []interface{}{TestTenantID, TestID, TestFormationID},
   167  		MethodName:                "GetForFormation",
   168  		DisableConverterErrorTest: true,
   169  	}
   170  
   171  	suite.Run(t)
   172  }
   173  
   174  func TestRepository_GetBySourceAndTarget(t *testing.T) {
   175  	suite := testdb.RepoGetTestSuite{
   176  		Name: "Get Formation Assignment by Source and Target",
   177  		SQLQueryDetails: []testdb.SQLQueryDetails{
   178  			{
   179  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND formation_id = $2 AND source = $3 AND target = $4`),
   180  				Args:     []driver.Value{TestTenantID, TestFormationID, TestSource, TestTarget},
   181  				IsSelect: true,
   182  				ValidRowsProvider: func() []*sqlmock.Rows {
   183  					return []*sqlmock.Rows{
   184  						sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr),
   185  					}
   186  				},
   187  				InvalidRowsProvider: func() []*sqlmock.Rows {
   188  					return []*sqlmock.Rows{
   189  						sqlmock.NewRows(fixColumns),
   190  					}
   191  				},
   192  			},
   193  		},
   194  		ConverterMockProvider: func() testdb.Mock {
   195  			return &automock.EntityConverter{}
   196  		},
   197  		RepoConstructorFunc:       formationassignment.NewRepository,
   198  		ExpectedModelEntity:       faModel,
   199  		ExpectedDBEntity:          faEntity,
   200  		MethodArgs:                []interface{}{TestTenantID, TestFormationID, TestSource, TestTarget},
   201  		MethodName:                "GetBySourceAndTarget",
   202  		DisableConverterErrorTest: true,
   203  	}
   204  
   205  	suite.Run(t)
   206  }
   207  
   208  func TestRepository_GetReverseBySourceAndTarget(t *testing.T) {
   209  	suite := testdb.RepoGetTestSuite{
   210  		Name: "Get Reverse Formation Assignment by Source and Target",
   211  		SQLQueryDetails: []testdb.SQLQueryDetails{
   212  			{
   213  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND formation_id = $2 AND source = $3 AND target = $4`),
   214  				Args:     []driver.Value{TestTenantID, TestFormationID, TestTarget, TestSource},
   215  				IsSelect: true,
   216  				ValidRowsProvider: func() []*sqlmock.Rows {
   217  					return []*sqlmock.Rows{
   218  						sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr),
   219  					}
   220  				},
   221  				InvalidRowsProvider: func() []*sqlmock.Rows {
   222  					return []*sqlmock.Rows{
   223  						sqlmock.NewRows(fixColumns),
   224  					}
   225  				},
   226  			},
   227  		},
   228  		ConverterMockProvider: func() testdb.Mock {
   229  			return &automock.EntityConverter{}
   230  		},
   231  		RepoConstructorFunc:       formationassignment.NewRepository,
   232  		ExpectedModelEntity:       faModel,
   233  		ExpectedDBEntity:          faEntity,
   234  		MethodArgs:                []interface{}{TestTenantID, TestFormationID, TestSource, TestTarget},
   235  		MethodName:                "GetReverseBySourceAndTarget",
   236  		DisableConverterErrorTest: true,
   237  	}
   238  
   239  	suite.Run(t)
   240  }
   241  
   242  func TestRepository_List(t *testing.T) {
   243  	suite := testdb.RepoListPageableTestSuite{
   244  		Name:       "List Formations Assignments",
   245  		MethodName: "List",
   246  		SQLQueryDetails: []testdb.SQLQueryDetails{
   247  			{
   248  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 ORDER BY id LIMIT 4 OFFSET 0`),
   249  				Args:     []driver.Value{TestTenantID},
   250  				IsSelect: true,
   251  				ValidRowsProvider: func() []*sqlmock.Rows {
   252  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr)}
   253  				},
   254  				InvalidRowsProvider: func() []*sqlmock.Rows {
   255  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
   256  				},
   257  			},
   258  			{
   259  				Query:    regexp.QuoteMeta(`SELECT COUNT(*) FROM public.formation_assignments`),
   260  				IsSelect: true,
   261  				ValidRowsProvider: func() []*sqlmock.Rows {
   262  					return []*sqlmock.Rows{sqlmock.NewRows([]string{"count"}).AddRow(1)}
   263  				},
   264  			},
   265  		},
   266  		ConverterMockProvider: func() testdb.Mock {
   267  			return &automock.EntityConverter{}
   268  		},
   269  		RepoConstructorFunc: formationassignment.NewRepository,
   270  		Pages: []testdb.PageDetails{
   271  			{
   272  				ExpectedModelEntities: []interface{}{faModel},
   273  				ExpectedDBEntities:    []interface{}{faEntity},
   274  				ExpectedPage: &model.FormationAssignmentPage{
   275  					Data: []*model.FormationAssignment{faModel},
   276  					PageInfo: &pagination.Page{
   277  						StartCursor: "",
   278  						EndCursor:   "",
   279  						HasNextPage: false,
   280  					},
   281  					TotalCount: 1,
   282  				},
   283  			},
   284  		},
   285  		MethodArgs:                []interface{}{4, "", TestTenantID},
   286  		DisableConverterErrorTest: true,
   287  	}
   288  
   289  	suite.Run(t)
   290  }
   291  
   292  func TestRepository_ListByFormationIDs(t *testing.T) {
   293  	emptyPageFormationID := "empty-formation-id"
   294  	onePageFormationID := "one-formation-id"
   295  	multiplePageFormationID := "multiple-formation-id"
   296  
   297  	faModel1 := fixFormationAssignmentModelWithFormationID(onePageFormationID)
   298  	faEntity1 := fixFormationAssignmentEntityWithFormationID(onePageFormationID)
   299  
   300  	faModel2 := fixFormationAssignmentModelWithFormationID(multiplePageFormationID)
   301  	faEntity2 := fixFormationAssignmentEntityWithFormationID(multiplePageFormationID)
   302  
   303  	pageSize := 1
   304  	cursor := ""
   305  
   306  	suite := testdb.RepoListPageableTestSuite{
   307  		Name: "List Formation Assignments by Formation IDs",
   308  		SQLQueryDetails: []testdb.SQLQueryDetails{
   309  			{
   310  				Query: regexp.QuoteMeta(`(SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND formation_id = $2 ORDER BY formation_id ASC, id ASC LIMIT $3 OFFSET $4)
   311  												UNION
   312  												(SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $5 AND formation_id = $6 ORDER BY formation_id ASC, id ASC LIMIT $7 OFFSET $8)
   313  												UNION
   314  												(SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $9 AND formation_id = $10 ORDER BY formation_id ASC, id ASC LIMIT $11 OFFSET $12)`),
   315  				Args:     []driver.Value{TestTenantID, emptyPageFormationID, pageSize, 0, TestTenantID, onePageFormationID, pageSize, 0, TestTenantID, multiplePageFormationID, pageSize, 0},
   316  				IsSelect: true,
   317  				ValidRowsProvider: func() []*sqlmock.Rows {
   318  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).
   319  						AddRow(faEntity1.ID, faEntity1.FormationID, faEntity1.TenantID, faEntity1.Source, faEntity1.SourceType, faEntity1.Target, faEntity1.TargetType, faEntity1.State, faEntity1.Value).
   320  						AddRow(faEntity2.ID, faEntity2.FormationID, faEntity2.TenantID, faEntity2.Source, faEntity2.SourceType, faEntity2.Target, faEntity2.TargetType, faEntity2.State, faEntity2.Value),
   321  					}
   322  				},
   323  			},
   324  			{
   325  				Query:    regexp.QuoteMeta(`SELECT formation_id AS id, COUNT(*) AS total_count FROM public.formation_assignments WHERE tenant_id = $1 GROUP BY formation_id ORDER BY formation_id ASC`),
   326  				Args:     []driver.Value{TestTenantID},
   327  				IsSelect: true,
   328  				ValidRowsProvider: func() []*sqlmock.Rows {
   329  					return []*sqlmock.Rows{sqlmock.NewRows([]string{"id", "total_count"}).AddRow(emptyPageFormationID, 0).AddRow(onePageFormationID, 1).AddRow(multiplePageFormationID, 2)}
   330  				},
   331  			},
   332  		},
   333  		Pages: []testdb.PageDetails{
   334  			{
   335  				ExpectedModelEntities: nil,
   336  				ExpectedDBEntities:    nil,
   337  				ExpectedPage: &model.FormationAssignmentPage{
   338  					Data: nil,
   339  					PageInfo: &pagination.Page{
   340  						StartCursor: "",
   341  						EndCursor:   "",
   342  						HasNextPage: false,
   343  					},
   344  					TotalCount: 0,
   345  				},
   346  			},
   347  			{
   348  				ExpectedModelEntities: []interface{}{faModel1},
   349  				ExpectedDBEntities:    []interface{}{faEntity1},
   350  				ExpectedPage: &model.FormationAssignmentPage{
   351  					Data: []*model.FormationAssignment{faModel1},
   352  					PageInfo: &pagination.Page{
   353  						StartCursor: "",
   354  						EndCursor:   "",
   355  						HasNextPage: false,
   356  					},
   357  					TotalCount: 1,
   358  				},
   359  			},
   360  			{
   361  				ExpectedModelEntities: []interface{}{faModel2},
   362  				ExpectedDBEntities:    []interface{}{faEntity2},
   363  				ExpectedPage: &model.FormationAssignmentPage{
   364  					Data: []*model.FormationAssignment{faModel2},
   365  					PageInfo: &pagination.Page{
   366  						StartCursor: "",
   367  						EndCursor:   pagination.EncodeNextOffsetCursor(0, pageSize),
   368  						HasNextPage: true,
   369  					},
   370  					TotalCount: 2,
   371  				},
   372  			},
   373  		},
   374  		ConverterMockProvider: func() testdb.Mock {
   375  			return &automock.EntityConverter{}
   376  		},
   377  		RepoConstructorFunc:       formationassignment.NewRepository,
   378  		MethodArgs:                []interface{}{TestTenantID, []string{emptyPageFormationID, onePageFormationID, multiplePageFormationID}, pageSize, cursor},
   379  		MethodName:                "ListByFormationIDs",
   380  		DisableConverterErrorTest: true,
   381  	}
   382  
   383  	suite.Run(t)
   384  }
   385  
   386  func TestRepository_ListAllForObject(t *testing.T) {
   387  	suite := testdb.RepoListTestSuite{
   388  		Name:       "ListAllForObject Formations Assignments",
   389  		MethodName: "ListAllForObject",
   390  		SQLQueryDetails: []testdb.SQLQueryDetails{
   391  			{
   392  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE (tenant_id = $1 AND (formation_id = $2 AND (source = $3 OR target = $4)))`),
   393  				Args:     []driver.Value{TestTenantID, TestFormationID, TestSource, TestSource},
   394  				IsSelect: true,
   395  				ValidRowsProvider: func() []*sqlmock.Rows {
   396  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr)}
   397  				},
   398  				InvalidRowsProvider: func() []*sqlmock.Rows {
   399  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
   400  				},
   401  			},
   402  		},
   403  		ConverterMockProvider: func() testdb.Mock {
   404  			return &automock.EntityConverter{}
   405  		},
   406  		ExpectedModelEntities:     []interface{}{faModel},
   407  		ExpectedDBEntities:        []interface{}{faEntity},
   408  		RepoConstructorFunc:       formationassignment.NewRepository,
   409  		MethodArgs:                []interface{}{TestTenantID, TestFormationID, TestSource},
   410  		DisableConverterErrorTest: true,
   411  	}
   412  
   413  	suite.Run(t)
   414  }
   415  
   416  func TestRepository_DeleteAssignmentsForObjectID(t *testing.T) {
   417  	suite := testdb.RepoDeleteTestSuite{
   418  		Name:       "DeleteAssignmentsForObjectID Formations Assignments",
   419  		MethodName: "DeleteAssignmentsForObjectID",
   420  		SQLQueryDetails: []testdb.SQLQueryDetails{
   421  			{
   422  				Query:         regexp.QuoteMeta(`DELETE FROM public.formation_assignments WHERE (tenant_id = $1 AND (formation_id = $2 AND (source = $3 OR target = $4)))`),
   423  				Args:          []driver.Value{TestTenantID, TestFormationID, TestSource, TestSource},
   424  				ValidResult:   sqlmock.NewResult(-1, 1),
   425  				InvalidResult: sqlmock.NewResult(-1, 0),
   426  			},
   427  		},
   428  		ConverterMockProvider: func() testdb.Mock {
   429  			return &automock.EntityConverter{}
   430  		},
   431  		IsDeleteMany:        true,
   432  		RepoConstructorFunc: formationassignment.NewRepository,
   433  		MethodArgs:          []interface{}{TestTenantID, TestFormationID, TestSource},
   434  	}
   435  
   436  	suite.Run(t)
   437  }
   438  
   439  func TestRepository_ListAllForObjectIDs(t *testing.T) {
   440  	suite := testdb.RepoListTestSuite{
   441  		Name:       "ListAllForObjectIDs Formations Assignments",
   442  		MethodName: "ListAllForObjectIDs",
   443  		SQLQueryDetails: []testdb.SQLQueryDetails{
   444  			{
   445  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE (tenant_id = $1 AND (formation_id = $2 AND (source IN ($3, $4) OR target IN ($5, $6)))`),
   446  				Args:     []driver.Value{TestTenantID, TestFormationID, TestSource, TestTarget, TestSource, TestTarget},
   447  				IsSelect: true,
   448  				ValidRowsProvider: func() []*sqlmock.Rows {
   449  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr)}
   450  				},
   451  				InvalidRowsProvider: func() []*sqlmock.Rows {
   452  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
   453  				},
   454  			},
   455  		},
   456  		ConverterMockProvider: func() testdb.Mock {
   457  			return &automock.EntityConverter{}
   458  		},
   459  		ExpectedModelEntities:     []interface{}{faModel},
   460  		ExpectedDBEntities:        []interface{}{faEntity},
   461  		RepoConstructorFunc:       formationassignment.NewRepository,
   462  		MethodArgs:                []interface{}{TestTenantID, TestFormationID, []string{TestSource, TestTarget}},
   463  		DisableConverterErrorTest: true,
   464  	}
   465  
   466  	suite.Run(t)
   467  }
   468  
   469  func TestRepository_Update(t *testing.T) {
   470  	updateStmt := regexp.QuoteMeta(`UPDATE public.formation_assignments SET state = ?, value = ? WHERE id = ? AND tenant_id = ?`)
   471  	suite := testdb.RepoUpdateTestSuite{
   472  		Name: "Update Formation Assignment by ID",
   473  		SQLQueryDetails: []testdb.SQLQueryDetails{
   474  			{
   475  				Query:         updateStmt,
   476  				Args:          []driver.Value{TestStateInitial, TestConfigValueStr, TestID, TestTenantID},
   477  				ValidResult:   sqlmock.NewResult(-1, 1),
   478  				InvalidResult: sqlmock.NewResult(-1, 0),
   479  			},
   480  		},
   481  		ConverterMockProvider: func() testdb.Mock {
   482  			return &automock.EntityConverter{}
   483  		},
   484  		RepoConstructorFunc:       formationassignment.NewRepository,
   485  		ModelEntity:               faModel,
   486  		DBEntity:                  faEntity,
   487  		NilModelEntity:            nilFormationAssignmentModel,
   488  		DisableConverterErrorTest: true,
   489  	}
   490  
   491  	suite.Run(t)
   492  }
   493  
   494  func TestRepository_Delete(t *testing.T) {
   495  	suite := testdb.RepoDeleteTestSuite{
   496  		Name: "Delete Formation Assignment by id",
   497  		SQLQueryDetails: []testdb.SQLQueryDetails{
   498  			{
   499  				Query:         regexp.QuoteMeta(`DELETE FROM public.formation_assignments WHERE tenant_id = $1 AND id = $2`),
   500  				Args:          []driver.Value{TestTenantID, TestID},
   501  				ValidResult:   sqlmock.NewResult(-1, 1),
   502  				InvalidResult: sqlmock.NewResult(-1, 2),
   503  			},
   504  		},
   505  		RepoConstructorFunc: formationassignment.NewRepository,
   506  		ConverterMockProvider: func() testdb.Mock {
   507  			return &automock.EntityConverter{}
   508  		},
   509  		MethodName: "Delete",
   510  		MethodArgs: []interface{}{TestID, TestTenantID},
   511  	}
   512  
   513  	suite.Run(t)
   514  }
   515  
   516  func TestRepository_Exists(t *testing.T) {
   517  	suite := testdb.RepoExistTestSuite{
   518  		Name: "Exists Formation Assignment by ID",
   519  		SQLQueryDetails: []testdb.SQLQueryDetails{
   520  			{
   521  				Query:    regexp.QuoteMeta(`SELECT 1 FROM public.formation_assignments WHERE tenant_id = $1 AND id = $2`),
   522  				Args:     []driver.Value{TestTenantID, TestID},
   523  				IsSelect: true,
   524  				ValidRowsProvider: func() []*sqlmock.Rows {
   525  					return []*sqlmock.Rows{testdb.RowWhenObjectExist()}
   526  				},
   527  				InvalidRowsProvider: func() []*sqlmock.Rows {
   528  					return []*sqlmock.Rows{testdb.RowWhenObjectDoesNotExist()}
   529  				},
   530  			},
   531  		},
   532  		RepoConstructorFunc: formationassignment.NewRepository,
   533  		ConverterMockProvider: func() testdb.Mock {
   534  			return &automock.EntityConverter{}
   535  		},
   536  		TargetID:   TestID,
   537  		TenantID:   TestTenantID,
   538  		MethodName: "Exists",
   539  		MethodArgs: []interface{}{TestID, TestTenantID},
   540  	}
   541  
   542  	suite.Run(t)
   543  }
   544  
   545  func TestRepository_GetByTargetAndSource(t *testing.T) {
   546  	suite := testdb.RepoGetTestSuite{
   547  		Name:       "Get Formation Assignment by Target and Source",
   548  		MethodName: "GetByTargetAndSource",
   549  		SQLQueryDetails: []testdb.SQLQueryDetails{
   550  			{
   551  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND formation_id = $2 AND target = $3 AND source = $4`),
   552  				Args:     []driver.Value{TestTenantID, TestFormationID, TestTarget, TestSource},
   553  				IsSelect: true,
   554  				ValidRowsProvider: func() []*sqlmock.Rows {
   555  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr)}
   556  				},
   557  				InvalidRowsProvider: func() []*sqlmock.Rows {
   558  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
   559  				},
   560  			},
   561  		},
   562  		ConverterMockProvider: func() testdb.Mock {
   563  			return &automock.EntityConverter{}
   564  		},
   565  		RepoConstructorFunc:       formationassignment.NewRepository,
   566  		ExpectedModelEntity:       fixFormationAssignmentModel(TestConfigValueRawJSON),
   567  		ExpectedDBEntity:          fixFormationAssignmentEntity(TestConfigValueStr),
   568  		MethodArgs:                []interface{}{TestTarget, TestSource, TestTenantID, TestFormationID},
   569  		DisableConverterErrorTest: true,
   570  	}
   571  
   572  	suite.Run(t)
   573  }
   574  
   575  func TestRepository_ListForIDs(t *testing.T) {
   576  	suite := testdb.RepoListTestSuite{
   577  		Name:       "ListForIDs Formations Assignments",
   578  		MethodName: "ListForIDs",
   579  		SQLQueryDetails: []testdb.SQLQueryDetails{
   580  			{
   581  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND id IN ($2)`),
   582  				Args:     []driver.Value{TestTenantID, TestSource},
   583  				IsSelect: true,
   584  				ValidRowsProvider: func() []*sqlmock.Rows {
   585  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr)}
   586  				},
   587  				InvalidRowsProvider: func() []*sqlmock.Rows {
   588  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
   589  				},
   590  			},
   591  		},
   592  		ConverterMockProvider: func() testdb.Mock {
   593  			return &automock.EntityConverter{}
   594  		},
   595  		ExpectedModelEntities:     []interface{}{faModel},
   596  		ExpectedDBEntities:        []interface{}{faEntity},
   597  		RepoConstructorFunc:       formationassignment.NewRepository,
   598  		MethodArgs:                []interface{}{TestTenantID, []string{TestSource}},
   599  		DisableConverterErrorTest: true,
   600  	}
   601  
   602  	suite.Run(t)
   603  
   604  	// Additional test - empty slice because test suite returns empty result given valid query
   605  	t.Run("returns empty slice given no scenarios", func(t *testing.T) {
   606  		// GIVEN
   607  		ctx := context.TODO()
   608  		repository := formationassignment.NewRepository(nil)
   609  
   610  		// WHEN
   611  		actual, err := repository.ListForIDs(ctx, TestTenantID, []string{})
   612  
   613  		// THEN
   614  		assert.NoError(t, err)
   615  		assert.Nil(t, actual)
   616  	})
   617  }
   618  
   619  func TestRepository_ListByFormationIDsNoPaging(t *testing.T) {
   620  	testErr := errors.New("test error")
   621  
   622  	t.Run("success", func(t *testing.T) {
   623  		converterMock := &automock.EntityConverter{}
   624  		defer converterMock.AssertExpectations(t)
   625  		converterMock.On("FromEntity", faEntity).Return(faModel).Once()
   626  
   627  		sqlxDB, sqlMock := testdb.MockDatabase(t)
   628  		defer sqlMock.AssertExpectations(t)
   629  		sqlMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND formation_id IN ($2)`)).
   630  			WithArgs(TestTenantID, TestFormationID).WillReturnRows(sqlmock.NewRows(fixColumns).
   631  			AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr))
   632  
   633  		ctx := persistence.SaveToContext(context.TODO(), sqlxDB)
   634  		expected := [][]*model.FormationAssignment{{faModel}}
   635  		repository := formationassignment.NewRepository(converterMock)
   636  
   637  		// WHEN
   638  		actual, err := repository.ListByFormationIDsNoPaging(ctx, TestTenantID, []string{TestFormationID})
   639  
   640  		// THEN
   641  		assert.NoError(t, err)
   642  		assert.Equal(t, expected, actual)
   643  	})
   644  
   645  	t.Run("success - returns empty slice given no scenarios", func(t *testing.T) {
   646  		// GIVEN
   647  		ctx := context.TODO()
   648  		repository := formationassignment.NewRepository(nil)
   649  
   650  		// WHEN
   651  		actual, err := repository.ListByFormationIDsNoPaging(ctx, TestTenantID, []string{})
   652  
   653  		// THEN
   654  		assert.NoError(t, err)
   655  		assert.Nil(t, actual)
   656  	})
   657  
   658  	t.Run("returns error when listing fails", func(t *testing.T) {
   659  		converterMock := &automock.EntityConverter{}
   660  		defer converterMock.AssertExpectations(t)
   661  
   662  		sqlxDB, sqlMock := testdb.MockDatabase(t)
   663  		sqlMock.AssertExpectations(t)
   664  		sqlMock.ExpectQuery(regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND formation_id IN ($2)`)).
   665  			WithArgs(TestTenantID, TestFormationID).WillReturnError(testErr)
   666  
   667  		ctx := persistence.SaveToContext(context.TODO(), sqlxDB)
   668  		repository := formationassignment.NewRepository(converterMock)
   669  
   670  		// WHEN
   671  		actual, err := repository.ListByFormationIDsNoPaging(ctx, TestTenantID, []string{TestFormationID})
   672  
   673  		// THEN
   674  		assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   675  		assert.Nil(t, actual)
   676  	})
   677  }
   678  
   679  func TestRepository_GetAssignmentsForFormationWithStates(t *testing.T) {
   680  	suite := testdb.RepoListTestSuite{
   681  		Name: "ListAllForObjectIDs Formations Assignments",
   682  		SQLQueryDetails: []testdb.SQLQueryDetails{
   683  			{
   684  				Query:    regexp.QuoteMeta(`SELECT id, formation_id, tenant_id, source, source_type, target, target_type, state, value FROM public.formation_assignments WHERE tenant_id = $1 AND formation_id = $2 AND state IN ($3, $4)`),
   685  				Args:     []driver.Value{TestTenantID, TestFormationID, TestStateInitial, TestReadyState},
   686  				IsSelect: true,
   687  				ValidRowsProvider: func() []*sqlmock.Rows {
   688  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns).AddRow(TestID, TestFormationID, TestTenantID, TestSource, TestSourceType, TestTarget, TestTargetType, TestStateInitial, TestConfigValueStr)}
   689  				},
   690  				InvalidRowsProvider: func() []*sqlmock.Rows {
   691  					return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)}
   692  				},
   693  			},
   694  		},
   695  		ConverterMockProvider: func() testdb.Mock {
   696  			return &automock.EntityConverter{}
   697  		},
   698  		ExpectedModelEntities:     []interface{}{faModel},
   699  		ExpectedDBEntities:        []interface{}{faEntity},
   700  		RepoConstructorFunc:       formationassignment.NewRepository,
   701  		MethodArgs:                []interface{}{TestTenantID, TestFormationID, []string{TestStateInitial, TestReadyState}},
   702  		MethodName:                "GetAssignmentsForFormationWithStates",
   703  		DisableConverterErrorTest: true,
   704  	}
   705  
   706  	suite.Run(t)
   707  
   708  	// Additional test - empty slice because test suite returns empty result given valid query
   709  	t.Run("returns empty slice given no scenarios", func(t *testing.T) {
   710  		// GIVEN
   711  		ctx := context.TODO()
   712  		repository := formationassignment.NewRepository(nil)
   713  
   714  		// WHEN
   715  		actual, err := repository.GetAssignmentsForFormationWithStates(ctx, TestTenantID, TestFormationID, []string{})
   716  
   717  		// THEN
   718  		assert.NoError(t, err)
   719  		assert.Nil(t, actual)
   720  	})
   721  }