github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/label/query_test.go (about) 1 package label_test 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/google/uuid" 8 "github.com/kyma-incubator/compass/components/director/internal/domain/label" 9 "github.com/kyma-incubator/compass/components/director/internal/labelfilter" 10 "github.com/kyma-incubator/compass/components/director/internal/model" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func Test_FilterQuery(t *testing.T) { 15 tenantID := uuid.New() 16 17 fooQuery := `["foo-value"]` 18 barQuery := `["bar-value"]` 19 scenariosFooQuery := `$[*] ? (@ == "foo")` 20 scenariosBarPongQuery := `$[*] ? (@ == "bar pong")` 21 filterQueryWithJSON := `{"exists": false}` 22 23 filterAllFoos := labelfilter.LabelFilter{ 24 Key: "Foo", 25 Query: nil, 26 } 27 filterAllBars := labelfilter.LabelFilter{ 28 Key: "Bar", 29 Query: nil, 30 } 31 filterFoosWithValues := labelfilter.LabelFilter{ 32 Key: "Foo", 33 Query: &fooQuery, 34 } 35 filterBarsWithValues := labelfilter.LabelFilter{ 36 Key: "Bar", 37 Query: &barQuery, 38 } 39 filterAllScenarios := labelfilter.LabelFilter{ 40 Key: "Scenarios", 41 Query: nil, 42 } 43 filterScenariosWithFooValues := labelfilter.LabelFilter{ 44 Key: "Scenarios", 45 Query: &scenariosFooQuery, 46 } 47 filterScenariosWithbarPongValues := labelfilter.LabelFilter{ 48 Key: "Scenarios", 49 Query: &scenariosBarPongQuery, 50 } 51 filterGlobalSubaacountIDValues := labelfilter.LabelFilter{ 52 Key: "global_subaccount_id", 53 Query: &filterQueryWithJSON, 54 } 55 56 stmtPrefix := `SELECT "runtime_id" FROM public.labels WHERE "runtime_id" IS NOT NULL AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = ?))` 57 58 testCases := []struct { 59 Name string 60 ReturnSetCombination label.SetCombination 61 FilterInput []*labelfilter.LabelFilter 62 ExpectedQueryFilter string 63 ExpectedArgs []interface{} 64 ExpectedError error 65 }{ 66 { 67 Name: "Returns empty query filter when no label filters defined - intersect set", 68 ReturnSetCombination: label.IntersectSet, 69 FilterInput: nil, 70 ExpectedQueryFilter: "", 71 ExpectedError: nil, 72 }, { 73 Name: "Returns empty query filter when no label filters defined - union set", 74 ReturnSetCombination: label.UnionSet, 75 FilterInput: nil, 76 ExpectedQueryFilter: "", 77 ExpectedError: nil, 78 }, { 79 Name: "Query only for label assigned if label filter defined only with key - intersect set", 80 ReturnSetCombination: label.IntersectSet, 81 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos}, 82 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ?`, 83 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key}, 84 ExpectedError: nil, 85 }, { 86 Name: "Query only for label assigned if label filter defined only with key - union set", 87 ReturnSetCombination: label.UnionSet, 88 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos}, 89 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ?`, 90 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key}, 91 ExpectedError: nil, 92 }, { 93 Name: "Query only for labels assigned if label filter defined only with keys (multiple) - intersect set", 94 ReturnSetCombination: label.IntersectSet, 95 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos, &filterAllBars}, 96 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? INTERSECT ` + stmtPrefix + ` AND "key" = ?`, 97 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key, tenantID, filterAllBars.Key}, 98 ExpectedError: nil, 99 }, { 100 Name: "Query only for labels assigned if label filter defined only with keys (multiple) - union set", 101 ReturnSetCombination: label.UnionSet, 102 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos, &filterAllBars}, 103 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? UNION ` + stmtPrefix + ` AND "key" = ?`, 104 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key, tenantID, filterAllBars.Key}, 105 ExpectedError: nil, 106 }, { 107 Name: "Query for label assigned with value - intersect set", 108 ReturnSetCombination: label.IntersectSet, 109 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues}, 110 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 111 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query}, 112 ExpectedError: nil, 113 }, { 114 Name: "Query for label assigned with value - union set", 115 ReturnSetCombination: label.UnionSet, 116 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues}, 117 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 118 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query}, 119 ExpectedError: nil, 120 }, { 121 Name: "Query for labels assigned with values (multiple) - intersect set", 122 ReturnSetCombination: label.IntersectSet, 123 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues, &filterBarsWithValues}, 124 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ? INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 125 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query, tenantID, filterBarsWithValues.Key, *filterBarsWithValues.Query}, 126 ExpectedError: nil, 127 }, { 128 Name: "Query for labels assigned with values (multiple) - union set", 129 ReturnSetCombination: label.UnionSet, 130 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues, &filterBarsWithValues}, 131 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ? UNION ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 132 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query, tenantID, filterBarsWithValues.Key, *filterBarsWithValues.Query}, 133 ExpectedError: nil, 134 }, { 135 Name: "[Scenarios] Query for label assigned", 136 ReturnSetCombination: label.IntersectSet, 137 FilterInput: []*labelfilter.LabelFilter{&filterAllScenarios}, 138 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ?`, 139 ExpectedArgs: []interface{}{tenantID, filterAllScenarios.Key}, 140 ExpectedError: nil, 141 }, { 142 Name: "[Scenarios] Query for label assigned with value", 143 ReturnSetCombination: label.IntersectSet, 144 FilterInput: []*labelfilter.LabelFilter{&filterScenariosWithFooValues}, 145 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]`, 146 ExpectedArgs: []interface{}{tenantID, filterScenariosWithFooValues.Key, "foo"}, 147 ExpectedError: nil, 148 }, { 149 Name: "[Scenarios] Query for label assigned with values", 150 ReturnSetCombination: label.IntersectSet, 151 FilterInput: []*labelfilter.LabelFilter{&filterScenariosWithFooValues, &filterScenariosWithbarPongValues}, 152 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]` + 153 ` INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]`, 154 ExpectedArgs: []interface{}{tenantID, filterScenariosWithFooValues.Key, "foo", tenantID, filterScenariosWithbarPongValues.Key, "bar pong"}, 155 ExpectedError: nil, 156 }, 157 { 158 Name: "[Global_Subaccount_Id] Query for label assigned with values", 159 ReturnSetCombination: label.IntersectSet, 160 FilterInput: []*labelfilter.LabelFilter{&filterGlobalSubaacountIDValues}, 161 ExpectedQueryFilter: stmtPrefix + ` AND "app_id" NOT IN (SELECT "app_id" FROM public.labels WHERE key = 'global_subaccount_id' AND "app_id" IS NOT NULL)`, 162 ExpectedArgs: []interface{}{tenantID}, 163 ExpectedError: nil, 164 }, 165 } 166 167 for _, testCase := range testCases { 168 t.Run(testCase.Name, func(t *testing.T) { 169 queryFilter, args, err := label.FilterQuery(model.RuntimeLabelableObject, testCase.ReturnSetCombination, tenantID, testCase.FilterInput) 170 171 assert.Equal(t, testCase.ExpectedQueryFilter, removeWhitespace(queryFilter)) 172 assert.Equal(t, testCase.ExpectedArgs, args) 173 assert.Equal(t, testCase.ExpectedError, err) 174 }) 175 } 176 } 177 178 func TestFilterQueryGlobal(t *testing.T) { 179 fooQuery := `["foo-value"]` 180 barQuery := `["bar-value"]` 181 scenariosFooQuery := `$[*] ? (@ == "foo")` 182 scenariosBarPongQuery := `$[*] ? (@ == "bar pong")` 183 184 filterAllFoos := labelfilter.LabelFilter{ 185 Key: "Foo", 186 Query: nil, 187 } 188 filterAllBars := labelfilter.LabelFilter{ 189 Key: "Bar", 190 Query: nil, 191 } 192 filterFoosWithValues := labelfilter.LabelFilter{ 193 Key: "Foo", 194 Query: &fooQuery, 195 } 196 filterBarsWithValues := labelfilter.LabelFilter{ 197 Key: "Bar", 198 Query: &barQuery, 199 } 200 filterAllScenarios := labelfilter.LabelFilter{ 201 Key: "Scenarios", 202 Query: nil, 203 } 204 filterScenariosWithFooValues := labelfilter.LabelFilter{ 205 Key: "Scenarios", 206 Query: &scenariosFooQuery, 207 } 208 filterScenariosWithbarPongValues := labelfilter.LabelFilter{ 209 Key: "Scenarios", 210 Query: &scenariosBarPongQuery, 211 } 212 213 stmtPrefix := `SELECT "runtime_id" FROM public.labels ` + 214 `WHERE "runtime_id" IS NOT NULL` 215 216 testCases := []struct { 217 Name string 218 ReturnSetCombination label.SetCombination 219 FilterInput []*labelfilter.LabelFilter 220 ExpectedQueryFilter string 221 ExpectedArgs []interface{} 222 ExpectedError error 223 }{ 224 { 225 Name: "Returns empty query filter when no label filters defined - intersect set", 226 ReturnSetCombination: label.IntersectSet, 227 FilterInput: nil, 228 ExpectedError: nil, 229 }, { 230 Name: "Returns empty query filter when no label filters defined - union set", 231 ReturnSetCombination: label.UnionSet, 232 FilterInput: nil, 233 ExpectedError: nil, 234 }, { 235 Name: "Query only for label assigned if label filter defined only with key - intersect set", 236 ReturnSetCombination: label.IntersectSet, 237 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos}, 238 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ?`, 239 ExpectedArgs: []interface{}{filterAllFoos.Key}, 240 ExpectedError: nil, 241 }, { 242 Name: "Query only for label assigned if label filter defined only with key - union set", 243 ReturnSetCombination: label.UnionSet, 244 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos}, 245 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ?`, 246 ExpectedArgs: []interface{}{filterAllFoos.Key}, 247 ExpectedError: nil, 248 }, { 249 Name: "Query only for labels assigned if label filter defined only with keys (multiple) - intersect set", 250 ReturnSetCombination: label.IntersectSet, 251 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos, &filterAllBars}, 252 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? INTERSECT ` + stmtPrefix + ` AND "key" = ?`, 253 ExpectedArgs: []interface{}{filterAllFoos.Key, filterAllBars.Key}, 254 ExpectedError: nil, 255 }, { 256 Name: "Query only for labels assigned if label filter defined only with keys (multiple) - union set", 257 ReturnSetCombination: label.UnionSet, 258 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos, &filterAllBars}, 259 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? UNION ` + stmtPrefix + ` AND "key" = ?`, 260 ExpectedArgs: []interface{}{filterAllFoos.Key, filterAllBars.Key}, 261 ExpectedError: nil, 262 }, { 263 Name: "Query for label assigned with value - intersect set", 264 ReturnSetCombination: label.IntersectSet, 265 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues}, 266 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 267 ExpectedArgs: []interface{}{filterFoosWithValues.Key, *filterFoosWithValues.Query}, 268 ExpectedError: nil, 269 }, { 270 Name: "Query for label assigned with value - union set", 271 ReturnSetCombination: label.UnionSet, 272 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues}, 273 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 274 ExpectedArgs: []interface{}{filterFoosWithValues.Key, *filterFoosWithValues.Query}, 275 ExpectedError: nil, 276 }, { 277 Name: "Query for labels assigned with values (multiple) - intersect set", 278 ReturnSetCombination: label.IntersectSet, 279 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues, &filterBarsWithValues}, 280 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ? INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 281 ExpectedArgs: []interface{}{filterFoosWithValues.Key, *filterFoosWithValues.Query, filterBarsWithValues.Key, *filterBarsWithValues.Query}, 282 ExpectedError: nil, 283 }, { 284 Name: "Query for labels assigned with values (multiple) - union set", 285 ReturnSetCombination: label.UnionSet, 286 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues, &filterBarsWithValues}, 287 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ? UNION ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 288 ExpectedArgs: []interface{}{filterFoosWithValues.Key, *filterFoosWithValues.Query, filterBarsWithValues.Key, *filterBarsWithValues.Query}, 289 ExpectedError: nil, 290 }, { 291 Name: "[Scenarios] Query for label assigned", 292 ReturnSetCombination: label.IntersectSet, 293 FilterInput: []*labelfilter.LabelFilter{&filterAllScenarios}, 294 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ?`, 295 ExpectedArgs: []interface{}{filterAllScenarios.Key}, 296 ExpectedError: nil, 297 }, { 298 Name: "[Scenarios] Query for label assigned with value", 299 ReturnSetCombination: label.IntersectSet, 300 FilterInput: []*labelfilter.LabelFilter{&filterScenariosWithFooValues}, 301 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]`, 302 ExpectedArgs: []interface{}{filterScenariosWithFooValues.Key, "foo"}, 303 ExpectedError: nil, 304 }, { 305 Name: "[Scenarios] Query for label assigned with values", 306 ReturnSetCombination: label.IntersectSet, 307 FilterInput: []*labelfilter.LabelFilter{&filterScenariosWithFooValues, &filterScenariosWithbarPongValues}, 308 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]` + 309 ` INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]`, 310 ExpectedArgs: []interface{}{filterScenariosWithFooValues.Key, "foo", filterScenariosWithbarPongValues.Key, "bar pong"}, 311 ExpectedError: nil, 312 }, 313 } 314 315 for _, testCase := range testCases { 316 t.Run(testCase.Name, func(t *testing.T) { 317 queryFilter, args, err := label.FilterQueryGlobal(model.RuntimeLabelableObject, testCase.ReturnSetCombination, testCase.FilterInput) 318 319 assert.Equal(t, testCase.ExpectedQueryFilter, queryFilter) 320 assert.Equal(t, testCase.ExpectedArgs, args) 321 assert.Equal(t, testCase.ExpectedError, err) 322 }) 323 } 324 } 325 326 func TestFilterQueryWithEmbeddedTenant(t *testing.T) { 327 tenantID := uuid.New() 328 329 fooQuery := `["foo-value"]` 330 barQuery := `["bar-value"]` 331 scenariosFooQuery := `$[*] ? (@ == "foo")` 332 scenariosBarPongQuery := `$[*] ? (@ == "bar pong")` 333 334 filterAllFoos := labelfilter.LabelFilter{ 335 Key: "Foo", 336 Query: nil, 337 } 338 filterAllBars := labelfilter.LabelFilter{ 339 Key: "Bar", 340 Query: nil, 341 } 342 filterFoosWithValues := labelfilter.LabelFilter{ 343 Key: "Foo", 344 Query: &fooQuery, 345 } 346 filterBarsWithValues := labelfilter.LabelFilter{ 347 Key: "Bar", 348 Query: &barQuery, 349 } 350 filterAllScenarios := labelfilter.LabelFilter{ 351 Key: "Scenarios", 352 Query: nil, 353 } 354 filterScenariosWithFooValues := labelfilter.LabelFilter{ 355 Key: "Scenarios", 356 Query: &scenariosFooQuery, 357 } 358 filterScenariosWithbarPongValues := labelfilter.LabelFilter{ 359 Key: "Scenarios", 360 Query: &scenariosBarPongQuery, 361 } 362 363 stmtPrefix := `SELECT "tenant_id" FROM public.labels ` + 364 `WHERE "tenant_id" IS NOT NULL AND tenant_id = ?` 365 366 testCases := []struct { 367 Name string 368 ReturnSetCombination label.SetCombination 369 FilterInput []*labelfilter.LabelFilter 370 ExpectedQueryFilter string 371 ExpectedArgs []interface{} 372 ExpectedError error 373 }{ 374 { 375 Name: "Returns empty query filter when no label filters defined - intersect set", 376 ReturnSetCombination: label.IntersectSet, 377 FilterInput: nil, 378 ExpectedError: nil, 379 }, { 380 Name: "Returns empty query filter when no label filters defined - union set", 381 ReturnSetCombination: label.UnionSet, 382 FilterInput: nil, 383 ExpectedError: nil, 384 }, { 385 Name: "Query only for label assigned if label filter defined only with key - intersect set", 386 ReturnSetCombination: label.IntersectSet, 387 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos}, 388 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ?`, 389 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key}, 390 ExpectedError: nil, 391 }, { 392 Name: "Query only for label assigned if label filter defined only with key - union set", 393 ReturnSetCombination: label.UnionSet, 394 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos}, 395 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ?`, 396 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key}, 397 ExpectedError: nil, 398 }, { 399 Name: "Query only for labels assigned if label filter defined only with keys (multiple) - intersect set", 400 ReturnSetCombination: label.IntersectSet, 401 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos, &filterAllBars}, 402 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? INTERSECT ` + stmtPrefix + ` AND "key" = ?`, 403 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key, tenantID, filterAllBars.Key}, 404 ExpectedError: nil, 405 }, { 406 Name: "Query only for labels assigned if label filter defined only with keys (multiple) - union set", 407 ReturnSetCombination: label.UnionSet, 408 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos, &filterAllBars}, 409 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? UNION ` + stmtPrefix + ` AND "key" = ?`, 410 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key, tenantID, filterAllBars.Key}, 411 ExpectedError: nil, 412 }, { 413 Name: "Query for label assigned with value - intersect set", 414 ReturnSetCombination: label.IntersectSet, 415 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues}, 416 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 417 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query}, 418 ExpectedError: nil, 419 }, { 420 Name: "Query for label assigned with value - union set", 421 ReturnSetCombination: label.UnionSet, 422 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues}, 423 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 424 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query}, 425 ExpectedError: nil, 426 }, { 427 Name: "Query for labels assigned with values (multiple) - intersect set", 428 ReturnSetCombination: label.IntersectSet, 429 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues, &filterBarsWithValues}, 430 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ? INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 431 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query, tenantID, filterBarsWithValues.Key, *filterBarsWithValues.Query}, 432 ExpectedError: nil, 433 }, { 434 Name: "Query for labels assigned with values (multiple) - union set", 435 ReturnSetCombination: label.UnionSet, 436 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues, &filterBarsWithValues}, 437 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" @> ? UNION ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 438 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query, tenantID, filterBarsWithValues.Key, *filterBarsWithValues.Query}, 439 ExpectedError: nil, 440 }, { 441 Name: "[Scenarios] Query for label assigned", 442 ReturnSetCombination: label.IntersectSet, 443 FilterInput: []*labelfilter.LabelFilter{&filterAllScenarios}, 444 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ?`, 445 ExpectedArgs: []interface{}{tenantID, filterAllScenarios.Key}, 446 ExpectedError: nil, 447 }, { 448 Name: "[Scenarios] Query for label assigned with value", 449 ReturnSetCombination: label.IntersectSet, 450 FilterInput: []*labelfilter.LabelFilter{&filterScenariosWithFooValues}, 451 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]`, 452 ExpectedArgs: []interface{}{tenantID, filterScenariosWithFooValues.Key, "foo"}, 453 ExpectedError: nil, 454 }, { 455 Name: "[Scenarios] Query for label assigned with values", 456 ReturnSetCombination: label.IntersectSet, 457 FilterInput: []*labelfilter.LabelFilter{&filterScenariosWithFooValues, &filterScenariosWithbarPongValues}, 458 ExpectedQueryFilter: stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]` + 459 ` INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]`, 460 ExpectedArgs: []interface{}{tenantID, filterScenariosWithFooValues.Key, "foo", tenantID, filterScenariosWithbarPongValues.Key, "bar pong"}, 461 ExpectedError: nil, 462 }, 463 } 464 465 for _, testCase := range testCases { 466 t.Run(testCase.Name, func(t *testing.T) { 467 queryFilter, args, err := label.FilterQuery(model.TenantLabelableObject, testCase.ReturnSetCombination, tenantID, testCase.FilterInput) 468 469 assert.Equal(t, testCase.ExpectedQueryFilter, queryFilter) 470 assert.Equal(t, testCase.ExpectedArgs, args) 471 assert.Equal(t, testCase.ExpectedError, err) 472 }) 473 } 474 } 475 476 func TestFilterSubquery(t *testing.T) { 477 tenantID := uuid.New() 478 479 fooQuery := `["foo-value"]` 480 barQuery := `["bar-value"]` 481 scenariosFooQuery := `$[*] ? (@ == "foo")` 482 scenariosBarPongQuery := `$[*] ? (@ == "bar pong")` 483 484 filterAllFoos := labelfilter.LabelFilter{ 485 Key: "Foo", 486 Query: nil, 487 } 488 filterAllBars := labelfilter.LabelFilter{ 489 Key: "Bar", 490 Query: nil, 491 } 492 filterFoosWithValues := labelfilter.LabelFilter{ 493 Key: "Foo", 494 Query: &fooQuery, 495 } 496 filterBarsWithValues := labelfilter.LabelFilter{ 497 Key: "Bar", 498 Query: &barQuery, 499 } 500 filterAllScenarios := labelfilter.LabelFilter{ 501 Key: "Scenarios", 502 Query: nil, 503 } 504 filterScenariosWithFooValues := labelfilter.LabelFilter{ 505 Key: "Scenarios", 506 Query: &scenariosFooQuery, 507 } 508 filterScenariosWithbarPongValues := labelfilter.LabelFilter{ 509 Key: "Scenarios", 510 Query: &scenariosBarPongQuery, 511 } 512 513 stmtPrefix := `SELECT "runtime_id" FROM public.labels WHERE "runtime_id" IS NOT NULL AND (id IN (SELECT id FROM runtime_labels_tenants WHERE tenant_id = ?))` 514 515 testCases := []struct { 516 Name string 517 ReturnSetCombination label.SetCombination 518 FilterInput []*labelfilter.LabelFilter 519 ExpectedQueryFilter string 520 ExpectedArgs []interface{} 521 ExpectedError error 522 }{ 523 { 524 Name: "Returns empty query filter when no label filters defined - intersect set", 525 ReturnSetCombination: label.IntersectSet, 526 FilterInput: nil, 527 ExpectedQueryFilter: "", 528 ExpectedError: nil, 529 }, { 530 Name: "Returns empty query filter when no label filters defined - union set", 531 ReturnSetCombination: label.UnionSet, 532 FilterInput: nil, 533 ExpectedQueryFilter: "", 534 ExpectedError: nil, 535 }, { 536 Name: "Query only for label assigned if label filter defined only with key - intersect set", 537 ReturnSetCombination: label.IntersectSet, 538 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos}, 539 ExpectedQueryFilter: `INTERSECT ` + stmtPrefix + ` AND "key" = ?`, 540 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key}, 541 ExpectedError: nil, 542 }, { 543 Name: "Query only for label assigned if label filter defined only with key - union set", 544 ReturnSetCombination: label.UnionSet, 545 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos}, 546 ExpectedQueryFilter: `UNION ` + stmtPrefix + ` AND "key" = ?`, 547 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key}, 548 ExpectedError: nil, 549 }, { 550 Name: "Query only for labels assigned if label filter defined only with keys (multiple) - intersect set", 551 ReturnSetCombination: label.IntersectSet, 552 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos, &filterAllBars}, 553 ExpectedQueryFilter: `INTERSECT ` + stmtPrefix + ` AND "key" = ? INTERSECT ` + stmtPrefix + ` AND "key" = ?`, 554 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key, tenantID, filterAllBars.Key}, 555 ExpectedError: nil, 556 }, { 557 Name: "Query only for labels assigned if label filter defined only with keys (multiple) - union set", 558 ReturnSetCombination: label.UnionSet, 559 FilterInput: []*labelfilter.LabelFilter{&filterAllFoos, &filterAllBars}, 560 ExpectedQueryFilter: `UNION ` + stmtPrefix + ` AND "key" = ? UNION ` + stmtPrefix + ` AND "key" = ?`, 561 ExpectedArgs: []interface{}{tenantID, filterAllFoos.Key, tenantID, filterAllBars.Key}, 562 ExpectedError: nil, 563 }, { 564 Name: "Query for label assigned with value - intersect set", 565 ReturnSetCombination: label.IntersectSet, 566 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues}, 567 ExpectedQueryFilter: `INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 568 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query}, 569 ExpectedError: nil, 570 }, { 571 Name: "Query for label assigned with value - union set", 572 ReturnSetCombination: label.UnionSet, 573 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues}, 574 ExpectedQueryFilter: `UNION ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 575 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query}, 576 ExpectedError: nil, 577 }, { 578 Name: "Query for labels assigned with values (multiple) - intersect set", 579 ReturnSetCombination: label.IntersectSet, 580 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues, &filterBarsWithValues}, 581 ExpectedQueryFilter: `INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" @> ? INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 582 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query, tenantID, filterBarsWithValues.Key, *filterBarsWithValues.Query}, 583 ExpectedError: nil, 584 }, { 585 Name: "Query for labels assigned with values (multiple) - union set", 586 ReturnSetCombination: label.UnionSet, 587 FilterInput: []*labelfilter.LabelFilter{&filterFoosWithValues, &filterBarsWithValues}, 588 ExpectedQueryFilter: `UNION ` + stmtPrefix + ` AND "key" = ? AND "value" @> ? UNION ` + stmtPrefix + ` AND "key" = ? AND "value" @> ?`, 589 ExpectedArgs: []interface{}{tenantID, filterFoosWithValues.Key, *filterFoosWithValues.Query, tenantID, filterBarsWithValues.Key, *filterBarsWithValues.Query}, 590 ExpectedError: nil, 591 }, { 592 Name: "[Scenarios] Query for label assigned", 593 ReturnSetCombination: label.IntersectSet, 594 FilterInput: []*labelfilter.LabelFilter{&filterAllScenarios}, 595 ExpectedQueryFilter: `INTERSECT ` + stmtPrefix + ` AND "key" = ?`, 596 ExpectedArgs: []interface{}{tenantID, filterAllScenarios.Key}, 597 ExpectedError: nil, 598 }, { 599 Name: "[Scenarios] Query for label assigned with value", 600 ReturnSetCombination: label.IntersectSet, 601 FilterInput: []*labelfilter.LabelFilter{&filterScenariosWithFooValues}, 602 ExpectedQueryFilter: `INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]`, 603 ExpectedArgs: []interface{}{tenantID, filterScenariosWithFooValues.Key, "foo"}, 604 ExpectedError: nil, 605 }, { 606 Name: "[Scenarios] Query for label assigned with values", 607 ReturnSetCombination: label.IntersectSet, 608 FilterInput: []*labelfilter.LabelFilter{&filterScenariosWithFooValues, &filterScenariosWithbarPongValues}, 609 ExpectedQueryFilter: `INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]` + 610 ` INTERSECT ` + stmtPrefix + ` AND "key" = ? AND "value" ?| array[?]`, 611 ExpectedArgs: []interface{}{tenantID, filterScenariosWithFooValues.Key, "foo", tenantID, filterScenariosWithbarPongValues.Key, "bar pong"}, 612 ExpectedError: nil, 613 }, 614 } 615 616 for _, testCase := range testCases { 617 t.Run(testCase.Name, func(t *testing.T) { 618 queryFilter, args, err := label.FilterSubquery(model.RuntimeLabelableObject, testCase.ReturnSetCombination, tenantID, testCase.FilterInput) 619 620 assert.Equal(t, testCase.ExpectedQueryFilter, removeWhitespace(queryFilter)) 621 assert.Equal(t, testCase.ExpectedArgs, args) 622 assert.Equal(t, testCase.ExpectedError, err) 623 }) 624 } 625 } 626 627 func removeWhitespace(s string) string { 628 return strings.Join(strings.Fields(s), " ") 629 }