github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/repo/list_test.go (about) 1 package repo_test 2 3 import ( 4 "context" 5 "database/sql/driver" 6 "fmt" 7 "regexp" 8 "testing" 9 "time" 10 11 "github.com/jmoiron/sqlx" 12 13 "github.com/DATA-DOG/go-sqlmock" 14 "github.com/kyma-incubator/compass/components/director/internal/repo" 15 "github.com/kyma-incubator/compass/components/director/internal/repo/testdb" 16 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 17 "github.com/kyma-incubator/compass/components/director/pkg/persistence" 18 "github.com/kyma-incubator/compass/components/director/pkg/resource" 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/require" 21 ) 22 23 func TestList(t *testing.T) { 24 sut := repo.NewLister(appTableName, appColumns) 25 resourceType := resource.Application 26 m2mTable, ok := resourceType.TenantAccessTable() 27 require.True(t, ok) 28 29 t.Run("lists all items successfully", func(t *testing.T) { 30 db, mock := testdb.MockDatabase(t) 31 ctx := mockListDBSelect(mock, m2mTable, db, repo.NoLock, false) 32 defer mock.AssertExpectations(t) 33 34 var dest AppCollection 35 err := sut.List(ctx, resourceType, tenantID, &dest) 36 require.NoError(t, err) 37 assert.Len(t, dest, 2) 38 assert.Contains(t, dest, *fixApp) 39 assert.Contains(t, dest, *fixApp2) 40 }) 41 42 t.Run("lists all items successfully with additional parameters", func(t *testing.T) { 43 db, mock := testdb.MockDatabase(t) 44 ctx := mockListDBSelectWithAdditionalParameters(mock, m2mTable, db, repo.NoLock, false) 45 defer mock.AssertExpectations(t) 46 47 var dest AppCollection 48 conditions := repo.Conditions{ 49 repo.NewEqualCondition("name", appName), 50 repo.NewNotEqualCondition("description", appDescription2), 51 } 52 53 err := sut.List(ctx, resourceType, tenantID, &dest, conditions...) 54 require.NoError(t, err) 55 assert.Len(t, dest, 1) 56 }) 57 58 t.Run("returns error if missing persistence context", func(t *testing.T) { 59 ctx := context.TODO() 60 err := sut.List(ctx, resourceType, tenantID, nil) 61 require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error()) 62 }) 63 64 t.Run("returns error if empty tenant", func(t *testing.T) { 65 ctx := context.TODO() 66 err := sut.List(ctx, resourceType, "", nil) 67 require.EqualError(t, err, apperrors.NewTenantRequiredError().Error()) 68 }) 69 70 t.Run("returns error on db operation", func(t *testing.T) { 71 db, mock := testdb.MockDatabase(t) 72 defer mock.AssertExpectations(t) 73 74 mock.ExpectQuery(`SELECT .*`).WillReturnError(someError()) 75 ctx := persistence.SaveToContext(context.TODO(), db) 76 var dest UserCollection 77 78 err := sut.List(ctx, resourceType, tenantID, &dest) 79 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 80 }) 81 82 t.Run("context properly canceled", func(t *testing.T) { 83 db, mock := testdb.MockDatabase(t) 84 defer mock.AssertExpectations(t) 85 86 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond) 87 defer cancel() 88 89 ctx = persistence.SaveToContext(ctx, db) 90 var dest UserCollection 91 err := sut.List(ctx, resourceType, tenantID, &dest) 92 require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached") 93 }) 94 95 t.Run("lists all items successfully with owner check", func(t *testing.T) { 96 ownerLister := repo.NewOwnerLister(appTableName, appColumns, true) 97 db, mock := testdb.MockDatabase(t) 98 ctx := mockListDBSelect(mock, m2mTable, db, repo.NoLock, true) 99 defer mock.AssertExpectations(t) 100 101 var dest AppCollection 102 err := ownerLister.List(ctx, resourceType, tenantID, &dest) 103 require.NoError(t, err) 104 assert.Len(t, dest, 2) 105 assert.Contains(t, dest, *fixApp) 106 assert.Contains(t, dest, *fixApp2) 107 }) 108 109 t.Run("lists all items successfully with additional parameters and owner check", func(t *testing.T) { 110 ownerLister := repo.NewOwnerLister(appTableName, appColumns, true) 111 db, mock := testdb.MockDatabase(t) 112 ctx := mockListDBSelectWithAdditionalParameters(mock, m2mTable, db, repo.NoLock, true) 113 defer mock.AssertExpectations(t) 114 115 var dest AppCollection 116 conditions := repo.Conditions{ 117 repo.NewEqualCondition("name", appName), 118 repo.NewNotEqualCondition("description", appDescription2), 119 } 120 121 err := ownerLister.List(ctx, resourceType, tenantID, &dest, conditions...) 122 require.NoError(t, err) 123 assert.Len(t, dest, 1) 124 }) 125 } 126 127 func TestListWithSelectForUpdate(t *testing.T) { 128 sut := repo.NewLister(appTableName, appColumns) 129 resourceType := resource.Application 130 m2mTable, ok := resourceType.TenantAccessTable() 131 require.True(t, ok) 132 133 t.Run("lists all items successfully", func(t *testing.T) { 134 db, mock := testdb.MockDatabase(t) 135 ctx := mockListDBSelect(mock, m2mTable, db, repo.ForUpdateLock, false) 136 defer mock.AssertExpectations(t) 137 138 var dest AppCollection 139 err := sut.ListWithSelectForUpdate(ctx, resourceType, tenantID, &dest) 140 require.NoError(t, err) 141 assert.Len(t, dest, 2) 142 assert.Contains(t, dest, *fixApp) 143 assert.Contains(t, dest, *fixApp2) 144 }) 145 146 t.Run("lists all items successfully with additional parameters", func(t *testing.T) { 147 db, mock := testdb.MockDatabase(t) 148 ctx := mockListDBSelectWithAdditionalParameters(mock, m2mTable, db, repo.ForUpdateLock, false) 149 defer mock.AssertExpectations(t) 150 151 var dest AppCollection 152 conditions := repo.Conditions{ 153 repo.NewEqualCondition("name", appName), 154 repo.NewNotEqualCondition("description", appDescription2), 155 } 156 157 err := sut.ListWithSelectForUpdate(ctx, resourceType, tenantID, &dest, conditions...) 158 require.NoError(t, err) 159 assert.Len(t, dest, 1) 160 }) 161 162 t.Run("returns error if missing persistence context", func(t *testing.T) { 163 ctx := context.TODO() 164 err := sut.ListWithSelectForUpdate(ctx, resourceType, tenantID, nil) 165 require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error()) 166 }) 167 168 t.Run("returns error if empty tenant", func(t *testing.T) { 169 ctx := context.TODO() 170 err := sut.ListWithSelectForUpdate(ctx, resourceType, "", nil) 171 require.EqualError(t, err, apperrors.NewTenantRequiredError().Error()) 172 }) 173 174 t.Run("returns error on db operation", func(t *testing.T) { 175 db, mock := testdb.MockDatabase(t) 176 defer mock.AssertExpectations(t) 177 178 mock.ExpectQuery(`SELECT .*`).WillReturnError(someError()) 179 ctx := persistence.SaveToContext(context.TODO(), db) 180 var dest UserCollection 181 182 err := sut.ListWithSelectForUpdate(ctx, resourceType, tenantID, &dest) 183 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 184 }) 185 186 t.Run("context properly canceled", func(t *testing.T) { 187 db, mock := testdb.MockDatabase(t) 188 defer mock.AssertExpectations(t) 189 190 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond) 191 defer cancel() 192 193 ctx = persistence.SaveToContext(ctx, db) 194 var dest UserCollection 195 err := sut.ListWithSelectForUpdate(ctx, resourceType, tenantID, &dest) 196 require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached") 197 }) 198 } 199 200 func mockListDBSelect(mock testdb.DBMock, m2mTable string, db *sqlx.DB, lockClause string, ownerCheck bool) context.Context { 201 rows := sqlmock.NewRows(appColumns). 202 AddRow(appID, appName, appDescription). 203 AddRow(appID2, appName2, appDescription2) 204 if ownerCheck { 205 mock.ExpectQuery(regexp.QuoteMeta(fmt.Sprintf("SELECT id, name, description FROM %s WHERE %s%s", appTableName, fmt.Sprintf(tenantIsolationConditionWithOwnerCheckFmt, m2mTable, "$1"), PrepareLockClause(lockClause)))). 206 WithArgs(tenantID).WillReturnRows(rows) 207 } else { 208 mock.ExpectQuery(regexp.QuoteMeta(fmt.Sprintf("SELECT id, name, description FROM %s WHERE %s%s", appTableName, fmt.Sprintf(tenantIsolationConditionWithoutOwnerCheckFmt, m2mTable, "$1"), PrepareLockClause(lockClause)))). 209 WithArgs(tenantID).WillReturnRows(rows) 210 } 211 ctx := persistence.SaveToContext(context.TODO(), db) 212 return ctx 213 } 214 215 func mockListDBSelectWithAdditionalParameters(mock testdb.DBMock, m2mTable string, db *sqlx.DB, lockClause string, ownerCheck bool) context.Context { 216 rows := sqlmock.NewRows(appColumns). 217 AddRow(appID, appName, appDescription) 218 if ownerCheck { 219 mock.ExpectQuery(regexp.QuoteMeta(fmt.Sprintf("SELECT id, name, description FROM %s WHERE name = $1 AND description != $2 AND %s%s", appTableName, fmt.Sprintf(tenantIsolationConditionWithOwnerCheckFmt, m2mTable, "$3"), PrepareLockClause(lockClause)))). 220 WithArgs(appName, appDescription2, tenantID).WillReturnRows(rows) 221 } else { 222 mock.ExpectQuery(regexp.QuoteMeta(fmt.Sprintf("SELECT id, name, description FROM %s WHERE name = $1 AND description != $2 AND %s%s", appTableName, fmt.Sprintf(tenantIsolationConditionWithoutOwnerCheckFmt, m2mTable, "$3"), PrepareLockClause(lockClause)))). 223 WithArgs(appName, appDescription2, tenantID).WillReturnRows(rows) 224 } 225 ctx := persistence.SaveToContext(context.TODO(), db) 226 return ctx 227 } 228 229 func TestListWithEmbeddedTenant(t *testing.T) { 230 peterID := "peterID" 231 homerID := "homerID" 232 peter := User{FirstName: "Peter", LastName: "Griffin", Age: 40, ID: peterID} 233 peterRow := []driver.Value{peterID, "Peter", "Griffin", 40} 234 homer := User{FirstName: "Homer", LastName: "Simpson", Age: 55, ID: homerID} 235 homerRow := []driver.Value{homerID, "Homer", "Simpson", 55} 236 237 sut := repo.NewListerWithEmbeddedTenant(userTableName, "tenant_id", []string{"id", "first_name", "last_name", "age"}) 238 239 t.Run("lists all items successfully", func(t *testing.T) { 240 db, mock := testdb.MockDatabase(t) 241 defer mock.AssertExpectations(t) 242 243 rows := sqlmock.NewRows([]string{"id", "first_name", "last_name", "age"}). 244 AddRow(peterRow...). 245 AddRow(homerRow...) 246 mock.ExpectQuery(regexp.QuoteMeta(`SELECT id, first_name, last_name, age FROM users WHERE tenant_id = $1`)). 247 WithArgs(tenantID).WillReturnRows(rows) 248 ctx := persistence.SaveToContext(context.TODO(), db) 249 var dest UserCollection 250 251 err := sut.List(ctx, UserType, tenantID, &dest) 252 require.NoError(t, err) 253 assert.Len(t, dest, 2) 254 assert.Contains(t, dest, peter) 255 assert.Contains(t, dest, homer) 256 }) 257 258 t.Run("lists all items successfully with additional parameters", func(t *testing.T) { 259 db, mock := testdb.MockDatabase(t) 260 defer mock.AssertExpectations(t) 261 262 rows := sqlmock.NewRows([]string{"id", "first_name", "last_name", "age"}). 263 AddRow(peterRow...) 264 mock.ExpectQuery(regexp.QuoteMeta("SELECT id, first_name, last_name, age FROM users WHERE tenant_id = $1 AND first_name = $2 AND age != $3")). 265 WithArgs(tenantID, "Peter", 18).WillReturnRows(rows) 266 ctx := persistence.SaveToContext(context.TODO(), db) 267 var dest UserCollection 268 269 conditions := repo.Conditions{ 270 repo.NewEqualCondition("first_name", "Peter"), 271 repo.NewNotEqualCondition("age", 18), 272 } 273 274 err := sut.List(ctx, UserType, tenantID, &dest, conditions...) 275 require.NoError(t, err) 276 assert.Len(t, dest, 1) 277 }) 278 279 t.Run("returns error if missing persistence context", func(t *testing.T) { 280 ctx := context.TODO() 281 err := sut.List(ctx, UserType, tenantID, nil) 282 require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error()) 283 }) 284 285 t.Run("returns error on db operation", func(t *testing.T) { 286 db, mock := testdb.MockDatabase(t) 287 defer mock.AssertExpectations(t) 288 289 mock.ExpectQuery(`SELECT .*`).WillReturnError(someError()) 290 ctx := persistence.SaveToContext(context.TODO(), db) 291 var dest UserCollection 292 293 err := sut.List(ctx, UserType, tenantID, &dest) 294 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 295 }) 296 297 t.Run("context properly canceled", func(t *testing.T) { 298 db, mock := testdb.MockDatabase(t) 299 defer mock.AssertExpectations(t) 300 301 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond) 302 defer cancel() 303 304 ctx = persistence.SaveToContext(ctx, db) 305 var dest UserCollection 306 err := sut.List(ctx, UserType, tenantID, &dest) 307 require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached") 308 }) 309 } 310 311 func TestListConditionTreeWithEmbeddedTenant(t *testing.T) { 312 peterID := "peterID" 313 homerID := "homerID" 314 peter := User{FirstName: "Peter", LastName: "Griffin", Age: 40, ID: peterID} 315 peterRow := []driver.Value{peterID, "Peter", "Griffin", 40} 316 homer := User{FirstName: "Homer", LastName: "Simpson", Age: 55, ID: homerID} 317 homerRow := []driver.Value{homerID, "Homer", "Simpson", 55} 318 319 sut := repo.NewConditionTreeListerWithEmbeddedTenant(userTableName, "tenant_id", []string{"id", "first_name", "last_name", "age"}) 320 321 t.Run("lists all items successfully", func(t *testing.T) { 322 db, mock := testdb.MockDatabase(t) 323 defer mock.AssertExpectations(t) 324 325 rows := sqlmock.NewRows([]string{"id", "first_name", "last_name", "age"}). 326 AddRow(peterRow...). 327 AddRow(homerRow...) 328 329 mock.ExpectQuery(regexp.QuoteMeta(`SELECT id, first_name, last_name, age FROM users WHERE (tenant_id = $1 AND first_name IN ($2, $3))`)). 330 WithArgs(tenantID, "Peter", "Homer").WillReturnRows(rows) 331 ctx := persistence.SaveToContext(context.TODO(), db) 332 var dest UserCollection 333 334 err := sut.ListConditionTree(ctx, UserType, tenantID, &dest, &repo.ConditionTree{Operand: repo.NewInConditionForStringValues("first_name", []string{"Peter", "Homer"})}) 335 require.NoError(t, err) 336 assert.Len(t, dest, 2) 337 assert.Contains(t, dest, peter) 338 assert.Contains(t, dest, homer) 339 }) 340 341 t.Run("lists all items successfully with additional parameters", func(t *testing.T) { 342 db, mock := testdb.MockDatabase(t) 343 defer mock.AssertExpectations(t) 344 345 rows := sqlmock.NewRows([]string{"id", "first_name", "last_name", "age"}). 346 AddRow(peterRow...) 347 mock.ExpectQuery(regexp.QuoteMeta("SELECT id, first_name, last_name, age FROM users WHERE (tenant_id = $1 AND (first_name = $2 OR age != $3))")). 348 WithArgs(tenantID, "Peter", 18).WillReturnRows(rows) 349 ctx := persistence.SaveToContext(context.TODO(), db) 350 var dest UserCollection 351 352 conditions := repo.Or(repo.ConditionTreesFromConditions([]repo.Condition{ 353 repo.NewEqualCondition("first_name", "Peter"), 354 repo.NewNotEqualCondition("age", 18), 355 })...) 356 357 err := sut.ListConditionTree(ctx, UserType, tenantID, &dest, conditions) 358 require.NoError(t, err) 359 assert.Len(t, dest, 1) 360 }) 361 362 t.Run("returns error if missing persistence context", func(t *testing.T) { 363 ctx := context.TODO() 364 err := sut.ListConditionTree(ctx, UserType, tenantID, nil, nil) 365 require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error()) 366 }) 367 368 t.Run("returns error on db operation", func(t *testing.T) { 369 db, mock := testdb.MockDatabase(t) 370 defer mock.AssertExpectations(t) 371 372 mock.ExpectQuery(`SELECT .*`).WillReturnError(someError()) 373 ctx := persistence.SaveToContext(context.TODO(), db) 374 var dest UserCollection 375 376 err := sut.ListConditionTree(ctx, UserType, tenantID, &dest, &repo.ConditionTree{Operand: repo.NewInConditionForStringValues("first_name", []string{"Peter", "Homer"})}) 377 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 378 }) 379 380 t.Run("context properly canceled", func(t *testing.T) { 381 db, mock := testdb.MockDatabase(t) 382 defer mock.AssertExpectations(t) 383 384 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond) 385 defer cancel() 386 387 ctx = persistence.SaveToContext(ctx, db) 388 var dest UserCollection 389 err := sut.ListConditionTree(ctx, UserType, tenantID, &dest, &repo.ConditionTree{Operand: repo.NewInConditionForStringValues("first_name", []string{"Peter", "Homer"})}) 390 require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached") 391 }) 392 } 393 394 func TestListGlobal(t *testing.T) { 395 peterID := "peterID" 396 homerID := "homerID" 397 peter := User{FirstName: "Peter", LastName: "Griffin", Age: 40, ID: peterID} 398 peterRow := []driver.Value{peterID, "Peter", "Griffin", 40} 399 homer := User{FirstName: "Homer", LastName: "Simpson", Age: 55, ID: homerID} 400 homerRow := []driver.Value{homerID, "Homer", "Simpson", 55} 401 402 sut := repo.NewListerGlobal(UserType, "users", []string{"id", "first_name", "last_name", "age"}) 403 404 t.Run("lists all items successfully", func(t *testing.T) { 405 db, mock := testdb.MockDatabase(t) 406 ctx := mockListGlobalDBSelect(peterRow, homerRow, mock, db, repo.NoLock) 407 defer mock.AssertExpectations(t) 408 409 var dest UserCollection 410 err := sut.ListGlobal(ctx, &dest) 411 require.NoError(t, err) 412 assert.Len(t, dest, 2) 413 assert.Contains(t, dest, peter) 414 assert.Contains(t, dest, homer) 415 }) 416 417 t.Run("lists all items successfully with additional parameters", func(t *testing.T) { 418 db, mock := testdb.MockDatabase(t) 419 defer mock.AssertExpectations(t) 420 421 ctx := mockListGlobalDBSelectWithAdditionalParameters(peterRow, mock, db, repo.NoLock) 422 var dest UserCollection 423 424 conditions := repo.Conditions{ 425 repo.NewEqualCondition("first_name", "Peter"), 426 repo.NewNotEqualCondition("age", 18), 427 } 428 429 err := sut.ListGlobal(ctx, &dest, conditions...) 430 require.NoError(t, err) 431 assert.Len(t, dest, 1) 432 }) 433 434 t.Run("returns error if missing persistence context", func(t *testing.T) { 435 ctx := context.TODO() 436 err := sut.ListGlobal(ctx, nil) 437 require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error()) 438 }) 439 440 t.Run("returns error on db operation", func(t *testing.T) { 441 db, mock := testdb.MockDatabase(t) 442 defer mock.AssertExpectations(t) 443 444 mock.ExpectQuery(`SELECT .*`).WillReturnError(someError()) 445 ctx := persistence.SaveToContext(context.TODO(), db) 446 var dest UserCollection 447 448 err := sut.ListGlobal(ctx, &dest) 449 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 450 }) 451 452 t.Run("context properly canceled", func(t *testing.T) { 453 db, mock := testdb.MockDatabase(t) 454 defer mock.AssertExpectations(t) 455 456 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond) 457 defer cancel() 458 459 ctx = persistence.SaveToContext(ctx, db) 460 var dest UserCollection 461 err := sut.ListGlobal(ctx, &dest) 462 require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached") 463 }) 464 } 465 466 func TestListGlobalWithSelectForUpdate(t *testing.T) { 467 peterID := "peterID" 468 homerID := "homerID" 469 peter := User{FirstName: "Peter", LastName: "Griffin", Age: 40, ID: peterID} 470 peterRow := []driver.Value{peterID, "Peter", "Griffin", 40} 471 homer := User{FirstName: "Homer", LastName: "Simpson", Age: 55, ID: homerID} 472 homerRow := []driver.Value{homerID, "Homer", "Simpson", 55} 473 474 sut := repo.NewListerGlobal(UserType, "users", []string{"id", "first_name", "last_name", "age"}) 475 476 t.Run("lists all items successfully", func(t *testing.T) { 477 db, mock := testdb.MockDatabase(t) 478 ctx := mockListGlobalDBSelect(peterRow, homerRow, mock, db, repo.ForUpdateLock) 479 defer mock.AssertExpectations(t) 480 481 var dest UserCollection 482 err := sut.ListGlobalWithSelectForUpdate(ctx, &dest) 483 require.NoError(t, err) 484 assert.Len(t, dest, 2) 485 assert.Contains(t, dest, peter) 486 assert.Contains(t, dest, homer) 487 }) 488 489 t.Run("lists all items successfully with additional parameters", func(t *testing.T) { 490 db, mock := testdb.MockDatabase(t) 491 ctx := mockListGlobalDBSelectWithAdditionalParameters(peterRow, mock, db, repo.ForUpdateLock) 492 defer mock.AssertExpectations(t) 493 494 var dest UserCollection 495 conditions := repo.Conditions{ 496 repo.NewEqualCondition("first_name", "Peter"), 497 repo.NewNotEqualCondition("age", 18), 498 } 499 500 err := sut.ListGlobalWithSelectForUpdate(ctx, &dest, conditions...) 501 require.NoError(t, err) 502 assert.Len(t, dest, 1) 503 }) 504 505 t.Run("returns error if missing persistence context", func(t *testing.T) { 506 ctx := context.TODO() 507 err := sut.ListGlobalWithSelectForUpdate(ctx, nil) 508 require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error()) 509 }) 510 511 t.Run("returns error on db operation", func(t *testing.T) { 512 db, mock := testdb.MockDatabase(t) 513 defer mock.AssertExpectations(t) 514 515 mock.ExpectQuery(`SELECT .*`).WillReturnError(someError()) 516 ctx := persistence.SaveToContext(context.TODO(), db) 517 var dest UserCollection 518 519 err := sut.ListGlobalWithSelectForUpdate(ctx, &dest) 520 require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query") 521 }) 522 523 t.Run("context properly canceled", func(t *testing.T) { 524 db, mock := testdb.MockDatabase(t) 525 defer mock.AssertExpectations(t) 526 527 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond) 528 defer cancel() 529 530 ctx = persistence.SaveToContext(ctx, db) 531 var dest UserCollection 532 err := sut.ListGlobalWithSelectForUpdate(ctx, &dest) 533 require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached") 534 }) 535 } 536 537 func mockListGlobalDBSelect(peterRow []driver.Value, homerRow []driver.Value, mock testdb.DBMock, db *sqlx.DB, lockClause string) context.Context { 538 rows := sqlmock.NewRows([]string{"id", "first_name", "last_name", "age"}). 539 AddRow(peterRow...). 540 AddRow(homerRow...) 541 mock.ExpectQuery(regexp.QuoteMeta(`SELECT id, first_name, last_name, age FROM users` + PrepareLockClause(lockClause))). 542 WillReturnRows(rows) 543 ctx := persistence.SaveToContext(context.TODO(), db) 544 return ctx 545 } 546 547 func mockListGlobalDBSelectWithAdditionalParameters(peterRow []driver.Value, mock testdb.DBMock, db *sqlx.DB, lockClause string) context.Context { 548 rows := sqlmock.NewRows([]string{"id", "first_name", "last_name", "age"}). 549 AddRow(peterRow...) 550 mock.ExpectQuery(regexp.QuoteMeta("SELECT id, first_name, last_name, age FROM users WHERE first_name = $1 AND age != $2"+PrepareLockClause(lockClause))). 551 WithArgs("Peter", 18).WillReturnRows(rows) 552 ctx := persistence.SaveToContext(context.TODO(), db) 553 return ctx 554 } 555 556 func PrepareLockClause(lockClause string) string { 557 if repo.IsLockClauseProvided(lockClause) { 558 lockClause = " " + lockClause 559 } 560 return lockClause 561 }