github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/labeldef/repository_test.go (about) 1 package labeldef_test 2 3 import ( 4 "context" 5 "database/sql" 6 "errors" 7 "reflect" 8 "regexp" 9 "testing" 10 11 "github.com/kyma-incubator/compass/components/director/internal/repo/testdb" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/mock" 15 16 "github.com/DATA-DOG/go-sqlmock" 17 "github.com/kyma-incubator/compass/components/director/internal/domain/labeldef" 18 "github.com/kyma-incubator/compass/components/director/internal/domain/labeldef/automock" 19 "github.com/kyma-incubator/compass/components/director/internal/model" 20 "github.com/kyma-incubator/compass/components/director/pkg/persistence" 21 "github.com/stretchr/testify/require" 22 ) 23 24 func TestRepositoryCreateLabelDefinition(t *testing.T) { 25 // GIVEN 26 labelDefID := "d048f47b-b700-49ed-913d-180c3748164b" 27 tenantID := "003a0855-4eb0-486d-8fc6-3ab2f2312ca0" 28 someString := "any" 29 version := 42 30 var someSchema interface{} = someString 31 32 in := model.LabelDefinition{ 33 ID: labelDefID, 34 Tenant: tenantID, 35 Key: "some-key", 36 Schema: &someSchema, 37 Version: version, 38 } 39 40 t.Run("successfully created definition with schema", func(t *testing.T) { 41 db, dbMock := testdb.MockDatabase(t) 42 ctx := context.TODO() 43 ctx = persistence.SaveToContext(ctx, db) 44 mockConverter := &automock.EntityConverter{} 45 defer mockConverter.AssertExpectations(t) 46 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{String: "any", Valid: true}, Version: version}, nil) 47 escapedQuery := regexp.QuoteMeta("INSERT INTO public.label_definitions ( id, tenant_id, key, schema, version ) VALUES ( ?, ?, ?, ?, ? )") 48 dbMock.ExpectExec(escapedQuery).WithArgs(labelDefID, tenantID, "some-key", "any", version).WillReturnResult(sqlmock.NewResult(1, 1)) 49 50 defer dbMock.AssertExpectations(t) 51 sut := labeldef.NewRepository(mockConverter) 52 // WHEN 53 err := sut.Create(ctx, in) 54 // THEN 55 require.NoError(t, err) 56 }) 57 58 t.Run("successfully created definition without schema", func(t *testing.T) { 59 db, dbMock := testdb.MockDatabase(t) 60 ctx := context.TODO() 61 ctx = persistence.SaveToContext(ctx, db) 62 mockConverter := &automock.EntityConverter{} 63 defer mockConverter.AssertExpectations(t) 64 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{}, Version: version}, nil) 65 escapedQuery := regexp.QuoteMeta("INSERT INTO public.label_definitions ( id, tenant_id, key, schema, version ) VALUES ( ?, ?, ?, ?, ? )") 66 dbMock.ExpectExec(escapedQuery).WithArgs(labelDefID, tenantID, "some-key", nil, version).WillReturnResult(sqlmock.NewResult(1, 1)) 67 defer dbMock.AssertExpectations(t) 68 sut := labeldef.NewRepository(mockConverter) 69 // WHEN 70 err := sut.Create(ctx, in) 71 // THEN 72 require.NoError(t, err) 73 }) 74 75 t.Run("returns error if insert fails", func(t *testing.T) { 76 mockConverter := &automock.EntityConverter{} 77 defer mockConverter.AssertExpectations(t) 78 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{String: "any", Valid: true}, Version: version}, nil) 79 80 sut := labeldef.NewRepository(mockConverter) 81 db, dbMock := testdb.MockDatabase(t) 82 ctx := context.TODO() 83 ctx = persistence.SaveToContext(ctx, db) 84 escapedQuery := regexp.QuoteMeta("INSERT INTO public.label_definitions ( id, tenant_id, key, schema, version ) VALUES ( ?, ?, ?, ?, ? )") 85 dbMock.ExpectExec(escapedQuery).WillReturnError(errors.New("some error")) 86 defer dbMock.AssertExpectations(t) 87 // WHEN 88 err := sut.Create(ctx, in) 89 // THEN 90 require.EqualError(t, err, "while inserting Label Definition: Internal Server Error: Unexpected error while executing SQL query") 91 }) 92 } 93 94 func TestRepositoryUpdateLabelDefinition(t *testing.T) { 95 // GIVEN 96 labelDefID := "d048f47b-b700-49ed-913d-180c3748164b" 97 tenantID := "003a0855-4eb0-486d-8fc6-3ab2f2312ca0" 98 someString := "any" 99 version := 42 100 var someSchema interface{} = someString 101 102 in := model.LabelDefinition{ 103 ID: labelDefID, 104 Tenant: tenantID, 105 Key: "some-key", 106 Schema: &someSchema, 107 } 108 109 t.Run("successfully updated definition with schema", func(t *testing.T) { 110 db, dbMock := testdb.MockDatabase(t) 111 112 ctx := context.TODO() 113 ctx = persistence.SaveToContext(ctx, db) 114 115 mockConverter := &automock.EntityConverter{} 116 defer mockConverter.AssertExpectations(t) 117 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{String: "any", Valid: true}, Version: version}, nil) 118 119 escapedQuery := regexp.QuoteMeta(`UPDATE public.label_definitions SET schema = ?, version = version+1 WHERE id = ? AND tenant_id = ?`) 120 dbMock.ExpectExec(escapedQuery).WithArgs("any", labelDefID, tenantID).WillReturnResult(sqlmock.NewResult(1, 1)) 121 defer dbMock.AssertExpectations(t) 122 123 sut := labeldef.NewRepository(mockConverter) 124 125 // WHEN 126 err := sut.Update(ctx, in) 127 // THEN 128 require.NoError(t, err) 129 }) 130 131 t.Run("successfully updated definition without schema", func(t *testing.T) { 132 db, dbMock := testdb.MockDatabase(t) 133 134 ctx := context.TODO() 135 ctx = persistence.SaveToContext(ctx, db) 136 137 mockConverter := &automock.EntityConverter{} 138 defer mockConverter.AssertExpectations(t) 139 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, Version: version}, nil) 140 141 escapedQuery := regexp.QuoteMeta(`UPDATE public.label_definitions SET schema = ?, version = version+1 WHERE id = ? AND tenant_id = ?`) 142 dbMock.ExpectExec(escapedQuery).WithArgs(nil, labelDefID, tenantID).WillReturnResult(sqlmock.NewResult(1, 1)) 143 defer dbMock.AssertExpectations(t) 144 145 sut := labeldef.NewRepository(mockConverter) 146 147 // WHEN 148 err := sut.Update(ctx, in) 149 // THEN 150 require.NoError(t, err) 151 }) 152 153 t.Run("returns error if update fails", func(t *testing.T) { 154 mockConverter := &automock.EntityConverter{} 155 defer mockConverter.AssertExpectations(t) 156 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{String: "any", Valid: true}, Version: version}, nil) 157 158 sut := labeldef.NewRepository(mockConverter) 159 db, dbMock := testdb.MockDatabase(t) 160 161 ctx := context.TODO() 162 ctx = persistence.SaveToContext(ctx, db) 163 164 escapedQuery := regexp.QuoteMeta(`UPDATE public.label_definitions SET schema = ?, version = version+1 WHERE id = ? AND tenant_id = ?`) 165 dbMock.ExpectExec(escapedQuery).WillReturnError(errors.New("some error")) 166 defer dbMock.AssertExpectations(t) 167 168 // WHEN 169 err := sut.Update(ctx, in) 170 // THEN 171 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 172 }) 173 174 t.Run("returns error if update fails", func(t *testing.T) { 175 mockConverter := &automock.EntityConverter{} 176 defer mockConverter.AssertExpectations(t) 177 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{String: "any", Valid: true}, Version: version}, nil) 178 179 sut := labeldef.NewRepository(mockConverter) 180 db, dbMock := testdb.MockDatabase(t) 181 182 ctx := context.TODO() 183 ctx = persistence.SaveToContext(ctx, db) 184 185 escapedQuery := regexp.QuoteMeta(`UPDATE public.label_definitions SET schema = ?, version = version+1 WHERE id = ? AND tenant_id = ?`) 186 dbMock.ExpectExec(escapedQuery).WillReturnError(errors.New("some error")) 187 defer dbMock.AssertExpectations(t) 188 189 // WHEN 190 err := sut.Update(ctx, in) 191 // THEN 192 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 193 }) 194 195 t.Run("returns error if no row was affected by query", func(t *testing.T) { 196 db, dbMock := testdb.MockDatabase(t) 197 198 ctx := context.TODO() 199 ctx = persistence.SaveToContext(ctx, db) 200 201 mockConverter := &automock.EntityConverter{} 202 defer mockConverter.AssertExpectations(t) 203 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{String: "any", Valid: true}, Version: version}, nil) 204 205 escapedQuery := regexp.QuoteMeta(`UPDATE public.label_definitions SET schema = ?, version = version+1 WHERE id = ? AND tenant_id = ?`) 206 dbMock.ExpectExec(escapedQuery).WithArgs("any", labelDefID, tenantID).WillReturnResult(sqlmock.NewResult(1, 0)) 207 defer dbMock.AssertExpectations(t) 208 209 sut := labeldef.NewRepository(mockConverter) 210 211 // WHEN 212 err := sut.Update(ctx, in) 213 // THEN 214 require.EqualError(t, err, "Could not update object due to concurrent update") 215 }) 216 } 217 218 func TestRepositoryUpdateLabelDefinitionWithVersion(t *testing.T) { 219 // GIVEN 220 labelDefID := "d048f47b-b700-49ed-913d-180c3748164b" 221 tenantID := "003a0855-4eb0-486d-8fc6-3ab2f2312ca0" 222 someString := "any" 223 version := 42 224 var someSchema interface{} = someString 225 226 in := model.LabelDefinition{ 227 ID: labelDefID, 228 Tenant: tenantID, 229 Key: "some-key", 230 Schema: &someSchema, 231 } 232 233 t.Run("successfully updated definition with schema", func(t *testing.T) { 234 db, dbMock := testdb.MockDatabase(t) 235 236 ctx := context.TODO() 237 ctx = persistence.SaveToContext(ctx, db) 238 239 mockConverter := &automock.EntityConverter{} 240 defer mockConverter.AssertExpectations(t) 241 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{String: "any", Valid: true}, Version: version}, nil) 242 243 escapedQuery := regexp.QuoteMeta(`UPDATE public.label_definitions SET schema = ?, version = version+1 WHERE id = ? AND version = ? AND tenant_id = ?`) 244 dbMock.ExpectExec(escapedQuery).WithArgs("any", labelDefID, version, tenantID).WillReturnResult(sqlmock.NewResult(1, 1)) 245 defer dbMock.AssertExpectations(t) 246 247 sut := labeldef.NewRepository(mockConverter) 248 249 // WHEN 250 err := sut.UpdateWithVersion(ctx, in) 251 // THEN 252 require.NoError(t, err) 253 }) 254 255 t.Run("successfully updated definition without schema", func(t *testing.T) { 256 db, dbMock := testdb.MockDatabase(t) 257 258 ctx := context.TODO() 259 ctx = persistence.SaveToContext(ctx, db) 260 261 mockConverter := &automock.EntityConverter{} 262 defer mockConverter.AssertExpectations(t) 263 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, Version: version}, nil) 264 265 escapedQuery := regexp.QuoteMeta(`UPDATE public.label_definitions SET schema = ?, version = version+1 WHERE id = ? AND version = ? AND tenant_id = ?`) 266 dbMock.ExpectExec(escapedQuery).WithArgs(nil, labelDefID, version, tenantID).WillReturnResult(sqlmock.NewResult(1, 1)) 267 defer dbMock.AssertExpectations(t) 268 269 sut := labeldef.NewRepository(mockConverter) 270 271 // WHEN 272 err := sut.UpdateWithVersion(ctx, in) 273 // THEN 274 require.NoError(t, err) 275 }) 276 277 t.Run("returns error if update fails", func(t *testing.T) { 278 mockConverter := &automock.EntityConverter{} 279 defer mockConverter.AssertExpectations(t) 280 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{String: "any", Valid: true}, Version: version}, nil) 281 282 sut := labeldef.NewRepository(mockConverter) 283 db, dbMock := testdb.MockDatabase(t) 284 285 ctx := context.TODO() 286 ctx = persistence.SaveToContext(ctx, db) 287 288 escapedQuery := regexp.QuoteMeta(`UPDATE public.label_definitions SET schema = ?, version = version+1 WHERE id = ? AND version = ? AND tenant_id = ?`) 289 dbMock.ExpectExec(escapedQuery).WillReturnError(errors.New("some error")) 290 defer dbMock.AssertExpectations(t) 291 292 // WHEN 293 err := sut.UpdateWithVersion(ctx, in) 294 // THEN 295 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 296 }) 297 298 t.Run("returns error if no row was affected by query", func(t *testing.T) { 299 db, dbMock := testdb.MockDatabase(t) 300 301 ctx := context.TODO() 302 ctx = persistence.SaveToContext(ctx, db) 303 304 mockConverter := &automock.EntityConverter{} 305 defer mockConverter.AssertExpectations(t) 306 mockConverter.On("ToEntity", in).Return(labeldef.Entity{ID: labelDefID, Key: "some-key", TenantID: tenantID, SchemaJSON: sql.NullString{String: "any", Valid: true}, Version: version}, nil) 307 308 escapedQuery := regexp.QuoteMeta(`UPDATE public.label_definitions SET schema = ?, version = version+1 WHERE id = ? AND version = ? AND tenant_id = ?`) 309 dbMock.ExpectExec(escapedQuery).WithArgs("any", labelDefID, version, tenantID).WillReturnResult(sqlmock.NewResult(1, 0)) 310 defer dbMock.AssertExpectations(t) 311 312 sut := labeldef.NewRepository(mockConverter) 313 314 // WHEN 315 err := sut.UpdateWithVersion(ctx, in) 316 // THEN 317 require.EqualError(t, err, "Could not update object due to concurrent update") 318 }) 319 } 320 321 func TestRepositoryGetByKey(t *testing.T) { 322 t.Run("returns LabelDefinition", func(t *testing.T) { 323 // GIVEN 324 mockConverter := &automock.EntityConverter{} 325 defer mockConverter.AssertExpectations(t) 326 327 var someSchema interface{} = ExampleSchema{Title: "title"} 328 mockConverter.On("FromEntity", 329 labeldef.Entity{ID: "id", TenantID: "tenant", Key: "key", SchemaJSON: sql.NullString{Valid: true, String: `{"title":"title"}`}}). 330 Return( 331 model.LabelDefinition{ 332 ID: "id", 333 Tenant: "tenant", 334 Key: "key", 335 Schema: &someSchema}, nil) 336 sut := labeldef.NewRepository(mockConverter) 337 338 db, dbMock := testdb.MockDatabase(t) 339 defer dbMock.AssertExpectations(t) 340 341 mockedRows := sqlmock.NewRows([]string{"id", "tenant_id", "key", "schema"}).AddRow("id", "tenant", "key", `{"title":"title"}`) 342 dbMock.ExpectQuery(`^SELECT (.+) FROM public.label_definitions WHERE tenant_id = \$1 AND key = \$2$`). 343 WithArgs("tenant", "key").WillReturnRows(mockedRows) 344 345 ctx := context.TODO() 346 ctx = persistence.SaveToContext(ctx, db) 347 // WHEN 348 actual, err := sut.GetByKey(ctx, "tenant", "key") 349 // THEN 350 require.NoError(t, err) 351 assert.Equal(t, "id", actual.ID) 352 assert.Equal(t, "tenant", actual.Tenant) 353 assert.Equal(t, "key", actual.Key) 354 assert.Equal(t, &someSchema, actual.Schema) 355 }) 356 t.Run("returns errorNotFound if LabelDefinition does not exist", func(t *testing.T) { 357 // GIVEN 358 db, dbMock := testdb.MockDatabase(t) 359 defer dbMock.AssertExpectations(t) 360 361 dbMock.ExpectQuery(`^SELECT (.+) FROM public.label_definitions WHERE tenant_id = \$1 AND key = \$2$`). 362 WithArgs("anything", "anything").WillReturnRows(sqlmock.NewRows([]string{"id", "tenant_id", "key", "schema"})) 363 ctx := context.TODO() 364 ctx = persistence.SaveToContext(ctx, db) 365 366 sut := labeldef.NewRepository(nil) 367 // WHEN 368 actual, err := sut.GetByKey(ctx, "anything", "anything") 369 // THEN 370 require.Error(t, err) 371 assert.Contains(t, err.Error(), "Object not found") 372 assert.Nil(t, actual) 373 }) 374 t.Run("returns error when conversion fails", func(t *testing.T) { 375 // GIVEN 376 mockConverter := &automock.EntityConverter{} 377 defer mockConverter.AssertExpectations(t) 378 mockConverter.On("FromEntity", mock.Anything).Return(model.LabelDefinition{}, errors.New("conversion error")) 379 sut := labeldef.NewRepository(mockConverter) 380 381 db, dbMock := testdb.MockDatabase(t) 382 defer dbMock.AssertExpectations(t) 383 384 mockedRows := sqlmock.NewRows([]string{"id", "tenant_id", "key", "schema"}).AddRow("id", "tenant", "key", `{"title":"title"}`) 385 dbMock.ExpectQuery(`^SELECT (.+) FROM public.label_definitions WHERE tenant_id = \$1 AND key = \$2$`). 386 WithArgs("tenant", "key").WillReturnRows(mockedRows) 387 388 ctx := context.TODO() 389 ctx = persistence.SaveToContext(ctx, db) 390 // WHEN 391 _, err := sut.GetByKey(ctx, "tenant", "key") 392 // THEN 393 require.EqualError(t, err, "while converting Label Definition: conversion error") 394 }) 395 t.Run("returns error if select fails", func(t *testing.T) { 396 // GIVEN 397 sut := labeldef.NewRepository(nil) 398 db, dbMock := testdb.MockDatabase(t) 399 defer dbMock.AssertExpectations(t) 400 401 dbMock.ExpectQuery(`^SELECT (.+) FROM public.label_definitions WHERE tenant_id = \$1 AND key = \$2$`). 402 WithArgs("tenant", "key").WillReturnError(errors.New("persistence error")) 403 404 ctx := context.TODO() 405 ctx = persistence.SaveToContext(ctx, db) 406 // WHEN 407 _, err := sut.GetByKey(ctx, "tenant", "key") 408 // THEN 409 require.EqualError(t, err, "while getting Label Definition by key=key: Internal Server Error: Unexpected error while executing SQL query") 410 }) 411 } 412 413 func TestRepositoryList(t *testing.T) { 414 t.Run("returns list of Label Definitions", func(t *testing.T) { 415 // GIVEN 416 mockConverter := &automock.EntityConverter{} 417 defer mockConverter.AssertExpectations(t) 418 419 mockConverter.On("FromEntity", 420 labeldef.Entity{ID: "id1", TenantID: "tenant", Key: "key1", Version: 0}). 421 Return( 422 model.LabelDefinition{ 423 ID: "id1", 424 Tenant: "tenant", 425 Key: "key1", 426 Version: 0, 427 }, nil) 428 mockConverter.On("FromEntity", 429 labeldef.Entity{ID: "id2", TenantID: "tenant", Key: "key2", SchemaJSON: sql.NullString{Valid: true, String: `{"title":"title"}`}, Version: 0}). 430 Return( 431 model.LabelDefinition{ 432 ID: "id2", 433 Tenant: "tenant", 434 Key: "key2", 435 Version: 0, 436 }, nil) 437 sut := labeldef.NewRepository(mockConverter) 438 439 db, dbMock := testdb.MockDatabase(t) 440 defer dbMock.AssertExpectations(t) 441 442 mockedRows := sqlmock.NewRows([]string{"id", "tenant_id", "key", "schema", "version"}). 443 AddRow("id1", "tenant", "key1", nil, 0). 444 AddRow("id2", "tenant", "key2", `{"title":"title"}`, 0) 445 446 dbMock.ExpectQuery(`^SELECT (.+) FROM public.label_definitions WHERE tenant_id = \$1$`).WithArgs("tenant").WillReturnRows(mockedRows) 447 448 ctx := context.TODO() 449 ctx = persistence.SaveToContext(ctx, db) 450 // WHEN 451 actual, err := sut.List(ctx, "tenant") 452 // THEN 453 require.NoError(t, err) 454 require.Len(t, actual, 2) 455 assert.Equal(t, "id1", actual[0].ID) 456 assert.Equal(t, "key1", actual[0].Key) 457 assert.Equal(t, 0, actual[0].Version) 458 assert.Equal(t, "id2", actual[1].ID) 459 assert.Equal(t, "key2", actual[1].Key) 460 assert.Equal(t, 0, actual[1].Version) 461 }) 462 t.Run("returns empty list of Label Definitions if given tenant has nothing defined", func(t *testing.T) { 463 // GIVEN 464 sut := labeldef.NewRepository(nil) 465 466 db, dbMock := testdb.MockDatabase(t) 467 defer dbMock.AssertExpectations(t) 468 469 mockedRows := sqlmock.NewRows([]string{"id", "tenant_id", "key", "schema", "version"}) 470 471 dbMock.ExpectQuery(`^SELECT (.+) FROM public.label_definitions WHERE tenant_id = \$1$`).WithArgs("tenant").WillReturnRows(mockedRows) 472 473 ctx := context.TODO() 474 ctx = persistence.SaveToContext(ctx, db) 475 // WHEN 476 actual, err := sut.List(ctx, "tenant") 477 // THEN 478 require.NoError(t, err) 479 require.Empty(t, actual) 480 }) 481 482 t.Run("returns error when conversion fails", func(t *testing.T) { 483 // GIVEN 484 mockConverter := &automock.EntityConverter{} 485 defer mockConverter.AssertExpectations(t) 486 487 mockConverter.On("FromEntity", 488 labeldef.Entity{ID: "id1", TenantID: "tenant", Key: "key1", Version: 0}). 489 Return( 490 model.LabelDefinition{}, errors.New("conversion error")) 491 492 sut := labeldef.NewRepository(mockConverter) 493 494 db, dbMock := testdb.MockDatabase(t) 495 defer dbMock.AssertExpectations(t) 496 497 mockedRows := sqlmock.NewRows([]string{"id", "tenant_id", "key", "schema", "version"}). 498 AddRow("id1", "tenant", "key1", nil, 0). 499 AddRow("id2", "tenant", "key2", `{"title":"title"}`, 0) 500 501 dbMock.ExpectQuery(`^SELECT (.+) FROM public.label_definitions WHERE tenant_id = \$1$`).WithArgs("tenant").WillReturnRows(mockedRows) 502 503 ctx := context.TODO() 504 ctx = persistence.SaveToContext(ctx, db) 505 // WHEN 506 _, err := sut.List(ctx, "tenant") 507 // THEN 508 require.EqualError(t, err, "while converting Label Definition [key=key1]: conversion error") 509 }) 510 t.Run("returns error if if select fails", func(t *testing.T) { 511 // GIVEN 512 sut := labeldef.NewRepository(nil) 513 514 db, dbMock := testdb.MockDatabase(t) 515 defer dbMock.AssertExpectations(t) 516 517 dbMock.ExpectQuery(`^SELECT (.+) FROM public.label_definitions WHERE tenant_id = \$1$`). 518 WithArgs("tenant").WillReturnError(errors.New("db error")) 519 520 ctx := context.TODO() 521 ctx = persistence.SaveToContext(ctx, db) 522 // WHEN 523 _, err := sut.List(ctx, "tenant") 524 // THEN 525 require.EqualError(t, err, "while listing Label Definitions: Internal Server Error: Unexpected error while executing SQL query") 526 }) 527 } 528 529 func TestRepositoryLabelDefExists(t *testing.T) { 530 t.Run("returns true", func(t *testing.T) { 531 // GIVEN 532 sut := labeldef.NewRepository(nil) 533 db, dbMock := testdb.MockDatabase(t) 534 defer dbMock.AssertExpectations(t) 535 536 escapedQuery := regexp.QuoteMeta("SELECT 1 FROM public.label_definitions WHERE tenant_id = $1 AND key = $2") 537 dbMock.ExpectQuery(escapedQuery).WithArgs("tenant", "key").WillReturnRows(sqlmock.NewRows([]string{"exists"}).AddRow("1")) 538 539 ctx := context.TODO() 540 ctx = persistence.SaveToContext(ctx, db) 541 // WHEN 542 actual, err := sut.Exists(ctx, "tenant", "key") 543 // THEN 544 require.NoError(t, err) 545 assert.True(t, actual) 546 }) 547 548 t.Run("returns false", func(t *testing.T) { 549 // GIVEN 550 db, dbMock := testdb.MockDatabase(t) 551 defer dbMock.AssertExpectations(t) 552 553 escapedQuery := regexp.QuoteMeta("SELECT 1 FROM public.label_definitions WHERE tenant_id = $1 AND key = $2") 554 dbMock.ExpectQuery(escapedQuery).WithArgs("anything", "anything").WillReturnRows(sqlmock.NewRows([]string{"exists"})) 555 ctx := context.TODO() 556 ctx = persistence.SaveToContext(ctx, db) 557 558 sut := labeldef.NewRepository(nil) 559 // WHEN 560 actual, err := sut.Exists(ctx, "anything", "anything") 561 // THEN 562 require.NoError(t, err) 563 assert.False(t, actual) 564 }) 565 t.Run("returns error if select fails", func(t *testing.T) { 566 // GIVEN 567 sut := labeldef.NewRepository(nil) 568 db, dbMock := testdb.MockDatabase(t) 569 defer dbMock.AssertExpectations(t) 570 571 escapedQuery := regexp.QuoteMeta("SELECT 1 FROM public.label_definitions WHERE tenant_id = $1 AND key = $2") 572 dbMock.ExpectQuery(escapedQuery).WithArgs("tenant", "key").WillReturnError(errors.New("persistence error")) 573 574 ctx := context.TODO() 575 ctx = persistence.SaveToContext(ctx, db) 576 // WHEN 577 _, err := sut.Exists(ctx, "tenant", "key") 578 // THEN 579 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 580 }) 581 } 582 583 func TestRepository_DeleteByKey(t *testing.T) { 584 t.Run("Success", func(t *testing.T) { 585 // GIVEN 586 key := "test" 587 tnt := "tenant" 588 589 mockConverter := &automock.EntityConverter{} 590 defer mockConverter.AssertExpectations(t) 591 592 repo := labeldef.NewRepository(mockConverter) 593 594 db, dbMock := testdb.MockDatabase(t) 595 defer dbMock.AssertExpectations(t) 596 597 escapedQuery := regexp.QuoteMeta("DELETE FROM public.label_definitions WHERE tenant_id = $1 AND key = $2") 598 dbMock.ExpectExec(escapedQuery).WithArgs(tnt, key).WillReturnResult(sqlmock.NewResult(1, 1)) 599 600 ctx := context.TODO() 601 ctx = persistence.SaveToContext(ctx, db) 602 // WHEN 603 err := repo.DeleteByKey(ctx, tnt, key) 604 // THEN 605 require.NoError(t, err) 606 }) 607 608 t.Run("Error - Operation", func(t *testing.T) { 609 // GIVEN 610 key := "test" 611 tnt := "tenant" 612 testErr := errors.New("Test err") 613 614 mockConverter := &automock.EntityConverter{} 615 defer mockConverter.AssertExpectations(t) 616 617 repo := labeldef.NewRepository(mockConverter) 618 619 db, dbMock := testdb.MockDatabase(t) 620 defer dbMock.AssertExpectations(t) 621 622 escapedQuery := regexp.QuoteMeta("DELETE FROM public.label_definitions WHERE tenant_id = $1 AND key = $2") 623 dbMock.ExpectExec(escapedQuery).WithArgs(tnt, key).WillReturnError(testErr) 624 625 ctx := context.TODO() 626 ctx = persistence.SaveToContext(ctx, db) 627 // WHEN 628 err := repo.DeleteByKey(ctx, tnt, key) 629 // THEN 630 require.Error(t, err) 631 assert.Contains(t, err.Error(), "Internal Server Error: Unexpected error while executing SQL query") 632 }) 633 634 t.Run("Error - No rows affected", func(t *testing.T) { 635 // GIVEN 636 key := "test" 637 tnt := "tenant" 638 639 mockConverter := &automock.EntityConverter{} 640 defer mockConverter.AssertExpectations(t) 641 642 repo := labeldef.NewRepository(mockConverter) 643 644 db, dbMock := testdb.MockDatabase(t) 645 defer dbMock.AssertExpectations(t) 646 647 escapedQuery := regexp.QuoteMeta("DELETE FROM public.label_definitions WHERE tenant_id = $1 AND key = $2") 648 dbMock.ExpectExec(escapedQuery).WithArgs(tnt, key).WillReturnResult(sqlmock.NewResult(1, 0)) 649 650 ctx := context.TODO() 651 ctx = persistence.SaveToContext(ctx, db) 652 // WHEN 653 err := repo.DeleteByKey(ctx, tnt, key) 654 // THEN 655 require.EqualError(t, err, "Unauthorized [reason=Owner access is needed for resource modification]") 656 }) 657 } 658 659 func TestRepository_Upsert(t *testing.T) { 660 t.Run("Success - Label for Runtime", func(t *testing.T) { 661 // GIVEN 662 key := "test" 663 tnt := "tenant" 664 schema := "{}" 665 schemaInterface := reflect.ValueOf(schema).Interface() 666 version := 42 667 668 labeldefModel := model.LabelDefinition{ 669 ID: "foo", 670 Tenant: tnt, 671 Key: key, 672 Schema: &schemaInterface, 673 Version: version, 674 } 675 labeldefEntity := labeldef.Entity{ 676 ID: "foo", 677 TenantID: tnt, 678 Key: key, 679 SchemaJSON: sql.NullString{ 680 String: schema, 681 Valid: true, 682 }, 683 Version: version, 684 } 685 686 mockConverter := &automock.EntityConverter{} 687 mockConverter.On("ToEntity", labeldefModel).Return(labeldefEntity, nil).Once() 688 defer mockConverter.AssertExpectations(t) 689 690 labelRepo := labeldef.NewRepository(mockConverter) 691 692 db, dbMock := testdb.MockDatabase(t) 693 defer dbMock.AssertExpectations(t) 694 695 escapedQuery := regexp.QuoteMeta(`INSERT INTO public.label_definitions ( id, tenant_id, key, schema, version ) VALUES ( ?, ?, ?, ?, ? ) ON CONFLICT ( tenant_id, key ) DO UPDATE SET schema=EXCLUDED.schema WHERE public.label_definitions.tenant_id = ?`) 696 dbMock.ExpectExec(escapedQuery).WithArgs(labeldefEntity.ID, labeldefEntity.TenantID, labeldefEntity.Key, labeldefEntity.SchemaJSON, labeldefEntity.Version, labeldefEntity.TenantID).WillReturnResult(sqlmock.NewResult(1, 1)) 697 698 ctx := context.TODO() 699 ctx = persistence.SaveToContext(ctx, db) 700 // WHEN 701 err := labelRepo.Upsert(ctx, labeldefModel) 702 // THEN 703 require.NoError(t, err) 704 }) 705 706 t.Run("Error when entityConverting fails", func(t *testing.T) { 707 labeldefModel := model.LabelDefinition{} 708 labeldefEntity := labeldef.Entity{} 709 testErr := errors.New("test-err") 710 711 mockConverter := &automock.EntityConverter{} 712 mockConverter.On("ToEntity", labeldefModel).Return(labeldefEntity, testErr).Once() 713 defer mockConverter.AssertExpectations(t) 714 715 labelRepo := labeldef.NewRepository(mockConverter) 716 717 // WHEN 718 ctx := context.TODO() 719 err := labelRepo.Upsert(ctx, labeldefModel) 720 // THEN 721 require.Error(t, err) 722 require.Contains(t, err.Error(), testErr.Error()) 723 }) 724 }