github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/label/repository_test.go (about) 1 package label_test 2 3 import ( 4 "context" 5 "database/sql" 6 "database/sql/driver" 7 "regexp" 8 "testing" 9 10 "github.com/pkg/errors" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/mock" 13 14 "github.com/DATA-DOG/go-sqlmock" 15 "github.com/kyma-incubator/compass/components/director/internal/domain/label" 16 "github.com/kyma-incubator/compass/components/director/internal/domain/label/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/persistence" 20 "github.com/stretchr/testify/require" 21 ) 22 23 func TestRepository_Create(t *testing.T) { 24 var nilLabelModel *model.Label 25 applabelModel := fixModelLabel(model.ApplicationLabelableObject) 26 appLabelEntity := fixEntityLabel(model.ApplicationLabelableObject) 27 runtimelabelModel := fixModelLabel(model.RuntimeLabelableObject) 28 runtimeLabelEntity := fixEntityLabel(model.RuntimeLabelableObject) 29 runtimeCtxlabelModel := fixModelLabel(model.RuntimeContextLabelableObject) 30 runtimeCtxLabelEntity := fixEntityLabel(model.RuntimeContextLabelableObject) 31 32 appLabelSuite := testdb.RepoCreateTestSuite{ 33 Name: "Create Application Label", 34 SQLQueryDetails: []testdb.SQLQueryDetails{ 35 { 36 Query: regexp.QuoteMeta("SELECT 1 FROM tenant_applications WHERE tenant_id = $1 AND id = $2 AND owner = $3"), 37 Args: []driver.Value{tenantID, refID, true}, 38 IsSelect: true, 39 ValidRowsProvider: func() []*sqlmock.Rows { 40 return []*sqlmock.Rows{testdb.RowWhenObjectExist()} 41 }, 42 InvalidRowsProvider: func() []*sqlmock.Rows { 43 return []*sqlmock.Rows{testdb.RowWhenObjectDoesNotExist()} 44 }, 45 }, 46 { 47 Query: regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )"), 48 Args: []driver.Value{appLabelEntity.ID, appLabelEntity.TenantID, appLabelEntity.AppID, appLabelEntity.RuntimeID, appLabelEntity.RuntimeContextID, appLabelEntity.AppTemplateID, appLabelEntity.Key, appLabelEntity.Value, appLabelEntity.Version}, 49 ValidResult: sqlmock.NewResult(-1, 1), 50 }, 51 }, 52 ConverterMockProvider: func() testdb.Mock { 53 return &automock.Converter{} 54 }, 55 RepoConstructorFunc: label.NewRepository, 56 ModelEntity: applabelModel, 57 DBEntity: appLabelEntity, 58 NilModelEntity: nilLabelModel, 59 TenantID: tenantID, 60 } 61 62 runtimeLabelSuite := testdb.RepoCreateTestSuite{ 63 Name: "Create Runtime Label", 64 SQLQueryDetails: []testdb.SQLQueryDetails{ 65 { 66 Query: regexp.QuoteMeta("SELECT 1 FROM tenant_runtimes WHERE tenant_id = $1 AND id = $2 AND owner = $3"), 67 Args: []driver.Value{tenantID, refID, true}, 68 IsSelect: true, 69 ValidRowsProvider: func() []*sqlmock.Rows { 70 return []*sqlmock.Rows{testdb.RowWhenObjectExist()} 71 }, 72 InvalidRowsProvider: func() []*sqlmock.Rows { 73 return []*sqlmock.Rows{testdb.RowWhenObjectDoesNotExist()} 74 }, 75 }, 76 { 77 Query: regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )"), 78 Args: []driver.Value{runtimeLabelEntity.ID, runtimeLabelEntity.TenantID, runtimeLabelEntity.AppID, runtimeLabelEntity.RuntimeID, runtimeLabelEntity.RuntimeContextID, runtimeLabelEntity.AppTemplateID, runtimeLabelEntity.Key, runtimeLabelEntity.Value, runtimeLabelEntity.Version}, 79 ValidResult: sqlmock.NewResult(-1, 1), 80 }, 81 }, 82 ConverterMockProvider: func() testdb.Mock { 83 return &automock.Converter{} 84 }, 85 RepoConstructorFunc: label.NewRepository, 86 ModelEntity: runtimelabelModel, 87 DBEntity: runtimeLabelEntity, 88 NilModelEntity: nilLabelModel, 89 TenantID: tenantID, 90 } 91 92 runtimeCtxLabelSuite := testdb.RepoCreateTestSuite{ 93 Name: "Create RuntimeCtx Label", 94 SQLQueryDetails: []testdb.SQLQueryDetails{ 95 { 96 Query: regexp.QuoteMeta("SELECT 1 FROM tenant_runtime_contexts WHERE tenant_id = $1 AND id = $2 AND owner = $3"), 97 Args: []driver.Value{tenantID, refID, true}, 98 IsSelect: true, 99 ValidRowsProvider: func() []*sqlmock.Rows { 100 return []*sqlmock.Rows{testdb.RowWhenObjectExist()} 101 }, 102 InvalidRowsProvider: func() []*sqlmock.Rows { 103 return []*sqlmock.Rows{testdb.RowWhenObjectDoesNotExist()} 104 }, 105 }, 106 { 107 Query: regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )"), 108 Args: []driver.Value{runtimeCtxLabelEntity.ID, runtimeCtxLabelEntity.TenantID, runtimeCtxLabelEntity.AppID, runtimeCtxLabelEntity.RuntimeID, runtimeCtxLabelEntity.RuntimeContextID, runtimeCtxLabelEntity.AppTemplateID, runtimeCtxLabelEntity.Key, runtimeCtxLabelEntity.Value, runtimeCtxLabelEntity.Version}, 109 ValidResult: sqlmock.NewResult(-1, 1), 110 }, 111 }, 112 ConverterMockProvider: func() testdb.Mock { 113 return &automock.Converter{} 114 }, 115 RepoConstructorFunc: label.NewRepository, 116 ModelEntity: runtimeCtxlabelModel, 117 DBEntity: runtimeCtxLabelEntity, 118 NilModelEntity: nilLabelModel, 119 TenantID: tenantID, 120 IsTopLevelEntity: true, 121 } 122 123 appLabelSuite.Run(t) 124 runtimeLabelSuite.Run(t) 125 runtimeCtxLabelSuite.Run(t) 126 127 // Additional tests - tenant labels are created globally as the tenant is embedded in the entity. 128 t.Run("Success create - Label for Tenant", func(t *testing.T) { 129 // GIVEN 130 labelModel := fixModelLabel(model.TenantLabelableObject) 131 labelEntity := fixEntityLabel(model.TenantLabelableObject) 132 133 mockConverter := &automock.Converter{} 134 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 135 defer mockConverter.AssertExpectations(t) 136 137 labelRepo := label.NewRepository(mockConverter) 138 139 db, dbMock := testdb.MockDatabase(t) 140 defer dbMock.AssertExpectations(t) 141 142 escapedInsertQuery := regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )") 143 dbMock.ExpectExec(escapedInsertQuery).WithArgs(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version).WillReturnResult(sqlmock.NewResult(1, 1)) 144 145 ctx := context.TODO() 146 ctx = persistence.SaveToContext(ctx, db) 147 // WHEN 148 err := labelRepo.Create(ctx, tenantID, labelModel) 149 // THEN 150 require.NoError(t, err) 151 }) 152 153 t.Run("Success create - Label for Application Template", func(t *testing.T) { 154 // GIVEN 155 appTemplateLabelModel := fixModelLabel(model.AppTemplateLabelableObject) 156 appTemplateLabelEntity := fixEntityLabel(model.AppTemplateLabelableObject) 157 158 mockConverter := &automock.Converter{} 159 mockConverter.On("ToEntity", appTemplateLabelModel).Return(appTemplateLabelEntity, nil).Once() 160 defer mockConverter.AssertExpectations(t) 161 162 labelRepo := label.NewRepository(mockConverter) 163 164 db, dbMock := testdb.MockDatabase(t) 165 defer dbMock.AssertExpectations(t) 166 167 escapedInsertQuery := regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )") 168 dbMock.ExpectExec(escapedInsertQuery).WithArgs(appTemplateLabelEntity.ID, appTemplateLabelEntity.TenantID, appTemplateLabelEntity.AppID, appTemplateLabelEntity.RuntimeID, appTemplateLabelEntity.RuntimeContextID, appTemplateLabelEntity.AppTemplateID, appTemplateLabelEntity.Key, appTemplateLabelEntity.Value, appTemplateLabelEntity.Version).WillReturnResult(sqlmock.NewResult(1, 1)) 169 170 ctx := context.TODO() 171 ctx = persistence.SaveToContext(ctx, db) 172 // WHEN 173 err := labelRepo.Create(ctx, tenantID, appTemplateLabelModel) 174 // THEN 175 require.NoError(t, err) 176 }) 177 } 178 179 func TestRepository_CreateGlobal(t *testing.T) { 180 var nilLabelModel *model.Label 181 appLabelModel := fixModelLabel(model.ApplicationLabelableObject) 182 appLabelEntity := fixEntityLabel(model.ApplicationLabelableObject) 183 184 appLabelSuite := testdb.RepoCreateTestSuite{ 185 Name: "Create Application Label with global creator", 186 SQLQueryDetails: []testdb.SQLQueryDetails{ 187 { 188 Query: regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )"), 189 Args: []driver.Value{appLabelEntity.ID, appLabelEntity.TenantID, appLabelEntity.AppID, appLabelEntity.RuntimeID, appLabelEntity.RuntimeContextID, appLabelEntity.AppTemplateID, appLabelEntity.Key, appLabelEntity.Value, appLabelEntity.Version}, 190 ValidResult: sqlmock.NewResult(-1, 1), 191 }, 192 }, 193 ConverterMockProvider: func() testdb.Mock { 194 return &automock.Converter{} 195 }, 196 RepoConstructorFunc: label.NewRepository, 197 ModelEntity: appLabelModel, 198 DBEntity: appLabelEntity, 199 NilModelEntity: nilLabelModel, 200 MethodName: "CreateGlobal", 201 IsGlobal: true, 202 } 203 204 appLabelSuite.Run(t) 205 } 206 207 func TestRepository_Upsert(t *testing.T) { 208 testErr := errors.New("Test error") 209 210 t.Run("Success update - Label for Runtime", func(t *testing.T) { 211 labelModel := fixModelLabel(model.RuntimeLabelableObject) 212 labelEntity := fixEntityLabel(model.TenantLabelableObject) 213 214 mockConverter := &automock.Converter{} 215 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 216 mockConverter.On("FromEntity", labelEntity).Return(labelModel, nil).Once() 217 defer mockConverter.AssertExpectations(t) 218 219 labelRepo := label.NewRepository(mockConverter) 220 221 db, dbMock := testdb.MockDatabase(t) 222 defer dbMock.AssertExpectations(t) 223 224 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND runtime_id = $2 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $3))`) 225 escapedUpdateQuery := regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ? AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = ? AND owner = true))`) 226 escapedExsistsQuery := regexp.QuoteMeta("SELECT 1 FROM public.labels WHERE id = $1 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $2 AND owner = true))") 227 228 mockedRows := sqlmock.NewRows(fixColumns).AddRow(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version) 229 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID, tenantID).WillReturnRows(mockedRows) 230 dbMock.ExpectQuery(escapedExsistsQuery).WithArgs(labelID, tenantID).WillReturnRows(testdb.RowWhenObjectExist()) 231 dbMock.ExpectExec(escapedUpdateQuery).WithArgs(labelEntity.Value, labelEntity.ID, tenantID).WillReturnResult(sqlmock.NewResult(-1, 1)) 232 233 ctx := context.TODO() 234 ctx = persistence.SaveToContext(ctx, db) 235 // WHEN 236 err := labelRepo.Upsert(ctx, tenantID, labelModel) 237 // THEN 238 require.NoError(t, err) 239 }) 240 241 t.Run("Success update - Label for Runtime Context", func(t *testing.T) { 242 // GIVEN 243 labelModel := fixModelLabel(model.RuntimeContextLabelableObject) 244 labelEntity := fixEntityLabel(model.RuntimeContextLabelableObject) 245 246 mockConverter := &automock.Converter{} 247 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 248 mockConverter.On("FromEntity", labelEntity).Return(labelModel, nil).Once() 249 defer mockConverter.AssertExpectations(t) 250 251 labelRepo := label.NewRepository(mockConverter) 252 253 db, dbMock := testdb.MockDatabase(t) 254 defer dbMock.AssertExpectations(t) 255 256 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND runtime_context_id = $2 AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $3))`) 257 escapedUpdateQuery := regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ? AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = ? AND owner = true))`) 258 escapedExsistsQuery := regexp.QuoteMeta("SELECT 1 FROM public.labels WHERE id = $1 AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $2 AND owner = true))") 259 260 mockedRows := sqlmock.NewRows(fixColumns).AddRow(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version) 261 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID, tenantID).WillReturnRows(mockedRows) 262 dbMock.ExpectQuery(escapedExsistsQuery).WithArgs(labelID, tenantID).WillReturnRows(testdb.RowWhenObjectExist()) 263 dbMock.ExpectExec(escapedUpdateQuery).WithArgs(labelEntity.Value, labelEntity.ID, tenantID).WillReturnResult(sqlmock.NewResult(-1, 1)) 264 265 ctx := context.TODO() 266 ctx = persistence.SaveToContext(ctx, db) 267 // WHEN 268 err := labelRepo.Upsert(ctx, tenantID, labelModel) 269 // THEN 270 require.NoError(t, err) 271 }) 272 273 t.Run("Success update - Label for Application", func(t *testing.T) { 274 labelModel := fixModelLabel(model.ApplicationLabelableObject) 275 labelEntity := fixEntityLabel(model.ApplicationLabelableObject) 276 277 mockConverter := &automock.Converter{} 278 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 279 mockConverter.On("FromEntity", labelEntity).Return(labelModel, nil).Once() 280 defer mockConverter.AssertExpectations(t) 281 282 labelRepo := label.NewRepository(mockConverter) 283 284 db, dbMock := testdb.MockDatabase(t) 285 defer dbMock.AssertExpectations(t) 286 287 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_id = $2 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $3))`) 288 escapedUpdateQuery := regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ? AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = ? AND owner = true))`) 289 escapedExsistsQuery := regexp.QuoteMeta("SELECT 1 FROM public.labels WHERE id = $1 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $2 AND owner = true))") 290 291 mockedRows := sqlmock.NewRows(fixColumns).AddRow(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version) 292 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID, tenantID).WillReturnRows(mockedRows) 293 dbMock.ExpectQuery(escapedExsistsQuery).WithArgs(labelID, tenantID).WillReturnRows(testdb.RowWhenObjectExist()) 294 dbMock.ExpectExec(escapedUpdateQuery).WithArgs(labelEntity.Value, labelEntity.ID, tenantID).WillReturnResult(sqlmock.NewResult(-1, 1)) 295 296 ctx := context.TODO() 297 ctx = persistence.SaveToContext(ctx, db) 298 // WHEN 299 err := labelRepo.Upsert(ctx, tenantID, labelModel) 300 // THEN 301 require.NoError(t, err) 302 }) 303 304 t.Run("Success update - Label for Tenant", func(t *testing.T) { 305 labelModel := fixModelLabel(model.TenantLabelableObject) 306 labelEntity := fixEntityLabel(model.TenantLabelableObject) 307 308 mockConverter := &automock.Converter{} 309 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 310 mockConverter.On("FromEntity", labelEntity).Return(labelModel, nil).Once() 311 defer mockConverter.AssertExpectations(t) 312 313 labelRepo := label.NewRepository(mockConverter) 314 315 db, dbMock := testdb.MockDatabase(t) 316 defer dbMock.AssertExpectations(t) 317 318 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE tenant_id = $1 AND key = $2`) 319 escapedUpdateQuery := regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ? AND tenant_id = ?`) 320 321 mockedRows := sqlmock.NewRows(fixColumns).AddRow(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version) 322 dbMock.ExpectQuery(escapedGetQuery).WithArgs(tenantID, key).WillReturnRows(mockedRows) 323 dbMock.ExpectExec(escapedUpdateQuery).WithArgs(labelEntity.Value, labelEntity.ID, labelEntity.TenantID).WillReturnResult(sqlmock.NewResult(-1, 1)) 324 325 ctx := context.TODO() 326 ctx = persistence.SaveToContext(ctx, db) 327 // WHEN 328 err := labelRepo.Upsert(ctx, tenantID, labelModel) 329 // THEN 330 require.NoError(t, err) 331 }) 332 333 t.Run("Success update - Label for Application Template", func(t *testing.T) { 334 appTemplateLabelModel := fixModelLabel(model.AppTemplateLabelableObject) 335 appTemplateLabelEntity := fixEntityLabel(model.AppTemplateLabelableObject) 336 337 mockConverter := &automock.Converter{} 338 mockConverter.On("ToEntity", appTemplateLabelModel).Return(appTemplateLabelEntity, nil).Once() 339 mockConverter.On("FromEntity", appTemplateLabelEntity).Return(appTemplateLabelModel, nil).Once() 340 defer mockConverter.AssertExpectations(t) 341 342 labelRepo := label.NewRepository(mockConverter) 343 344 db, dbMock := testdb.MockDatabase(t) 345 defer dbMock.AssertExpectations(t) 346 347 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_template_id = $2`) 348 escapedUpdateQuery := regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ?`) 349 350 mockedRows := sqlmock.NewRows(fixColumns).AddRow(appTemplateLabelEntity.ID, appTemplateLabelEntity.TenantID, appTemplateLabelEntity.AppID, appTemplateLabelEntity.RuntimeID, appTemplateLabelEntity.RuntimeContextID, appTemplateLabelEntity.AppTemplateID, appTemplateLabelEntity.Key, appTemplateLabelEntity.Value, appTemplateLabelEntity.Version) 351 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID).WillReturnRows(mockedRows) 352 dbMock.ExpectExec(escapedUpdateQuery).WithArgs(appTemplateLabelEntity.Value, appTemplateLabelEntity.ID).WillReturnResult(sqlmock.NewResult(-1, 1)) 353 354 ctx := context.TODO() 355 ctx = persistence.SaveToContext(ctx, db) 356 // WHEN 357 err := labelRepo.Upsert(ctx, tenantID, appTemplateLabelModel) 358 // THEN 359 require.NoError(t, err) 360 }) 361 362 t.Run("Success create - Label for Runtime", func(t *testing.T) { 363 labelModel := fixModelLabel(model.RuntimeLabelableObject) 364 labelEntity := fixEntityLabel(model.RuntimeLabelableObject) 365 366 mockConverter := &automock.Converter{} 367 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 368 defer mockConverter.AssertExpectations(t) 369 370 labelRepo := label.NewRepository(mockConverter) 371 372 db, dbMock := testdb.MockDatabase(t) 373 defer dbMock.AssertExpectations(t) 374 375 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND runtime_id = $2 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $3))`) 376 escapedCheckParentAccessQuery := regexp.QuoteMeta("SELECT 1 FROM tenant_runtimes WHERE tenant_id = $1 AND id = $2 AND owner = $3") 377 escapedInsertQuery := regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )") 378 379 mockedRows := sqlmock.NewRows(fixColumns) 380 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID, tenantID).WillReturnRows(mockedRows) 381 dbMock.ExpectQuery(escapedCheckParentAccessQuery).WithArgs(tenantID, refID, true).WillReturnRows(testdb.RowWhenObjectExist()) 382 dbMock.ExpectExec(escapedInsertQuery).WithArgs(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version).WillReturnResult(sqlmock.NewResult(1, 1)) 383 384 ctx := context.TODO() 385 ctx = persistence.SaveToContext(ctx, db) 386 // WHEN 387 err := labelRepo.Upsert(ctx, tenantID, labelModel) 388 // THEN 389 require.NoError(t, err) 390 }) 391 392 t.Run("Success create - Label for Runtime Context", func(t *testing.T) { 393 labelModel := fixModelLabel(model.RuntimeContextLabelableObject) 394 labelEntity := fixEntityLabel(model.RuntimeContextLabelableObject) 395 396 mockConverter := &automock.Converter{} 397 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 398 defer mockConverter.AssertExpectations(t) 399 400 labelRepo := label.NewRepository(mockConverter) 401 402 db, dbMock := testdb.MockDatabase(t) 403 defer dbMock.AssertExpectations(t) 404 405 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND runtime_context_id = $2 AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $3))`) 406 escapedCheckParentAccessQuery := regexp.QuoteMeta("SELECT 1 FROM tenant_runtime_contexts WHERE tenant_id = $1 AND id = $2 AND owner = $3") 407 escapedInsertQuery := regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )") 408 409 mockedRows := sqlmock.NewRows(fixColumns) 410 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID, tenantID).WillReturnRows(mockedRows) 411 dbMock.ExpectQuery(escapedCheckParentAccessQuery).WithArgs(tenantID, refID, true).WillReturnRows(testdb.RowWhenObjectExist()) 412 dbMock.ExpectExec(escapedInsertQuery).WithArgs(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version).WillReturnResult(sqlmock.NewResult(1, 1)) 413 414 ctx := context.TODO() 415 ctx = persistence.SaveToContext(ctx, db) 416 // WHEN 417 err := labelRepo.Upsert(ctx, tenantID, labelModel) 418 // THEN 419 require.NoError(t, err) 420 }) 421 422 t.Run("Success create - Label for Application", func(t *testing.T) { 423 labelModel := fixModelLabel(model.ApplicationLabelableObject) 424 labelEntity := fixEntityLabel(model.ApplicationLabelableObject) 425 426 mockConverter := &automock.Converter{} 427 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 428 defer mockConverter.AssertExpectations(t) 429 430 labelRepo := label.NewRepository(mockConverter) 431 432 db, dbMock := testdb.MockDatabase(t) 433 defer dbMock.AssertExpectations(t) 434 435 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_id = $2 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $3))`) 436 escapedCheckParentAccessQuery := regexp.QuoteMeta("SELECT 1 FROM tenant_applications WHERE tenant_id = $1 AND id = $2 AND owner = $3") 437 escapedInsertQuery := regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )") 438 439 mockedRows := sqlmock.NewRows(fixColumns) 440 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID, tenantID).WillReturnRows(mockedRows) 441 dbMock.ExpectQuery(escapedCheckParentAccessQuery).WithArgs(tenantID, refID, true).WillReturnRows(testdb.RowWhenObjectExist()) 442 dbMock.ExpectExec(escapedInsertQuery).WithArgs(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version).WillReturnResult(sqlmock.NewResult(1, 1)) 443 444 ctx := context.TODO() 445 ctx = persistence.SaveToContext(ctx, db) 446 // WHEN 447 err := labelRepo.Upsert(ctx, tenantID, labelModel) 448 // THEN 449 require.NoError(t, err) 450 }) 451 452 t.Run("Success create - Label for Tenant", func(t *testing.T) { 453 labelModel := fixModelLabel(model.TenantLabelableObject) 454 labelEntity := fixEntityLabel(model.TenantLabelableObject) 455 456 mockConverter := &automock.Converter{} 457 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 458 defer mockConverter.AssertExpectations(t) 459 460 labelRepo := label.NewRepository(mockConverter) 461 462 db, dbMock := testdb.MockDatabase(t) 463 defer dbMock.AssertExpectations(t) 464 465 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE tenant_id = $1 AND key = $2`) 466 escapedInsertQuery := regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )") 467 468 mockedRows := sqlmock.NewRows(fixColumns) 469 dbMock.ExpectQuery(escapedGetQuery).WithArgs(tenantID, key).WillReturnRows(mockedRows) 470 dbMock.ExpectExec(escapedInsertQuery).WithArgs(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version).WillReturnResult(sqlmock.NewResult(1, 1)) 471 472 ctx := context.TODO() 473 ctx = persistence.SaveToContext(ctx, db) 474 // WHEN 475 err := labelRepo.Upsert(ctx, tenantID, labelModel) 476 // THEN 477 require.NoError(t, err) 478 }) 479 480 t.Run("Success create - Label for Tenant", func(t *testing.T) { 481 labelModel := fixModelLabel(model.AppTemplateLabelableObject) 482 labelEntity := fixEntityLabel(model.AppTemplateLabelableObject) 483 484 mockConverter := &automock.Converter{} 485 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 486 defer mockConverter.AssertExpectations(t) 487 488 labelRepo := label.NewRepository(mockConverter) 489 490 db, dbMock := testdb.MockDatabase(t) 491 defer dbMock.AssertExpectations(t) 492 493 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_template_id = $2`) 494 escapedInsertQuery := regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )") 495 496 mockedRows := sqlmock.NewRows(fixColumns) 497 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID).WillReturnRows(mockedRows) 498 dbMock.ExpectExec(escapedInsertQuery).WithArgs(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version).WillReturnResult(sqlmock.NewResult(1, 1)) 499 500 ctx := context.TODO() 501 ctx = persistence.SaveToContext(ctx, db) 502 // WHEN 503 err := labelRepo.Upsert(ctx, tenantID, labelModel) 504 // THEN 505 require.NoError(t, err) 506 }) 507 508 t.Run("Error - GetByKey", func(t *testing.T) { 509 labelModel := fixModelLabel(model.RuntimeLabelableObject) 510 511 labelRepo := label.NewRepository(&automock.Converter{}) 512 513 db, dbMock := testdb.MockDatabase(t) 514 defer dbMock.AssertExpectations(t) 515 516 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND runtime_id = $2 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $3))`) 517 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID, tenantID).WillReturnError(testErr) 518 519 ctx := context.TODO() 520 ctx = persistence.SaveToContext(ctx, db) 521 // WHEN 522 err := labelRepo.Upsert(ctx, tenantID, labelModel) 523 // THEN 524 require.Error(t, err) 525 assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 526 }) 527 528 t.Run("Error - Create", func(t *testing.T) { 529 labelModel := fixModelLabel(model.RuntimeLabelableObject) 530 labelEntity := fixEntityLabel(model.RuntimeLabelableObject) 531 532 mockConverter := &automock.Converter{} 533 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 534 defer mockConverter.AssertExpectations(t) 535 536 labelRepo := label.NewRepository(mockConverter) 537 538 db, dbMock := testdb.MockDatabase(t) 539 defer dbMock.AssertExpectations(t) 540 541 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND runtime_id = $2 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $3))`) 542 escapedCheckParentAccessQuery := regexp.QuoteMeta("SELECT 1 FROM tenant_runtimes WHERE tenant_id = $1 AND id = $2 AND owner = $3") 543 escapedInsertQuery := regexp.QuoteMeta("INSERT INTO public.labels ( id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )") 544 545 mockedRows := sqlmock.NewRows(fixColumns) 546 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID, tenantID).WillReturnRows(mockedRows) 547 dbMock.ExpectQuery(escapedCheckParentAccessQuery).WithArgs(tenantID, refID, true).WillReturnRows(testdb.RowWhenObjectExist()) 548 dbMock.ExpectExec(escapedInsertQuery).WithArgs(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version).WillReturnError(testErr) 549 550 ctx := context.TODO() 551 ctx = persistence.SaveToContext(ctx, db) 552 // WHEN 553 err := labelRepo.Upsert(ctx, tenantID, labelModel) 554 // THEN 555 require.Error(t, err) 556 assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 557 }) 558 } 559 560 func TestRepository_UpsertGlobal(t *testing.T) { 561 testErr := errors.New("Test error") 562 563 t.Run("Success update of label for Application", func(t *testing.T) { 564 labelModel := fixModelLabel(model.ApplicationLabelableObject) 565 labelEntity := fixEntityLabel(model.ApplicationLabelableObject) 566 567 mockConverter := &automock.Converter{} 568 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 569 mockConverter.On("FromEntity", labelEntity).Return(labelModel, nil).Once() 570 defer mockConverter.AssertExpectations(t) 571 572 labelRepo := label.NewRepository(mockConverter) 573 574 db, dbMock := testdb.MockDatabase(t) 575 defer dbMock.AssertExpectations(t) 576 577 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_id = $2`) 578 escapedUpdateQuery := regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ?`) 579 580 mockedRows := sqlmock.NewRows(fixColumns).AddRow(labelEntity.ID, labelEntity.TenantID, labelEntity.AppID, labelEntity.RuntimeID, labelEntity.RuntimeContextID, labelEntity.AppTemplateID, labelEntity.Key, labelEntity.Value, labelEntity.Version) 581 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID).WillReturnRows(mockedRows) 582 dbMock.ExpectExec(escapedUpdateQuery).WithArgs(labelEntity.Value, labelEntity.ID).WillReturnResult(sqlmock.NewResult(-1, 1)) 583 584 ctx := context.TODO() 585 ctx = persistence.SaveToContext(ctx, db) 586 // WHEN 587 err := labelRepo.UpsertGlobal(ctx, labelModel) 588 // THEN 589 require.NoError(t, err) 590 }) 591 592 t.Run("Error in GetByKeyGlobal", func(t *testing.T) { 593 labelModel := fixModelLabel(model.ApplicationLabelableObject) 594 595 labelRepo := label.NewRepository(&automock.Converter{}) 596 597 db, dbMock := testdb.MockDatabase(t) 598 defer dbMock.AssertExpectations(t) 599 600 escapedGetQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_id = $2`) 601 dbMock.ExpectQuery(escapedGetQuery).WithArgs(key, refID).WillReturnError(testErr) 602 603 ctx := context.TODO() 604 ctx = persistence.SaveToContext(ctx, db) 605 // WHEN 606 err := labelRepo.UpsertGlobal(ctx, labelModel) 607 // THEN 608 require.Error(t, err) 609 assert.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 610 }) 611 612 t.Run("Error when empty label is passed", func(t *testing.T) { 613 var labelModel *model.Label 614 labelRepo := label.NewRepository(&automock.Converter{}) 615 616 db, dbMock := testdb.MockDatabase(t) 617 defer dbMock.AssertExpectations(t) 618 619 ctx := context.TODO() 620 ctx = persistence.SaveToContext(ctx, db) 621 // WHEN 622 err := labelRepo.UpsertGlobal(ctx, labelModel) 623 // THEN 624 require.Error(t, err) 625 assert.EqualError(t, err, "Internal Server Error: item can not be empty") 626 }) 627 } 628 629 func TestRepository_UpdateWithVersion(t *testing.T) { 630 version := 42 631 632 var nilLabelModel *model.Label 633 applabelModel := fixModelLabel(model.ApplicationLabelableObject) 634 appLabelEntity := fixEntityLabel(model.ApplicationLabelableObject) 635 runtimelabelModel := fixModelLabel(model.RuntimeLabelableObject) 636 runtimeLabelEntity := fixEntityLabel(model.RuntimeLabelableObject) 637 runtimeCtxlabelModel := fixModelLabel(model.RuntimeContextLabelableObject) 638 runtimeCtxLabelEntity := fixEntityLabel(model.RuntimeContextLabelableObject) 639 640 appLabelSuite := testdb.RepoUpdateTestSuite{ 641 Name: "Update Application Label", 642 SQLQueryDetails: []testdb.SQLQueryDetails{ 643 { 644 Query: regexp.QuoteMeta("SELECT 1 FROM public.labels WHERE id = $1 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $2 AND owner = true))"), 645 Args: []driver.Value{labelID, tenantID}, 646 IsSelect: true, 647 ValidRowsProvider: func() []*sqlmock.Rows { 648 return []*sqlmock.Rows{testdb.RowWhenObjectExist()} 649 }, 650 InvalidRowsProvider: func() []*sqlmock.Rows { 651 return []*sqlmock.Rows{testdb.RowWhenObjectDoesNotExist()} 652 }, 653 }, 654 { 655 Query: regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ? AND version = ? AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = ? AND owner = true))`), 656 Args: []driver.Value{appLabelEntity.Value, appLabelEntity.ID, version, tenantID}, 657 ValidResult: sqlmock.NewResult(-1, 1), 658 InvalidResult: sqlmock.NewResult(-1, 0), 659 }, 660 }, 661 ConverterMockProvider: func() testdb.Mock { 662 return &automock.Converter{} 663 }, 664 RepoConstructorFunc: label.NewRepository, 665 ModelEntity: applabelModel, 666 DBEntity: appLabelEntity, 667 NilModelEntity: nilLabelModel, 668 TenantID: tenantID, 669 UpdateMethodName: "UpdateWithVersion", 670 } 671 672 runtimeLabelSuite := testdb.RepoUpdateTestSuite{ 673 Name: "Update Runtime Label", 674 SQLQueryDetails: []testdb.SQLQueryDetails{ 675 { 676 Query: regexp.QuoteMeta("SELECT 1 FROM public.labels WHERE id = $1 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $2 AND owner = true))"), 677 Args: []driver.Value{labelID, tenantID}, 678 IsSelect: true, 679 ValidRowsProvider: func() []*sqlmock.Rows { 680 return []*sqlmock.Rows{testdb.RowWhenObjectExist()} 681 }, 682 InvalidRowsProvider: func() []*sqlmock.Rows { 683 return []*sqlmock.Rows{testdb.RowWhenObjectDoesNotExist()} 684 }, 685 }, 686 { 687 Query: regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ? AND version = ? AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = ? AND owner = true))`), 688 Args: []driver.Value{runtimeLabelEntity.Value, runtimeLabelEntity.ID, version, tenantID}, 689 ValidResult: sqlmock.NewResult(-1, 1), 690 InvalidResult: sqlmock.NewResult(-1, 0), 691 }, 692 }, 693 ConverterMockProvider: func() testdb.Mock { 694 return &automock.Converter{} 695 }, 696 RepoConstructorFunc: label.NewRepository, 697 ModelEntity: runtimelabelModel, 698 DBEntity: runtimeLabelEntity, 699 NilModelEntity: nilLabelModel, 700 TenantID: tenantID, 701 UpdateMethodName: "UpdateWithVersion", 702 } 703 704 runtimeCtxLabelSuite := testdb.RepoUpdateTestSuite{ 705 Name: "Update RuntimeCtx Label", 706 SQLQueryDetails: []testdb.SQLQueryDetails{ 707 { 708 Query: regexp.QuoteMeta("SELECT 1 FROM public.labels WHERE id = $1 AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $2 AND owner = true))"), 709 Args: []driver.Value{labelID, tenantID}, 710 IsSelect: true, 711 ValidRowsProvider: func() []*sqlmock.Rows { 712 return []*sqlmock.Rows{testdb.RowWhenObjectExist()} 713 }, 714 InvalidRowsProvider: func() []*sqlmock.Rows { 715 return []*sqlmock.Rows{testdb.RowWhenObjectDoesNotExist()} 716 }, 717 }, 718 { 719 Query: regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ? AND version = ? AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = ? AND owner = true))`), 720 Args: []driver.Value{runtimeCtxLabelEntity.Value, runtimeCtxLabelEntity.ID, version, tenantID}, 721 ValidResult: sqlmock.NewResult(-1, 1), 722 InvalidResult: sqlmock.NewResult(-1, 0), 723 }, 724 }, 725 ConverterMockProvider: func() testdb.Mock { 726 return &automock.Converter{} 727 }, 728 RepoConstructorFunc: label.NewRepository, 729 ModelEntity: runtimeCtxlabelModel, 730 DBEntity: runtimeCtxLabelEntity, 731 NilModelEntity: nilLabelModel, 732 TenantID: tenantID, 733 UpdateMethodName: "UpdateWithVersion", 734 } 735 736 appLabelSuite.Run(t) 737 runtimeLabelSuite.Run(t) 738 runtimeCtxLabelSuite.Run(t) 739 740 // Additional tests - tenant labels are updated globally as the tenant is embedded in the entity. 741 t.Run("Success update - Label for Tenant", func(t *testing.T) { 742 // GIVEN 743 labelModel := fixModelLabel(model.TenantLabelableObject) 744 labelEntity := fixEntityLabel(model.TenantLabelableObject) 745 746 mockConverter := &automock.Converter{} 747 mockConverter.On("ToEntity", labelModel).Return(labelEntity, nil).Once() 748 defer mockConverter.AssertExpectations(t) 749 750 labelRepo := label.NewRepository(mockConverter) 751 752 db, dbMock := testdb.MockDatabase(t) 753 defer dbMock.AssertExpectations(t) 754 755 escapedUpdateQuery := regexp.QuoteMeta(`UPDATE public.labels SET value = ?, version = version+1 WHERE id = ? AND version = ? AND tenant_id = ?`) 756 dbMock.ExpectExec(escapedUpdateQuery).WithArgs(labelEntity.Value, labelEntity.ID, version, labelEntity.TenantID).WillReturnResult(sqlmock.NewResult(1, 1)) 757 758 ctx := context.TODO() 759 ctx = persistence.SaveToContext(ctx, db) 760 // WHEN 761 err := labelRepo.UpdateWithVersion(ctx, tenantID, labelModel) 762 // THEN 763 require.NoError(t, err) 764 }) 765 } 766 767 func TestRepository_GetByKey(t *testing.T) { 768 applabelModel := fixModelLabel(model.ApplicationLabelableObject) 769 appLabelEntity := fixEntityLabel(model.ApplicationLabelableObject) 770 runtimelabelModel := fixModelLabel(model.RuntimeLabelableObject) 771 runtimeLabelEntity := fixEntityLabel(model.RuntimeLabelableObject) 772 runtimeCtxlabelModel := fixModelLabel(model.RuntimeContextLabelableObject) 773 runtimeCtxLabelEntity := fixEntityLabel(model.RuntimeContextLabelableObject) 774 775 appLabelSuite := testdb.RepoGetTestSuite{ 776 Name: "Get Application Label", 777 SQLQueryDetails: []testdb.SQLQueryDetails{ 778 { 779 Query: regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_id = $2 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $3))`), 780 Args: []driver.Value{key, refID, tenantID}, 781 IsSelect: true, 782 ValidRowsProvider: func() []*sqlmock.Rows { 783 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns). 784 AddRow(appLabelEntity.ID, appLabelEntity.TenantID, appLabelEntity.AppID, appLabelEntity.RuntimeID, appLabelEntity.RuntimeContextID, appLabelEntity.AppTemplateID, appLabelEntity.Key, appLabelEntity.Value, appLabelEntity.Version)} 785 }, 786 InvalidRowsProvider: func() []*sqlmock.Rows { 787 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)} 788 }, 789 }, 790 }, 791 ConverterMockProvider: func() testdb.Mock { 792 return &automock.Converter{} 793 }, 794 RepoConstructorFunc: label.NewRepository, 795 ExpectedModelEntity: applabelModel, 796 ExpectedDBEntity: appLabelEntity, 797 MethodArgs: []interface{}{tenantID, model.ApplicationLabelableObject, refID, key}, 798 MethodName: "GetByKey", 799 } 800 801 rtLabelSuite := testdb.RepoGetTestSuite{ 802 Name: "Get Runtime Label", 803 SQLQueryDetails: []testdb.SQLQueryDetails{ 804 { 805 Query: regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND runtime_id = $2 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $3))`), 806 Args: []driver.Value{key, refID, tenantID}, 807 IsSelect: true, 808 ValidRowsProvider: func() []*sqlmock.Rows { 809 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns). 810 AddRow(runtimeLabelEntity.ID, runtimeLabelEntity.TenantID, runtimeLabelEntity.AppID, runtimeLabelEntity.RuntimeID, runtimeLabelEntity.RuntimeContextID, runtimeCtxLabelEntity.AppTemplateID, runtimeLabelEntity.Key, runtimeLabelEntity.Value, runtimeLabelEntity.Version)} 811 }, 812 InvalidRowsProvider: func() []*sqlmock.Rows { 813 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)} 814 }, 815 }, 816 }, 817 ConverterMockProvider: func() testdb.Mock { 818 return &automock.Converter{} 819 }, 820 RepoConstructorFunc: label.NewRepository, 821 ExpectedModelEntity: runtimelabelModel, 822 ExpectedDBEntity: runtimeLabelEntity, 823 MethodArgs: []interface{}{tenantID, model.RuntimeLabelableObject, refID, key}, 824 MethodName: "GetByKey", 825 } 826 827 rtCtxLabelSuite := testdb.RepoGetTestSuite{ 828 Name: "Get Runtime Context Label", 829 SQLQueryDetails: []testdb.SQLQueryDetails{ 830 { 831 Query: regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND runtime_context_id = $2 AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $3))`), 832 Args: []driver.Value{key, refID, tenantID}, 833 IsSelect: true, 834 ValidRowsProvider: func() []*sqlmock.Rows { 835 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns). 836 AddRow(runtimeCtxLabelEntity.ID, runtimeCtxLabelEntity.TenantID, runtimeCtxLabelEntity.AppID, runtimeCtxLabelEntity.RuntimeID, runtimeCtxLabelEntity.RuntimeContextID, runtimeCtxLabelEntity.AppTemplateID, runtimeCtxLabelEntity.Key, runtimeCtxLabelEntity.Value, runtimeCtxLabelEntity.Version)} 837 }, 838 InvalidRowsProvider: func() []*sqlmock.Rows { 839 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)} 840 }, 841 }, 842 }, 843 ConverterMockProvider: func() testdb.Mock { 844 return &automock.Converter{} 845 }, 846 RepoConstructorFunc: label.NewRepository, 847 ExpectedModelEntity: runtimeCtxlabelModel, 848 ExpectedDBEntity: runtimeCtxLabelEntity, 849 MethodArgs: []interface{}{tenantID, model.RuntimeContextLabelableObject, refID, key}, 850 MethodName: "GetByKey", 851 } 852 853 appLabelSuite.Run(t) 854 rtLabelSuite.Run(t) 855 rtCtxLabelSuite.Run(t) 856 857 t.Run("Success - Label for Tenant", func(t *testing.T) { 858 tenantLabelModel := fixModelLabel(model.TenantLabelableObject) 859 tenantLabelEntity := fixEntityLabel(model.TenantLabelableObject) 860 861 mockConverter := &automock.Converter{} 862 defer mockConverter.AssertExpectations(t) 863 mockConverter.On("FromEntity", tenantLabelEntity).Return(tenantLabelModel, nil).Once() 864 865 labelRepo := label.NewRepository(mockConverter) 866 867 db, dbMock := testdb.MockDatabase(t) 868 defer dbMock.AssertExpectations(t) 869 870 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE tenant_id = $1 AND key = $2`) 871 mockedRows := sqlmock.NewRows(fixColumns).AddRow(tenantLabelEntity.ID, tenantLabelEntity.TenantID, tenantLabelEntity.AppID, tenantLabelEntity.RuntimeID, tenantLabelEntity.RuntimeContextID, tenantLabelEntity.AppTemplateID, tenantLabelEntity.Key, tenantLabelEntity.Value, tenantLabelEntity.Version) 872 dbMock.ExpectQuery(escapedQuery).WithArgs(tenantID, key).WillReturnRows(mockedRows) 873 874 ctx := context.TODO() 875 ctx = persistence.SaveToContext(ctx, db) 876 // WHEN 877 actual, err := labelRepo.GetByKey(ctx, tenantID, model.TenantLabelableObject, tenantID, key) 878 // THEN 879 require.NoError(t, err) 880 require.Equal(t, tenantLabelModel, actual) 881 require.Equal(t, value, actual.Value) 882 }) 883 884 t.Run("Success - Label for Application Template", func(t *testing.T) { 885 appTemplatelabelModel := fixModelLabel(model.AppTemplateLabelableObject) 886 appTemplateLabelEntity := fixEntityLabel(model.AppTemplateLabelableObject) 887 888 mockConverter := &automock.Converter{} 889 defer mockConverter.AssertExpectations(t) 890 mockConverter.On("FromEntity", appTemplateLabelEntity).Return(appTemplatelabelModel, nil).Once() 891 892 labelRepo := label.NewRepository(mockConverter) 893 894 db, dbMock := testdb.MockDatabase(t) 895 defer dbMock.AssertExpectations(t) 896 897 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE tenant_id = $1 AND key = $2`) 898 mockedRows := sqlmock.NewRows(fixColumns).AddRow(appTemplateLabelEntity.ID, appTemplateLabelEntity.TenantID, appTemplateLabelEntity.AppID, appTemplateLabelEntity.RuntimeID, appTemplateLabelEntity.RuntimeContextID, appTemplateLabelEntity.AppTemplateID, appTemplateLabelEntity.Key, appTemplateLabelEntity.Value, appTemplateLabelEntity.Version) 899 dbMock.ExpectQuery(escapedQuery).WithArgs(tenantID, key).WillReturnRows(mockedRows) 900 901 ctx := context.TODO() 902 ctx = persistence.SaveToContext(ctx, db) 903 // WHEN 904 actual, err := labelRepo.GetByKey(ctx, tenantID, model.TenantLabelableObject, tenantID, key) 905 // THEN 906 require.NoError(t, err) 907 require.Equal(t, appTemplatelabelModel, actual) 908 require.Equal(t, value, actual.Value) 909 }) 910 } 911 912 func TestRepository_GetByKeyGlobal(t *testing.T) { 913 appLabelModel := fixModelLabel(model.ApplicationLabelableObject) 914 appLabelEntity := fixEntityLabel(model.ApplicationLabelableObject) 915 916 appLabelSuite := testdb.RepoGetTestSuite{ 917 Name: "Get Application Label with global getter", 918 SQLQueryDetails: []testdb.SQLQueryDetails{ 919 { 920 Query: regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_id = $2`), 921 Args: []driver.Value{key, refID}, 922 IsSelect: true, 923 ValidRowsProvider: func() []*sqlmock.Rows { 924 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns). 925 AddRow(appLabelEntity.ID, appLabelEntity.TenantID, appLabelEntity.AppID, appLabelEntity.RuntimeID, appLabelEntity.RuntimeContextID, appLabelEntity.AppTemplateID, appLabelEntity.Key, appLabelEntity.Value, appLabelEntity.Version)} 926 }, 927 InvalidRowsProvider: func() []*sqlmock.Rows { 928 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)} 929 }, 930 }, 931 }, 932 ConverterMockProvider: func() testdb.Mock { 933 return &automock.Converter{} 934 }, 935 RepoConstructorFunc: label.NewRepository, 936 ExpectedModelEntity: appLabelModel, 937 ExpectedDBEntity: appLabelEntity, 938 MethodArgs: []interface{}{model.ApplicationLabelableObject, refID, key}, 939 MethodName: "GetByKeyGlobal", 940 } 941 942 appLabelSuite.Run(t) 943 } 944 945 func TestRepository_ListForObject(t *testing.T) { 946 t.Run("Success - Label for Runtime", func(t *testing.T) { 947 // GIVEN 948 label1Model := fixModelLabelWithID("1", "foo", model.RuntimeLabelableObject) 949 label2Model := fixModelLabelWithID("2", "bar", model.RuntimeLabelableObject) 950 951 label1Entity := fixEntityLabelWithID("1", "foo", model.RuntimeLabelableObject) 952 label2Entity := fixEntityLabelWithID("2", "bar", model.RuntimeLabelableObject) 953 954 inputItems := []*label.Entity{label1Entity, label2Entity} 955 expected := map[string]*model.Label{ 956 "foo": label1Model, 957 "bar": label2Model, 958 } 959 960 mockConverter := &automock.Converter{} 961 defer mockConverter.AssertExpectations(t) 962 for _, entity := range inputItems { 963 mockConverter.On("FromEntity", entity).Return(expected[entity.Key], nil).Once() 964 } 965 966 labelRepo := label.NewRepository(mockConverter) 967 968 db, dbMock := testdb.MockDatabase(t) 969 defer dbMock.AssertExpectations(t) 970 971 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE runtime_id = $1 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $2))`) 972 mockedRows := sqlmock.NewRows(fixColumns). 973 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 974 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 975 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: refID}, tenantID).WillReturnRows(mockedRows) 976 977 ctx := context.TODO() 978 ctx = persistence.SaveToContext(ctx, db) 979 // WHEN 980 actual, err := labelRepo.ListForObject(ctx, tenantID, model.RuntimeLabelableObject, refID) 981 // THEN 982 require.NoError(t, err) 983 assert.Equal(t, expected, actual) 984 }) 985 986 t.Run("Success - Label for Runtime Context", func(t *testing.T) { 987 // GIVEN 988 label1Model := fixModelLabelWithID("1", "foo", model.RuntimeContextLabelableObject) 989 label2Model := fixModelLabelWithID("2", "bar", model.RuntimeContextLabelableObject) 990 991 label1Entity := fixEntityLabelWithID("1", "foo", model.RuntimeContextLabelableObject) 992 label2Entity := fixEntityLabelWithID("2", "bar", model.RuntimeContextLabelableObject) 993 994 inputItems := []*label.Entity{label1Entity, label2Entity} 995 expected := map[string]*model.Label{ 996 "foo": label1Model, 997 "bar": label2Model, 998 } 999 1000 mockConverter := &automock.Converter{} 1001 defer mockConverter.AssertExpectations(t) 1002 for _, entity := range inputItems { 1003 mockConverter.On("FromEntity", entity).Return(expected[entity.Key], nil).Once() 1004 } 1005 1006 labelRepo := label.NewRepository(mockConverter) 1007 1008 db, dbMock := testdb.MockDatabase(t) 1009 defer dbMock.AssertExpectations(t) 1010 1011 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE runtime_context_id = $1 AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $2))`) 1012 mockedRows := sqlmock.NewRows(fixColumns). 1013 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 1014 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 1015 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: refID}, tenantID).WillReturnRows(mockedRows) 1016 1017 ctx := context.TODO() 1018 ctx = persistence.SaveToContext(ctx, db) 1019 // WHEN 1020 actual, err := labelRepo.ListForObject(ctx, tenantID, model.RuntimeContextLabelableObject, refID) 1021 // THEN 1022 require.NoError(t, err) 1023 assert.Equal(t, expected, actual) 1024 }) 1025 1026 t.Run("Success - Label for Application", func(t *testing.T) { 1027 // GIVEN 1028 label1Model := fixModelLabelWithID("1", "foo", model.ApplicationLabelableObject) 1029 label2Model := fixModelLabelWithID("2", "bar", model.ApplicationLabelableObject) 1030 1031 label1Entity := fixEntityLabelWithID("1", "foo", model.ApplicationLabelableObject) 1032 label2Entity := fixEntityLabelWithID("2", "bar", model.ApplicationLabelableObject) 1033 1034 inputItems := []*label.Entity{label1Entity, label2Entity} 1035 expected := map[string]*model.Label{ 1036 "foo": label1Model, 1037 "bar": label2Model, 1038 } 1039 1040 mockConverter := &automock.Converter{} 1041 defer mockConverter.AssertExpectations(t) 1042 for _, entity := range inputItems { 1043 mockConverter.On("FromEntity", entity).Return(expected[entity.Key], nil).Once() 1044 } 1045 1046 labelRepo := label.NewRepository(mockConverter) 1047 1048 db, dbMock := testdb.MockDatabase(t) 1049 defer dbMock.AssertExpectations(t) 1050 1051 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE app_id = $1 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $2))`) 1052 mockedRows := sqlmock.NewRows(fixColumns). 1053 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 1054 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label1Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 1055 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: refID}, tenantID).WillReturnRows(mockedRows) 1056 1057 ctx := context.TODO() 1058 ctx = persistence.SaveToContext(ctx, db) 1059 1060 // WHEN 1061 actual, err := labelRepo.ListForObject(ctx, tenantID, model.ApplicationLabelableObject, refID) 1062 // THEN 1063 require.NoError(t, err) 1064 assert.Equal(t, expected, actual) 1065 }) 1066 1067 t.Run("Success - Label for Tenant", func(t *testing.T) { 1068 // GIVEN 1069 label1Model := fixModelLabelWithID("1", "foo", model.TenantLabelableObject) 1070 label2Model := fixModelLabelWithID("2", "bar", model.TenantLabelableObject) 1071 1072 label1Entity := fixEntityLabelWithID("1", "foo", model.TenantLabelableObject) 1073 label2Entity := fixEntityLabelWithID("2", "bar", model.TenantLabelableObject) 1074 1075 inputItems := []*label.Entity{label1Entity, label2Entity} 1076 expected := map[string]*model.Label{ 1077 "foo": label1Model, 1078 "bar": label2Model, 1079 } 1080 1081 mockConverter := &automock.Converter{} 1082 defer mockConverter.AssertExpectations(t) 1083 for _, entity := range inputItems { 1084 mockConverter.On("FromEntity", entity).Return(expected[entity.Key], nil).Once() 1085 } 1086 1087 labelRepo := label.NewRepository(mockConverter) 1088 1089 db, dbMock := testdb.MockDatabase(t) 1090 defer dbMock.AssertExpectations(t) 1091 1092 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE tenant_id = $1 AND app_id IS NULL AND runtime_context_id IS NULL AND runtime_id IS NULL`) 1093 mockedRows := sqlmock.NewRows(fixColumns). 1094 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 1095 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 1096 dbMock.ExpectQuery(escapedQuery).WithArgs(tenantID).WillReturnRows(mockedRows) 1097 1098 ctx := context.TODO() 1099 ctx = persistence.SaveToContext(ctx, db) 1100 1101 // WHEN 1102 actual, err := labelRepo.ListForObject(ctx, tenantID, model.TenantLabelableObject, tenantID) 1103 // THEN 1104 require.NoError(t, err) 1105 assert.Equal(t, expected, actual) 1106 }) 1107 1108 t.Run("Success - Label for Application Template", func(t *testing.T) { 1109 // GIVEN 1110 label1Model := fixModelLabelWithID("1", "foo", model.AppTemplateLabelableObject) 1111 label2Model := fixModelLabelWithID("2", "bar", model.AppTemplateLabelableObject) 1112 1113 label1Entity := fixEntityLabelWithID("1", "foo", model.AppTemplateLabelableObject) 1114 label2Entity := fixEntityLabelWithID("2", "bar", model.AppTemplateLabelableObject) 1115 1116 inputItems := []*label.Entity{label1Entity, label2Entity} 1117 expected := map[string]*model.Label{ 1118 "foo": label1Model, 1119 "bar": label2Model, 1120 } 1121 1122 mockConverter := &automock.Converter{} 1123 defer mockConverter.AssertExpectations(t) 1124 for _, entity := range inputItems { 1125 mockConverter.On("FromEntity", entity).Return(expected[entity.Key], nil).Once() 1126 } 1127 1128 labelRepo := label.NewRepository(mockConverter) 1129 1130 db, dbMock := testdb.MockDatabase(t) 1131 defer dbMock.AssertExpectations(t) 1132 1133 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE `) 1134 mockedRows := sqlmock.NewRows(fixColumns). 1135 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 1136 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 1137 dbMock.ExpectQuery(escapedQuery).WithArgs(tenantID).WillReturnRows(mockedRows) 1138 1139 ctx := context.TODO() 1140 ctx = persistence.SaveToContext(ctx, db) 1141 1142 // WHEN 1143 actual, err := labelRepo.ListForObject(ctx, tenantID, model.AppTemplateLabelableObject, tenantID) 1144 // THEN 1145 require.NoError(t, err) 1146 assert.Equal(t, expected, actual) 1147 }) 1148 1149 t.Run("Error - Doesn't exist", func(t *testing.T) { 1150 mockConverter := &automock.Converter{} 1151 defer mockConverter.AssertExpectations(t) 1152 1153 labelRepo := label.NewRepository(mockConverter) 1154 1155 db, dbMock := testdb.MockDatabase(t) 1156 defer dbMock.AssertExpectations(t) 1157 1158 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE app_id = $1 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $2))`) 1159 mockedRows := sqlmock.NewRows(fixColumns) 1160 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: refID}, tenantID).WillReturnRows(mockedRows) 1161 1162 ctx := context.TODO() 1163 ctx = persistence.SaveToContext(ctx, db) 1164 // WHEN 1165 actual, err := labelRepo.ListForObject(ctx, tenantID, model.ApplicationLabelableObject, refID) 1166 // THEN 1167 require.NoError(t, err) 1168 assert.Empty(t, actual) 1169 }) 1170 1171 t.Run("Error - Select error", func(t *testing.T) { 1172 labelRepo := label.NewRepository(nil) 1173 db, dbMock := testdb.MockDatabase(t) 1174 defer dbMock.AssertExpectations(t) 1175 1176 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE app_id = $1 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $2))`) 1177 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: refID}, tenantID).WillReturnError(errors.New("persistence error")) 1178 1179 ctx := context.TODO() 1180 ctx = persistence.SaveToContext(ctx, db) 1181 // WHEN 1182 _, err := labelRepo.ListForObject(ctx, tenantID, model.ApplicationLabelableObject, refID) 1183 // THEN 1184 require.Error(t, err) 1185 require.Contains(t, err.Error(), "Unexpected error while executing SQL query") 1186 }) 1187 1188 t.Run("Error - Missing persistence", func(t *testing.T) { 1189 // GIVEN 1190 labelRepo := label.NewRepository(nil) 1191 1192 // WHEN 1193 _, err := labelRepo.ListForObject(context.TODO(), tenantID, model.ApplicationLabelableObject, refID) 1194 // THEN 1195 require.Error(t, err) 1196 require.Contains(t, err.Error(), "unable to fetch database from context") 1197 }) 1198 } 1199 1200 func TestRepository_ListByKey(t *testing.T) { 1201 label1Model := fixModelLabelWithID("1", "foo", model.RuntimeLabelableObject) 1202 label2Model := fixModelLabelWithID("2", "bar", model.ApplicationLabelableObject) 1203 label3Model := fixModelLabelWithID("3", "bar", model.RuntimeContextLabelableObject) 1204 1205 label1Entity := fixEntityLabelWithID("1", "foo", model.RuntimeLabelableObject) 1206 label2Entity := fixEntityLabelWithID("2", "bar", model.ApplicationLabelableObject) 1207 label3Entity := fixEntityLabelWithID("3", "bar", model.RuntimeContextLabelableObject) 1208 1209 suite := testdb.RepoListTestSuite{ 1210 Name: "List Labels by key", 1211 SQLQueryDetails: []testdb.SQLQueryDetails{ 1212 { 1213 Query: regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND (id IN (SELECT id FROM labels_tenants WHERE tenant_id = $2))`), 1214 Args: []driver.Value{key, tenantID}, 1215 IsSelect: true, 1216 ValidRowsProvider: func() []*sqlmock.Rows { 1217 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns). 1218 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 1219 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version). 1220 AddRow(label3Entity.ID, label3Entity.TenantID, label3Entity.AppID, label3Entity.RuntimeID, label3Entity.RuntimeContextID, label3Entity.AppTemplateID, label3Entity.Key, label3Entity.Value, label3Entity.Version), 1221 } 1222 }, 1223 InvalidRowsProvider: func() []*sqlmock.Rows { 1224 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)} 1225 }, 1226 }, 1227 }, 1228 ConverterMockProvider: func() testdb.Mock { 1229 return &automock.Converter{} 1230 }, 1231 RepoConstructorFunc: label.NewRepository, 1232 ExpectedModelEntities: []interface{}{label1Model, label2Model, label3Model}, 1233 ExpectedDBEntities: []interface{}{label1Entity, label2Entity, label3Entity}, 1234 MethodArgs: []interface{}{tenantID, key}, 1235 MethodName: "ListByKey", 1236 } 1237 1238 suite.Run(t) 1239 } 1240 1241 func TestRepository_ListGlobalByKey(t *testing.T) { 1242 t.Run("Success", func(t *testing.T) { 1243 // GIVEN 1244 objType := model.ApplicationLabelableObject 1245 objIDs := []string{"foo", "bar", "baz"} 1246 labelKey := "key" 1247 version := 42 1248 1249 inputItems := []*label.Entity{ 1250 {ID: "1", Key: labelKey, Value: "test1", AppID: sql.NullString{Valid: true, String: objIDs[0]}, Version: version}, 1251 {ID: "2", Key: labelKey, Value: "test2", AppID: sql.NullString{Valid: true, String: objIDs[1]}, Version: version}, 1252 {ID: "3", Key: labelKey, Value: "test3", AppID: sql.NullString{Valid: true, String: objIDs[2]}, Version: version}, 1253 } 1254 expected := []*model.Label{ 1255 {ID: "1", Key: labelKey, Value: "test1", ObjectType: objType, ObjectID: objIDs[0], Version: version}, 1256 {ID: "2", Key: labelKey, Value: "test2", ObjectType: objType, ObjectID: objIDs[1], Version: version}, 1257 {ID: "3", Key: labelKey, Value: "test3", ObjectType: objType, ObjectID: objIDs[2], Version: version}, 1258 } 1259 1260 mockConverter := &automock.Converter{} 1261 defer mockConverter.AssertExpectations(t) 1262 for _, entity := range inputItems { 1263 for i := range expected { 1264 if expected[i].ObjectID == entity.AppID.String { 1265 mockConverter.On("FromEntity", entity).Return(expected[i], nil).Once() 1266 } 1267 } 1268 } 1269 1270 labelRepo := label.NewRepository(mockConverter) 1271 1272 db, dbMock := testdb.MockDatabase(t) 1273 defer dbMock.AssertExpectations(t) 1274 1275 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1`) 1276 mockedRows := sqlmock.NewRows([]string{"id", "tenant_id", "app_template_id", "key", "value", "app_id", "runtime_id", "runtime_context_id", "version"}). 1277 AddRow("1", nil, nil, labelKey, "test1", objIDs[0], nil, nil, version). 1278 AddRow("2", nil, nil, labelKey, "test2", objIDs[1], nil, nil, version). 1279 AddRow("3", nil, nil, labelKey, "test3", objIDs[2], nil, nil, version) 1280 dbMock.ExpectQuery(escapedQuery).WithArgs(labelKey).WillReturnRows(mockedRows) 1281 1282 ctx := context.TODO() 1283 ctx = persistence.SaveToContext(ctx, db) 1284 1285 // WHEN 1286 actual, err := labelRepo.ListGlobalByKey(ctx, labelKey) 1287 // THEN 1288 require.NoError(t, err) 1289 assert.Equal(t, expected, actual) 1290 }) 1291 1292 t.Run("Error - Select error", func(t *testing.T) { 1293 // GIVEN 1294 labelKey := "key" 1295 1296 labelRepo := label.NewRepository(nil) 1297 1298 db, dbMock := testdb.MockDatabase(t) 1299 defer dbMock.AssertExpectations(t) 1300 1301 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1`) 1302 dbMock.ExpectQuery(escapedQuery).WithArgs(labelKey).WillReturnError(errors.New("persistence error")) 1303 1304 ctx := context.TODO() 1305 ctx = persistence.SaveToContext(ctx, db) 1306 1307 // WHEN 1308 _, err := labelRepo.ListGlobalByKey(ctx, labelKey) 1309 // THEN 1310 require.Error(t, err) 1311 require.Contains(t, err.Error(), "Unexpected error while executing SQL query") 1312 }) 1313 1314 t.Run("Error - Converting entity", func(t *testing.T) { 1315 // GIVEN 1316 objIDs := []string{"foo", "bar", "baz"} 1317 labelKey := "key" 1318 testErr := errors.New("test error") 1319 version := 42 1320 1321 mockConverter := &automock.Converter{} 1322 mockConverter.On("FromEntity", mock.Anything).Return(&model.Label{}, testErr).Once() 1323 1324 labelRepo := label.NewRepository(mockConverter) 1325 1326 db, dbMock := testdb.MockDatabase(t) 1327 defer dbMock.AssertExpectations(t) 1328 1329 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1`) 1330 mockedRows := sqlmock.NewRows([]string{"id", "tenant_id", "app_template_id", "key", "value", "app_id", "runtime_id", "runtime_context_id", "version"}). 1331 AddRow("1", nil, nil, labelKey, "test1", objIDs[0], nil, nil, version) 1332 dbMock.ExpectQuery(escapedQuery).WithArgs(labelKey).WillReturnRows(mockedRows) 1333 1334 ctx := context.TODO() 1335 ctx = persistence.SaveToContext(ctx, db) 1336 1337 // WHEN 1338 _, err := labelRepo.ListGlobalByKey(ctx, labelKey) 1339 // THEN 1340 require.Error(t, err) 1341 }) 1342 } 1343 1344 func TestRepository_ListGlobalByKeyAndObjects(t *testing.T) { 1345 t.Run("Success", func(t *testing.T) { 1346 // GIVEN 1347 objType := model.ApplicationLabelableObject 1348 objIDs := []string{"foo", "bar", "baz"} 1349 labelKey := "key" 1350 version := 42 1351 1352 inputItems := []*label.Entity{ 1353 {ID: "1", Key: labelKey, Value: "test1", AppID: sql.NullString{Valid: true, String: objIDs[0]}, Version: version}, 1354 {ID: "2", Key: labelKey, Value: "test2", AppID: sql.NullString{Valid: true, String: objIDs[1]}, Version: version}, 1355 {ID: "3", Key: labelKey, Value: "test3", AppID: sql.NullString{Valid: true, String: objIDs[2]}, Version: version}, 1356 } 1357 expected := []*model.Label{ 1358 {ID: "1", Key: labelKey, Value: "test1", ObjectType: objType, ObjectID: objIDs[0], Version: version}, 1359 {ID: "2", Key: labelKey, Value: "test2", ObjectType: objType, ObjectID: objIDs[1], Version: version}, 1360 {ID: "3", Key: labelKey, Value: "test3", ObjectType: objType, ObjectID: objIDs[2], Version: version}, 1361 } 1362 1363 mockConverter := &automock.Converter{} 1364 defer mockConverter.AssertExpectations(t) 1365 for _, entity := range inputItems { 1366 for i := range expected { 1367 if expected[i].ObjectID == entity.AppID.String { 1368 mockConverter.On("FromEntity", entity).Return(expected[i], nil).Once() 1369 } 1370 } 1371 } 1372 1373 labelRepo := label.NewRepository(mockConverter) 1374 1375 db, dbMock := testdb.MockDatabase(t) 1376 defer dbMock.AssertExpectations(t) 1377 1378 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_id IN ($2, $3, $4) FOR UPDATE`) 1379 mockedRows := sqlmock.NewRows([]string{"id", "tenant_id", "app_template_id", "key", "value", "app_id", "runtime_id", "runtime_context_id", "version"}). 1380 AddRow("1", nil, nil, labelKey, "test1", objIDs[0], nil, nil, version). 1381 AddRow("2", nil, nil, labelKey, "test2", objIDs[1], nil, nil, version). 1382 AddRow("3", nil, nil, labelKey, "test3", objIDs[2], nil, nil, version) 1383 dbMock.ExpectQuery(escapedQuery).WithArgs(labelKey, sql.NullString{Valid: true, String: objIDs[0]}, sql.NullString{Valid: true, String: objIDs[1]}, sql.NullString{Valid: true, String: objIDs[2]}).WillReturnRows(mockedRows) 1384 1385 ctx := context.TODO() 1386 ctx = persistence.SaveToContext(ctx, db) 1387 1388 // WHEN 1389 actual, err := labelRepo.ListGlobalByKeyAndObjects(ctx, objType, objIDs, labelKey) 1390 // THEN 1391 require.NoError(t, err) 1392 assert.Equal(t, expected, actual) 1393 }) 1394 1395 t.Run("Error - Select error", func(t *testing.T) { 1396 // GIVEN 1397 objType := model.ApplicationLabelableObject 1398 objIDs := []string{"foo", "bar", "baz"} 1399 labelKey := "key" 1400 1401 labelRepo := label.NewRepository(nil) 1402 1403 db, dbMock := testdb.MockDatabase(t) 1404 defer dbMock.AssertExpectations(t) 1405 1406 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_id IN ($2, $3, $4) FOR UPDATE`) 1407 dbMock.ExpectQuery(escapedQuery).WithArgs(labelKey, sql.NullString{Valid: true, String: objIDs[0]}, sql.NullString{Valid: true, String: objIDs[1]}, sql.NullString{Valid: true, String: objIDs[2]}). 1408 WillReturnError(errors.New("persistence error")) 1409 1410 ctx := context.TODO() 1411 ctx = persistence.SaveToContext(ctx, db) 1412 1413 // WHEN 1414 _, err := labelRepo.ListGlobalByKeyAndObjects(ctx, objType, objIDs, labelKey) 1415 // THEN 1416 require.Error(t, err) 1417 require.Contains(t, err.Error(), "Unexpected error while executing SQL query") 1418 }) 1419 1420 t.Run("Error - Converting entity", func(t *testing.T) { 1421 // GIVEN 1422 objType := model.ApplicationLabelableObject 1423 objIDs := []string{"foo", "bar", "baz"} 1424 labelKey := "key" 1425 testErr := errors.New("test error") 1426 version := 42 1427 1428 mockConverter := &automock.Converter{} 1429 mockConverter.On("FromEntity", mock.Anything).Return(&model.Label{}, testErr).Once() 1430 1431 labelRepo := label.NewRepository(mockConverter) 1432 1433 db, dbMock := testdb.MockDatabase(t) 1434 defer dbMock.AssertExpectations(t) 1435 1436 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND app_id IN ($2, $3, $4) FOR UPDATE`) 1437 mockedRows := sqlmock.NewRows([]string{"id", "tenant_id", "app_template_id", "key", "value", "app_id", "runtime_id", "runtime_context_id", "version"}). 1438 AddRow("1", nil, nil, labelKey, "test1", objIDs[0], nil, nil, version) 1439 dbMock.ExpectQuery(escapedQuery).WithArgs(labelKey, sql.NullString{Valid: true, String: objIDs[0]}, sql.NullString{Valid: true, String: objIDs[1]}, sql.NullString{Valid: true, String: objIDs[2]}).WillReturnRows(mockedRows) 1440 1441 ctx := context.TODO() 1442 ctx = persistence.SaveToContext(ctx, db) 1443 1444 // WHEN 1445 _, err := labelRepo.ListGlobalByKeyAndObjects(ctx, objType, objIDs, labelKey) 1446 // THEN 1447 require.Error(t, err) 1448 }) 1449 } 1450 1451 func TestRepository_Delete(t *testing.T) { 1452 appLabelSuite := testdb.RepoDeleteTestSuite{ 1453 Name: "App Label Delete", 1454 SQLQueryDetails: []testdb.SQLQueryDetails{ 1455 { 1456 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE key = $1 AND app_id = $2 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $3 AND owner = true))`), 1457 Args: []driver.Value{key, refID, tenantID}, 1458 ValidResult: sqlmock.NewResult(-1, 1), 1459 InvalidResult: sqlmock.NewResult(-1, 2), 1460 }, 1461 }, 1462 ConverterMockProvider: func() testdb.Mock { 1463 return &automock.Converter{} 1464 }, 1465 RepoConstructorFunc: label.NewRepository, 1466 MethodArgs: []interface{}{tenantID, model.ApplicationLabelableObject, refID, key}, 1467 IsDeleteMany: true, 1468 } 1469 1470 rtLabelSuite := testdb.RepoDeleteTestSuite{ 1471 Name: "Runtime Label Delete", 1472 SQLQueryDetails: []testdb.SQLQueryDetails{ 1473 { 1474 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE key = $1 AND runtime_id = $2 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $3 AND owner = true))`), 1475 Args: []driver.Value{key, refID, tenantID}, 1476 ValidResult: sqlmock.NewResult(-1, 1), 1477 InvalidResult: sqlmock.NewResult(-1, 2), 1478 }, 1479 }, 1480 ConverterMockProvider: func() testdb.Mock { 1481 return &automock.Converter{} 1482 }, 1483 RepoConstructorFunc: label.NewRepository, 1484 MethodArgs: []interface{}{tenantID, model.RuntimeLabelableObject, refID, key}, 1485 IsDeleteMany: true, 1486 } 1487 1488 rtCtxLabelSuite := testdb.RepoDeleteTestSuite{ 1489 Name: "Runtime Context Label Delete", 1490 SQLQueryDetails: []testdb.SQLQueryDetails{ 1491 { 1492 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE key = $1 AND runtime_context_id = $2 AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $3 AND owner = true))`), 1493 Args: []driver.Value{key, refID, tenantID}, 1494 ValidResult: sqlmock.NewResult(-1, 1), 1495 InvalidResult: sqlmock.NewResult(-1, 2), 1496 }, 1497 }, 1498 ConverterMockProvider: func() testdb.Mock { 1499 return &automock.Converter{} 1500 }, 1501 RepoConstructorFunc: label.NewRepository, 1502 MethodArgs: []interface{}{tenantID, model.RuntimeContextLabelableObject, refID, key}, 1503 IsDeleteMany: true, 1504 } 1505 1506 appLabelSuite.Run(t) 1507 rtLabelSuite.Run(t) 1508 rtCtxLabelSuite.Run(t) 1509 1510 t.Run("Success - Label for Tenant", func(t *testing.T) { 1511 mockConverter := &automock.Converter{} 1512 defer mockConverter.AssertExpectations(t) 1513 1514 labelRepo := label.NewRepository(mockConverter) 1515 1516 db, dbMock := testdb.MockDatabase(t) 1517 defer dbMock.AssertExpectations(t) 1518 1519 escapedQuery := regexp.QuoteMeta(`DELETE FROM public.labels WHERE tenant_id = $1 AND key = $2`) 1520 dbMock.ExpectExec(escapedQuery).WithArgs(tenantID, key).WillReturnResult(sqlmock.NewResult(-1, 1)) 1521 1522 ctx := context.TODO() 1523 ctx = persistence.SaveToContext(ctx, db) 1524 // WHEN 1525 err := labelRepo.Delete(ctx, tenantID, model.TenantLabelableObject, tenantID, key) 1526 // THEN 1527 require.NoError(t, err) 1528 }) 1529 1530 t.Run("Success - Label for Tenant", func(t *testing.T) { 1531 mockConverter := &automock.Converter{} 1532 defer mockConverter.AssertExpectations(t) 1533 1534 labelRepo := label.NewRepository(mockConverter) 1535 1536 db, dbMock := testdb.MockDatabase(t) 1537 defer dbMock.AssertExpectations(t) 1538 1539 escapedQuery := regexp.QuoteMeta(`DELETE FROM public.labels WHERE key = $1 AND app_template_id = $2`) 1540 dbMock.ExpectExec(escapedQuery).WithArgs(key, refID).WillReturnResult(sqlmock.NewResult(-1, 1)) 1541 1542 ctx := context.TODO() 1543 ctx = persistence.SaveToContext(ctx, db) 1544 // WHEN 1545 err := labelRepo.Delete(ctx, tenantID, model.AppTemplateLabelableObject, refID, key) 1546 // THEN 1547 require.NoError(t, err) 1548 }) 1549 } 1550 1551 func TestRepository_DeleteAll(t *testing.T) { 1552 appLabelSuite := testdb.RepoDeleteTestSuite{ 1553 Name: "App Label Delete All", 1554 SQLQueryDetails: []testdb.SQLQueryDetails{ 1555 { 1556 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE app_id = $1 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $2 AND owner = true))`), 1557 Args: []driver.Value{refID, tenantID}, 1558 ValidResult: sqlmock.NewResult(-1, 1), 1559 InvalidResult: sqlmock.NewResult(-1, 2), 1560 }, 1561 }, 1562 ConverterMockProvider: func() testdb.Mock { 1563 return &automock.Converter{} 1564 }, 1565 RepoConstructorFunc: label.NewRepository, 1566 MethodArgs: []interface{}{tenantID, model.ApplicationLabelableObject, refID}, 1567 MethodName: "DeleteAll", 1568 IsDeleteMany: true, 1569 } 1570 1571 rtLabelSuite := testdb.RepoDeleteTestSuite{ 1572 Name: "Runtime Label Delete All", 1573 SQLQueryDetails: []testdb.SQLQueryDetails{ 1574 { 1575 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE runtime_id = $1 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $2 AND owner = true))`), 1576 Args: []driver.Value{refID, tenantID}, 1577 ValidResult: sqlmock.NewResult(-1, 1), 1578 InvalidResult: sqlmock.NewResult(-1, 2), 1579 }, 1580 }, 1581 ConverterMockProvider: func() testdb.Mock { 1582 return &automock.Converter{} 1583 }, 1584 RepoConstructorFunc: label.NewRepository, 1585 MethodArgs: []interface{}{tenantID, model.RuntimeLabelableObject, refID}, 1586 MethodName: "DeleteAll", 1587 IsDeleteMany: true, 1588 } 1589 1590 rtCtxLabelSuite := testdb.RepoDeleteTestSuite{ 1591 Name: "Runtime Context Label Delete All", 1592 SQLQueryDetails: []testdb.SQLQueryDetails{ 1593 { 1594 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE runtime_context_id = $1 AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $2 AND owner = true))`), 1595 Args: []driver.Value{refID, tenantID}, 1596 ValidResult: sqlmock.NewResult(-1, 1), 1597 InvalidResult: sqlmock.NewResult(-1, 2), 1598 }, 1599 }, 1600 ConverterMockProvider: func() testdb.Mock { 1601 return &automock.Converter{} 1602 }, 1603 RepoConstructorFunc: label.NewRepository, 1604 MethodArgs: []interface{}{tenantID, model.RuntimeContextLabelableObject, refID}, 1605 MethodName: "DeleteAll", 1606 IsDeleteMany: true, 1607 } 1608 1609 appLabelSuite.Run(t) 1610 rtLabelSuite.Run(t) 1611 rtCtxLabelSuite.Run(t) 1612 1613 t.Run("Success - Label for Tenant", func(t *testing.T) { 1614 mockConverter := &automock.Converter{} 1615 defer mockConverter.AssertExpectations(t) 1616 1617 labelRepo := label.NewRepository(mockConverter) 1618 1619 db, dbMock := testdb.MockDatabase(t) 1620 defer dbMock.AssertExpectations(t) 1621 1622 escapedQuery := regexp.QuoteMeta(`DELETE FROM public.labels WHERE tenant_id = $1`) 1623 dbMock.ExpectExec(escapedQuery).WithArgs(tenantID).WillReturnResult(sqlmock.NewResult(-1, 1)) 1624 1625 ctx := context.TODO() 1626 ctx = persistence.SaveToContext(ctx, db) 1627 // WHEN 1628 err := labelRepo.DeleteAll(ctx, tenantID, model.TenantLabelableObject, tenantID) 1629 // THEN 1630 require.NoError(t, err) 1631 }) 1632 1633 t.Run("Success - Label for Application Template", func(t *testing.T) { 1634 mockConverter := &automock.Converter{} 1635 defer mockConverter.AssertExpectations(t) 1636 1637 labelRepo := label.NewRepository(mockConverter) 1638 1639 db, dbMock := testdb.MockDatabase(t) 1640 defer dbMock.AssertExpectations(t) 1641 1642 escapedQuery := regexp.QuoteMeta(`DELETE FROM public.labels WHERE app_template_id = $1`) 1643 dbMock.ExpectExec(escapedQuery).WithArgs(refID).WillReturnResult(sqlmock.NewResult(-1, 1)) 1644 1645 ctx := context.TODO() 1646 ctx = persistence.SaveToContext(ctx, db) 1647 // WHEN 1648 err := labelRepo.DeleteAll(ctx, tenantID, model.AppTemplateLabelableObject, refID) 1649 // THEN 1650 require.NoError(t, err) 1651 }) 1652 } 1653 1654 func TestRepository_DeleteByKey(t *testing.T) { 1655 suite := testdb.RepoDeleteTestSuite{ 1656 Name: "Label Delete By Key", 1657 SQLQueryDetails: []testdb.SQLQueryDetails{ 1658 { 1659 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE key = $1 AND (id IN (SELECT id FROM labels_tenants WHERE tenant_id = $2 AND owner = true))`), 1660 Args: []driver.Value{key, tenantID}, 1661 ValidResult: sqlmock.NewResult(-1, 1), 1662 InvalidResult: sqlmock.NewResult(-1, 2), 1663 }, 1664 }, 1665 ConverterMockProvider: func() testdb.Mock { 1666 return &automock.Converter{} 1667 }, 1668 RepoConstructorFunc: label.NewRepository, 1669 MethodArgs: []interface{}{tenantID, key}, 1670 MethodName: "DeleteByKey", 1671 IsDeleteMany: true, 1672 } 1673 1674 suite.Run(t) 1675 } 1676 1677 func TestRepository_DeleteByKeyNegationPattern(t *testing.T) { 1678 pattern := "pattern" 1679 1680 appLabelSuite := testdb.RepoDeleteTestSuite{ 1681 Name: "App Label DeleteByKeyNegationPattern", 1682 SQLQueryDetails: []testdb.SQLQueryDetails{ 1683 { 1684 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE NOT key ~ $1 AND app_id = $2 AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $3 AND owner = true))`), 1685 Args: []driver.Value{pattern, refID, tenantID}, 1686 ValidResult: sqlmock.NewResult(-1, 1), 1687 InvalidResult: sqlmock.NewResult(-1, 2), 1688 }, 1689 }, 1690 ConverterMockProvider: func() testdb.Mock { 1691 return &automock.Converter{} 1692 }, 1693 RepoConstructorFunc: label.NewRepository, 1694 MethodArgs: []interface{}{tenantID, model.ApplicationLabelableObject, refID, pattern}, 1695 MethodName: "DeleteByKeyNegationPattern", 1696 IsDeleteMany: true, 1697 } 1698 1699 rtLabelSuite := testdb.RepoDeleteTestSuite{ 1700 Name: "Runtime Label DeleteByKeyNegationPattern", 1701 SQLQueryDetails: []testdb.SQLQueryDetails{ 1702 { 1703 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE NOT key ~ $1 AND runtime_id = $2 AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $3 AND owner = true))`), 1704 Args: []driver.Value{pattern, refID, tenantID}, 1705 ValidResult: sqlmock.NewResult(-1, 1), 1706 InvalidResult: sqlmock.NewResult(-1, 2), 1707 }, 1708 }, 1709 ConverterMockProvider: func() testdb.Mock { 1710 return &automock.Converter{} 1711 }, 1712 RepoConstructorFunc: label.NewRepository, 1713 MethodArgs: []interface{}{tenantID, model.RuntimeLabelableObject, refID, pattern}, 1714 MethodName: "DeleteByKeyNegationPattern", 1715 IsDeleteMany: true, 1716 } 1717 1718 rtCtxLabelSuite := testdb.RepoDeleteTestSuite{ 1719 Name: "Runtime Context Label DeleteByKeyNegationPattern", 1720 SQLQueryDetails: []testdb.SQLQueryDetails{ 1721 { 1722 Query: regexp.QuoteMeta(`DELETE FROM public.labels WHERE NOT key ~ $1 AND runtime_context_id = $2 AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $3 AND owner = true))`), 1723 Args: []driver.Value{pattern, refID, tenantID}, 1724 ValidResult: sqlmock.NewResult(-1, 1), 1725 InvalidResult: sqlmock.NewResult(-1, 2), 1726 }, 1727 }, 1728 ConverterMockProvider: func() testdb.Mock { 1729 return &automock.Converter{} 1730 }, 1731 RepoConstructorFunc: label.NewRepository, 1732 MethodArgs: []interface{}{tenantID, model.RuntimeContextLabelableObject, refID, pattern}, 1733 MethodName: "DeleteByKeyNegationPattern", 1734 IsDeleteMany: true, 1735 } 1736 1737 appLabelSuite.Run(t) 1738 rtLabelSuite.Run(t) 1739 rtCtxLabelSuite.Run(t) 1740 1741 t.Run("Success - Label for Tenant", func(t *testing.T) { 1742 mockConverter := &automock.Converter{} 1743 defer mockConverter.AssertExpectations(t) 1744 1745 labelRepo := label.NewRepository(mockConverter) 1746 1747 db, dbMock := testdb.MockDatabase(t) 1748 defer dbMock.AssertExpectations(t) 1749 1750 escapedQuery := regexp.QuoteMeta(`DELETE FROM public.labels WHERE tenant_id = $1 AND NOT key ~ $2 `) 1751 dbMock.ExpectExec(escapedQuery).WithArgs(tenantID, pattern).WillReturnResult(sqlmock.NewResult(-1, 1)) 1752 1753 ctx := context.TODO() 1754 ctx = persistence.SaveToContext(ctx, db) 1755 // WHEN 1756 err := labelRepo.DeleteByKeyNegationPattern(ctx, tenantID, model.TenantLabelableObject, tenantID, pattern) 1757 // THEN 1758 require.NoError(t, err) 1759 }) 1760 1761 t.Run("Success - Label for Application Template", func(t *testing.T) { 1762 mockConverter := &automock.Converter{} 1763 defer mockConverter.AssertExpectations(t) 1764 1765 labelRepo := label.NewRepository(mockConverter) 1766 1767 db, dbMock := testdb.MockDatabase(t) 1768 defer dbMock.AssertExpectations(t) 1769 1770 escapedQuery := regexp.QuoteMeta(`DELETE FROM public.labels WHERE NOT key ~ $1 AND app_template_id = $2`) 1771 dbMock.ExpectExec(escapedQuery).WithArgs(pattern, refID).WillReturnResult(sqlmock.NewResult(-1, 1)) 1772 1773 ctx := context.TODO() 1774 ctx = persistence.SaveToContext(ctx, db) 1775 // WHEN 1776 err := labelRepo.DeleteByKeyNegationPattern(ctx, tenantID, model.AppTemplateLabelableObject, refID, pattern) 1777 // THEN 1778 require.NoError(t, err) 1779 }) 1780 } 1781 1782 func TestRepository_GetScenarioLabelsForRuntimes(t *testing.T) { 1783 rt1ID := "rt1" 1784 rt2ID := "rt2" 1785 1786 label1Model := fixModelLabelWithRefID("1", model.ScenariosKey, model.RuntimeLabelableObject, rt1ID) 1787 label2Model := fixModelLabelWithRefID("2", model.ScenariosKey, model.RuntimeLabelableObject, rt2ID) 1788 1789 label1Entity := fixEntityLabelWithRefID("1", model.ScenariosKey, model.RuntimeLabelableObject, rt1ID) 1790 label2Entity := fixEntityLabelWithRefID("2", model.ScenariosKey, model.RuntimeLabelableObject, rt2ID) 1791 1792 suite := testdb.RepoListTestSuite{ 1793 Name: "List Runtime Scenarios Matching Selector", 1794 SQLQueryDetails: []testdb.SQLQueryDetails{ 1795 { 1796 Query: regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE key = $1 AND runtime_id IN ($2, $3) AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $4))`), 1797 Args: []driver.Value{model.ScenariosKey, rt1ID, rt2ID, tenantID}, 1798 IsSelect: true, 1799 ValidRowsProvider: func() []*sqlmock.Rows { 1800 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns). 1801 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 1802 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version), 1803 } 1804 }, 1805 InvalidRowsProvider: func() []*sqlmock.Rows { 1806 return []*sqlmock.Rows{sqlmock.NewRows(fixColumns)} 1807 }, 1808 }, 1809 }, 1810 ConverterMockProvider: func() testdb.Mock { 1811 return &automock.Converter{} 1812 }, 1813 RepoConstructorFunc: label.NewRepository, 1814 ExpectedModelEntities: []interface{}{label1Model, label2Model}, 1815 ExpectedDBEntities: []interface{}{label1Entity, label2Entity}, 1816 MethodArgs: []interface{}{tenantID, []string{rt1ID, rt2ID}}, 1817 MethodName: "GetScenarioLabelsForRuntimes", 1818 } 1819 1820 suite.Run(t) 1821 } 1822 1823 func TestRepository_ListForObjectIDs(t *testing.T) { 1824 labelIDs := []string{"1", "2"} 1825 t.Run("Success - Label for Runtime", func(t *testing.T) { 1826 // GIVEN 1827 rt1ID := "rt1" 1828 rt2ID := "rt2" 1829 1830 label1Model := fixModelLabelWithRefID("1", "foo", model.RuntimeLabelableObject, rt1ID) 1831 label2Model := fixModelLabelWithRefID("2", "bar", model.RuntimeLabelableObject, rt2ID) 1832 1833 label1Entity := fixEntityLabelWithRefID("1", "foo", model.RuntimeLabelableObject, rt1ID) 1834 label2Entity := fixEntityLabelWithRefID("2", "bar", model.RuntimeLabelableObject, rt2ID) 1835 1836 inputItems := []*label.Entity{label1Entity, label2Entity} 1837 outputItems := []*model.Label{label1Model, label2Model} 1838 expected := map[string]map[string]interface{}{ 1839 rt1ID: { 1840 label1Model.Key: label1Model.Value, 1841 }, 1842 rt2ID: { 1843 label2Model.Key: label2Model.Value, 1844 }, 1845 } 1846 1847 mockConverter := &automock.Converter{} 1848 defer mockConverter.AssertExpectations(t) 1849 for i, entity := range inputItems { 1850 mockConverter.On("FromEntity", entity).Return(outputItems[i], nil).Once() 1851 } 1852 1853 labelRepo := label.NewRepository(mockConverter) 1854 1855 db, dbMock := testdb.MockDatabase(t) 1856 defer dbMock.AssertExpectations(t) 1857 1858 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE runtime_id IN ($1, $2) AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = $3))`) 1859 mockedRows := sqlmock.NewRows(fixColumns). 1860 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 1861 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 1862 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: labelIDs[0]}, sql.NullString{Valid: true, String: labelIDs[1]}, tenantID).WillReturnRows(mockedRows) 1863 1864 ctx := context.TODO() 1865 ctx = persistence.SaveToContext(ctx, db) 1866 // WHEN 1867 actual, err := labelRepo.ListForObjectIDs(ctx, tenantID, model.RuntimeLabelableObject, labelIDs) 1868 // THEN 1869 require.NoError(t, err) 1870 assert.Equal(t, expected, actual) 1871 }) 1872 1873 t.Run("Success - Label for Runtime Context", func(t *testing.T) { 1874 // GIVEN 1875 rtCtx1Id := "rtm-ctx-1" 1876 rtCtx2Id := "rtm-ctx-2" 1877 1878 label1Model := fixModelLabelWithRefID("1", "foo", model.RuntimeContextLabelableObject, rtCtx1Id) 1879 label2Model := fixModelLabelWithRefID("2", "bar", model.RuntimeContextLabelableObject, rtCtx2Id) 1880 1881 label1Entity := fixEntityLabelWithRefID("1", "foo", model.RuntimeContextLabelableObject, rtCtx1Id) 1882 label2Entity := fixEntityLabelWithRefID("2", "bar", model.RuntimeContextLabelableObject, rtCtx2Id) 1883 1884 inputItems := []*label.Entity{label1Entity, label2Entity} 1885 outputItems := []*model.Label{label1Model, label2Model} 1886 expected := map[string]map[string]interface{}{ 1887 rtCtx1Id: { 1888 label1Model.Key: label1Model.Value, 1889 }, 1890 rtCtx2Id: { 1891 label2Model.Key: label2Model.Value, 1892 }, 1893 } 1894 1895 mockConverter := &automock.Converter{} 1896 defer mockConverter.AssertExpectations(t) 1897 for i, entity := range inputItems { 1898 mockConverter.On("FromEntity", entity).Return(outputItems[i], nil).Once() 1899 } 1900 1901 labelRepo := label.NewRepository(mockConverter) 1902 1903 db, dbMock := testdb.MockDatabase(t) 1904 defer dbMock.AssertExpectations(t) 1905 1906 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE runtime_context_id IN ($1, $2) AND (id IN (SELECT id FROM runtime_contexts_labels_tenants WHERE tenant_id = $3))`) 1907 mockedRows := sqlmock.NewRows(fixColumns). 1908 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 1909 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 1910 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: labelIDs[0]}, sql.NullString{Valid: true, String: labelIDs[1]}, tenantID).WillReturnRows(mockedRows) 1911 1912 ctx := context.TODO() 1913 ctx = persistence.SaveToContext(ctx, db) 1914 // WHEN 1915 actual, err := labelRepo.ListForObjectIDs(ctx, tenantID, model.RuntimeContextLabelableObject, labelIDs) 1916 // THEN 1917 require.NoError(t, err) 1918 assert.Equal(t, expected, actual) 1919 }) 1920 1921 t.Run("Success - Label for Application", func(t *testing.T) { 1922 // GIVEN 1923 app1Id := "app-1" 1924 app2Id := "app-2" 1925 1926 label1Model := fixModelLabelWithRefID("1", "foo", model.ApplicationLabelableObject, app1Id) 1927 label2Model := fixModelLabelWithRefID("2", "bar", model.ApplicationLabelableObject, app2Id) 1928 1929 label1Entity := fixEntityLabelWithRefID("1", "foo", model.ApplicationLabelableObject, app1Id) 1930 label2Entity := fixEntityLabelWithRefID("2", "bar", model.ApplicationLabelableObject, app2Id) 1931 1932 inputItems := []*label.Entity{label1Entity, label2Entity} 1933 outputItems := []*model.Label{label1Model, label2Model} 1934 expected := map[string]map[string]interface{}{ 1935 app1Id: { 1936 label1Model.Key: label1Model.Value, 1937 }, 1938 app2Id: { 1939 label2Model.Key: label2Model.Value, 1940 }, 1941 } 1942 1943 mockConverter := &automock.Converter{} 1944 defer mockConverter.AssertExpectations(t) 1945 for i, entity := range inputItems { 1946 mockConverter.On("FromEntity", entity).Return(outputItems[i], nil).Once() 1947 } 1948 1949 labelRepo := label.NewRepository(mockConverter) 1950 1951 db, dbMock := testdb.MockDatabase(t) 1952 defer dbMock.AssertExpectations(t) 1953 1954 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE app_id IN ($1, $2) AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $3))`) 1955 mockedRows := sqlmock.NewRows(fixColumns). 1956 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 1957 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label1Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 1958 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: labelIDs[0]}, sql.NullString{Valid: true, String: labelIDs[1]}, tenantID).WillReturnRows(mockedRows) 1959 1960 ctx := context.TODO() 1961 ctx = persistence.SaveToContext(ctx, db) 1962 1963 // WHEN 1964 actual, err := labelRepo.ListForObjectIDs(ctx, tenantID, model.ApplicationLabelableObject, labelIDs) 1965 // THEN 1966 require.NoError(t, err) 1967 assert.Equal(t, expected, actual) 1968 }) 1969 1970 t.Run("Success - Label for Tenant", func(t *testing.T) { 1971 // GIVEN 1972 tenant1Id := "tenant-1" 1973 tenant2Id := "tenant-2" 1974 1975 label1Model := fixModelLabelWithRefID("1", "foo", model.TenantLabelableObject, tenant1Id) 1976 label2Model := fixModelLabelWithRefID("2", "bar", model.TenantLabelableObject, tenant2Id) 1977 1978 label1Entity := fixEntityLabelWithRefID("1", "foo", model.TenantLabelableObject, tenant1Id) 1979 label2Entity := fixEntityLabelWithRefID("2", "bar", model.TenantLabelableObject, tenant2Id) 1980 1981 inputItems := []*label.Entity{label1Entity, label2Entity} 1982 outputItems := []*model.Label{label1Model, label2Model} 1983 expected := map[string]map[string]interface{}{ 1984 tenant1Id: { 1985 label1Model.Key: label1Model.Value, 1986 }, 1987 tenant2Id: { 1988 label2Model.Key: label2Model.Value, 1989 }, 1990 } 1991 1992 mockConverter := &automock.Converter{} 1993 defer mockConverter.AssertExpectations(t) 1994 for i, entity := range inputItems { 1995 mockConverter.On("FromEntity", entity).Return(outputItems[i], nil).Once() 1996 } 1997 1998 labelRepo := label.NewRepository(mockConverter) 1999 2000 db, dbMock := testdb.MockDatabase(t) 2001 defer dbMock.AssertExpectations(t) 2002 2003 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE tenant_id = $1 AND tenant_id IN ($2, $3) AND app_id IS NULL AND runtime_context_id IS NULL AND runtime_id IS NULL`) 2004 mockedRows := sqlmock.NewRows(fixColumns). 2005 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 2006 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 2007 dbMock.ExpectQuery(escapedQuery).WithArgs(tenantID, sql.NullString{Valid: true, String: labelIDs[0]}, sql.NullString{Valid: true, String: labelIDs[1]}).WillReturnRows(mockedRows) 2008 2009 ctx := context.TODO() 2010 ctx = persistence.SaveToContext(ctx, db) 2011 2012 // WHEN 2013 actual, err := labelRepo.ListForObjectIDs(ctx, tenantID, model.TenantLabelableObject, labelIDs) 2014 // THEN 2015 require.NoError(t, err) 2016 assert.Equal(t, expected, actual) 2017 }) 2018 2019 t.Run("Success - Label for Application Template", func(t *testing.T) { 2020 // GIVEN 2021 tenant1Id := "tenant-1" 2022 tenant2Id := "tenant-2" 2023 2024 label1Model := fixModelLabelWithRefID("1", "foo", model.AppTemplateLabelableObject, tenant1Id) 2025 label2Model := fixModelLabelWithRefID("2", "bar", model.AppTemplateLabelableObject, tenant2Id) 2026 2027 label1Entity := fixEntityLabelWithRefID("1", "foo", model.AppTemplateLabelableObject, tenant1Id) 2028 label2Entity := fixEntityLabelWithRefID("2", "bar", model.AppTemplateLabelableObject, tenant2Id) 2029 2030 inputItems := []*label.Entity{label1Entity, label2Entity} 2031 outputItems := []*model.Label{label1Model, label2Model} 2032 expected := map[string]map[string]interface{}{ 2033 tenant1Id: { 2034 label1Model.Key: label1Model.Value, 2035 }, 2036 tenant2Id: { 2037 label2Model.Key: label2Model.Value, 2038 }, 2039 } 2040 2041 mockConverter := &automock.Converter{} 2042 defer mockConverter.AssertExpectations(t) 2043 for i, entity := range inputItems { 2044 mockConverter.On("FromEntity", entity).Return(outputItems[i], nil).Once() 2045 } 2046 2047 labelRepo := label.NewRepository(mockConverter) 2048 2049 db, dbMock := testdb.MockDatabase(t) 2050 defer dbMock.AssertExpectations(t) 2051 2052 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE app_template_id IN ($1, $2)`) 2053 mockedRows := sqlmock.NewRows(fixColumns). 2054 AddRow(label1Entity.ID, label1Entity.TenantID, label1Entity.AppID, label1Entity.RuntimeID, label1Entity.RuntimeContextID, label1Entity.AppTemplateID, label1Entity.Key, label1Entity.Value, label1Entity.Version). 2055 AddRow(label2Entity.ID, label2Entity.TenantID, label2Entity.AppID, label2Entity.RuntimeID, label2Entity.RuntimeContextID, label2Entity.AppTemplateID, label2Entity.Key, label2Entity.Value, label2Entity.Version) 2056 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: labelIDs[0]}, sql.NullString{Valid: true, String: labelIDs[1]}).WillReturnRows(mockedRows) 2057 2058 ctx := context.TODO() 2059 ctx = persistence.SaveToContext(ctx, db) 2060 2061 // WHEN 2062 actual, err := labelRepo.ListForObjectIDs(ctx, tenantID, model.AppTemplateLabelableObject, labelIDs) 2063 // THEN 2064 require.NoError(t, err) 2065 assert.Equal(t, expected, actual) 2066 }) 2067 2068 t.Run("Error - Doesn't exist", func(t *testing.T) { 2069 mockConverter := &automock.Converter{} 2070 defer mockConverter.AssertExpectations(t) 2071 2072 labelRepo := label.NewRepository(mockConverter) 2073 2074 db, dbMock := testdb.MockDatabase(t) 2075 defer dbMock.AssertExpectations(t) 2076 2077 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE app_id IN ($1, $2) AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $3))`) 2078 mockedRows := sqlmock.NewRows(fixColumns) 2079 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: labelIDs[0]}, sql.NullString{Valid: true, String: labelIDs[1]}, tenantID).WillReturnRows(mockedRows) 2080 2081 ctx := context.TODO() 2082 ctx = persistence.SaveToContext(ctx, db) 2083 // WHEN 2084 actual, err := labelRepo.ListForObjectIDs(ctx, tenantID, model.ApplicationLabelableObject, labelIDs) 2085 // THEN 2086 require.NoError(t, err) 2087 assert.Empty(t, actual) 2088 }) 2089 2090 t.Run("Error - Select error", func(t *testing.T) { 2091 labelRepo := label.NewRepository(nil) 2092 db, dbMock := testdb.MockDatabase(t) 2093 defer dbMock.AssertExpectations(t) 2094 2095 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE app_id IN ($1, $2) AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $3))`) 2096 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: labelIDs[0]}, sql.NullString{Valid: true, String: labelIDs[1]}, tenantID).WillReturnError(errors.New("persistence error")) 2097 2098 ctx := context.TODO() 2099 ctx = persistence.SaveToContext(ctx, db) 2100 // WHEN 2101 _, err := labelRepo.ListForObjectIDs(ctx, tenantID, model.ApplicationLabelableObject, labelIDs) 2102 // THEN 2103 require.Error(t, err) 2104 require.Contains(t, err.Error(), "Unexpected error while executing SQL query") 2105 }) 2106 2107 t.Run("Error - Select error on global lister", func(t *testing.T) { 2108 labelRepo := label.NewRepository(nil) 2109 db, dbMock := testdb.MockDatabase(t) 2110 defer dbMock.AssertExpectations(t) 2111 2112 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE app_template_id IN ($1, $2)`) 2113 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: labelIDs[0]}, sql.NullString{Valid: true, String: labelIDs[1]}).WillReturnError(errors.New("persistence error")) 2114 2115 ctx := context.TODO() 2116 ctx = persistence.SaveToContext(ctx, db) 2117 // WHEN 2118 _, err := labelRepo.ListForObjectIDs(ctx, tenantID, model.AppTemplateLabelableObject, labelIDs) 2119 // THEN 2120 require.Error(t, err) 2121 require.Contains(t, err.Error(), "Unexpected error while executing SQL query") 2122 }) 2123 2124 t.Run("Error - While converting to model", func(t *testing.T) { 2125 // GIVEN 2126 app1Id := "app-1" 2127 2128 inputItem := fixEntityLabelWithRefID("1", "foo", model.ApplicationLabelableObject, app1Id) 2129 expectedErr := errors.New("converting error") 2130 2131 mockConverter := &automock.Converter{} 2132 defer mockConverter.AssertExpectations(t) 2133 mockConverter.On("FromEntity", inputItem).Return(nil, expectedErr).Once() 2134 2135 labelRepo := label.NewRepository(mockConverter) 2136 2137 db, dbMock := testdb.MockDatabase(t) 2138 defer dbMock.AssertExpectations(t) 2139 2140 escapedQuery := regexp.QuoteMeta(`SELECT id, tenant_id, app_id, runtime_id, runtime_context_id, app_template_id, key, value, version FROM public.labels WHERE app_id IN ($1, $2) AND (id IN (SELECT id FROM application_labels_tenants WHERE tenant_id = $3))`) 2141 mockedRows := sqlmock.NewRows(fixColumns). 2142 AddRow(inputItem.ID, inputItem.TenantID, inputItem.AppID, inputItem.RuntimeID, inputItem.RuntimeContextID, inputItem.AppTemplateID, inputItem.Key, inputItem.Value, inputItem.Version) 2143 dbMock.ExpectQuery(escapedQuery).WithArgs(sql.NullString{Valid: true, String: labelIDs[0]}, sql.NullString{Valid: true, String: labelIDs[1]}, tenantID).WillReturnRows(mockedRows) 2144 2145 ctx := context.TODO() 2146 ctx = persistence.SaveToContext(ctx, db) 2147 2148 // WHEN 2149 _, err := labelRepo.ListForObjectIDs(ctx, tenantID, model.ApplicationLabelableObject, labelIDs) 2150 // THEN 2151 require.Error(t, err) 2152 require.Contains(t, err.Error(), expectedErr.Error()) 2153 }) 2154 2155 t.Run("Error - Missing persistence", func(t *testing.T) { 2156 // GIVEN 2157 labelRepo := label.NewRepository(nil) 2158 2159 // WHEN 2160 _, err := labelRepo.ListForObjectIDs(context.TODO(), tenantID, model.ApplicationLabelableObject, labelIDs) 2161 // THEN 2162 require.Error(t, err) 2163 require.Contains(t, err.Error(), "unable to fetch database from context") 2164 }) 2165 2166 t.Run("Returns nil when given no object IDs", func(t *testing.T) { 2167 // GIVEN 2168 labelRepo := label.NewRepository(nil) 2169 2170 // WHEN 2171 actual, err := labelRepo.ListForObjectIDs(context.TODO(), tenantID, model.ApplicationLabelableObject, []string{}) 2172 // THEN 2173 require.NoError(t, err) 2174 require.Nil(t, actual) 2175 }) 2176 }