github.com/argoproj/argo-events@v1.9.1/sensors/dependencies/filter_test.go (about) 1 /* 2 Copyright 2018 BlackRock, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package dependencies 18 19 import ( 20 "encoding/json" 21 "testing" 22 "time" 23 24 "github.com/stretchr/testify/assert" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 27 "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1" 28 ) 29 30 func TestFilter(t *testing.T) { 31 t.Run("test empty", func(t *testing.T) { 32 filter := &v1alpha1.EventDependencyFilter{} 33 filtersLogicalOperator := v1alpha1.AndLogicalOperator 34 now := time.Now().UTC() 35 event := &v1alpha1.Event{ 36 Context: &v1alpha1.EventContext{ 37 Type: "webhook", 38 SpecVersion: "0.3", 39 Source: "webhook-gateway", 40 ID: "1", 41 Time: metav1.Time{ 42 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 43 }, 44 DataContentType: "application/json", 45 Subject: "example-1", 46 }, 47 Data: []byte(`{"k": "v"}`), 48 } 49 50 pass, err := Filter(event, filter, filtersLogicalOperator) 51 52 assert.NoError(t, err) 53 assert.True(t, pass) 54 }) 55 56 t.Run("test event passing", func(t *testing.T) { 57 filter := &v1alpha1.EventDependencyFilter{ 58 Data: []v1alpha1.DataFilter{ 59 { 60 Path: "k", 61 Type: v1alpha1.JSONTypeString, 62 Value: []string{"v"}, 63 }, 64 }, 65 } 66 filtersLogicalOperator := v1alpha1.AndLogicalOperator 67 68 now := time.Now().UTC() 69 event := &v1alpha1.Event{ 70 Context: &v1alpha1.EventContext{ 71 Type: "webhook", 72 SpecVersion: "0.3", 73 Source: "webhook-gateway", 74 ID: "1", 75 Time: metav1.Time{ 76 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 77 }, 78 DataContentType: "application/json", 79 Subject: "example-1", 80 }, 81 Data: []byte(`{"k": "v"}`), 82 } 83 84 pass, err := filterEvent(filter, filtersLogicalOperator, event) 85 86 assert.NoError(t, err) 87 assert.True(t, pass) 88 }) 89 90 t.Run("test event not passing", func(t *testing.T) { 91 filter := &v1alpha1.EventDependencyFilter{ 92 Data: []v1alpha1.DataFilter{ 93 { 94 Path: "z", 95 Type: v1alpha1.JSONTypeString, 96 Value: []string{"v"}, 97 }, 98 }, 99 } 100 filtersLogicalOperator := v1alpha1.AndLogicalOperator 101 now := time.Now().UTC() 102 event := &v1alpha1.Event{ 103 Context: &v1alpha1.EventContext{ 104 Type: "webhook", 105 SpecVersion: "0.3", 106 Source: "webhook-gateway", 107 ID: "1", 108 Time: metav1.Time{ 109 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 110 }, 111 DataContentType: "application/json", 112 Subject: "example-1", 113 }, 114 Data: []byte(`{"k": "v"}`), 115 } 116 117 pass, err := filterEvent(filter, filtersLogicalOperator, event) 118 119 assert.Error(t, err) 120 assert.False(t, pass) 121 }) 122 123 t.Run("test error", func(t *testing.T) { 124 filter := &v1alpha1.EventDependencyFilter{ 125 Time: &v1alpha1.TimeFilter{ 126 Start: "09:09:0", 127 Stop: "19:19:19", 128 }, 129 } 130 filtersLogicalOperator := v1alpha1.AndLogicalOperator 131 now := time.Now().UTC() 132 event := &v1alpha1.Event{ 133 Context: &v1alpha1.EventContext{ 134 Type: "webhook", 135 SpecVersion: "0.3", 136 Source: "webhook-gateway", 137 ID: "1", 138 Time: metav1.Time{ 139 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 140 }, 141 DataContentType: "application/json", 142 Subject: "example-1", 143 }, 144 Data: []byte(`{"k": "v"}`), 145 } 146 147 pass, err := filterEvent(filter, filtersLogicalOperator, event) 148 149 assert.Error(t, err) 150 assert.False(t, pass) 151 }) 152 153 t.Run("test 'empty' filtersLogicalOperator", func(t *testing.T) { 154 // ctx filter: true 155 // data filter: false 156 filter := &v1alpha1.EventDependencyFilter{ 157 Context: &v1alpha1.EventContext{ 158 Type: "webhook", 159 Source: "webhook-gateway", 160 }, 161 Data: []v1alpha1.DataFilter{ 162 { 163 Path: "k", 164 Type: v1alpha1.JSONTypeString, 165 Value: []string{"z"}, 166 }, 167 }, 168 } 169 filtersLogicalOperator := v1alpha1.EmptyLogicalOperator 170 now := time.Now().UTC() 171 event := &v1alpha1.Event{ 172 Context: &v1alpha1.EventContext{ 173 Type: "webhook", 174 SpecVersion: "0.3", 175 Source: "webhook-gateway", 176 ID: "1", 177 Time: metav1.Time{ 178 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 179 }, 180 DataContentType: "application/json", 181 Subject: "example-1", 182 }, 183 Data: []byte(`{"k": "v"}`), 184 } 185 186 pass, err := filterEvent(filter, filtersLogicalOperator, event) 187 188 assert.NoError(t, err) 189 assert.False(t, pass) 190 }) 191 192 t.Run("test 'empty' filtersLogicalOperator with error", func(t *testing.T) { 193 // ctx filter: true 194 // data filter: error (false) 195 filter := &v1alpha1.EventDependencyFilter{ 196 Context: &v1alpha1.EventContext{ 197 Type: "webhook", 198 Source: "webhook-gateway", 199 }, 200 Data: []v1alpha1.DataFilter{ 201 { 202 Path: "z", 203 Type: v1alpha1.JSONTypeString, 204 Value: []string{"v"}, 205 }, 206 }, 207 } 208 filtersLogicalOperator := v1alpha1.EmptyLogicalOperator 209 now := time.Now().UTC() 210 event := &v1alpha1.Event{ 211 Context: &v1alpha1.EventContext{ 212 Type: "webhook", 213 SpecVersion: "0.3", 214 Source: "webhook-gateway", 215 ID: "1", 216 Time: metav1.Time{ 217 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 218 }, 219 DataContentType: "application/json", 220 Subject: "example-1", 221 }, 222 Data: []byte(`{"k": "v"}`), 223 } 224 225 pass, err := filterEvent(filter, filtersLogicalOperator, event) 226 227 assert.Error(t, err) 228 assert.False(t, pass) 229 }) 230 231 t.Run("test 'and' filtersLogicalOperator", func(t *testing.T) { 232 // ctx filter: false 233 // data filter: true 234 filter := &v1alpha1.EventDependencyFilter{ 235 Context: &v1alpha1.EventContext{ 236 Type: "webhook", 237 Source: "webhook-fake", 238 }, 239 Data: []v1alpha1.DataFilter{ 240 { 241 Path: "k", 242 Type: v1alpha1.JSONTypeString, 243 Value: []string{"v"}, 244 }, 245 }, 246 } 247 filtersLogicalOperator := v1alpha1.AndLogicalOperator 248 now := time.Now().UTC() 249 event := &v1alpha1.Event{ 250 Context: &v1alpha1.EventContext{ 251 Type: "webhook", 252 SpecVersion: "0.3", 253 Source: "webhook-gateway", 254 ID: "1", 255 Time: metav1.Time{ 256 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 257 }, 258 DataContentType: "application/json", 259 Subject: "example-1", 260 }, 261 Data: []byte(`{"k": "v"}`), 262 } 263 264 pass, err := filterEvent(filter, filtersLogicalOperator, event) 265 266 assert.NoError(t, err) 267 assert.False(t, pass) 268 }) 269 270 t.Run("test 'and' filtersLogicalOperator with error", func(t *testing.T) { 271 // ctx filter: true 272 // data filter: error (false) 273 filter := &v1alpha1.EventDependencyFilter{ 274 Context: &v1alpha1.EventContext{ 275 Type: "webhook", 276 Source: "webhook-gateway", 277 }, 278 Data: []v1alpha1.DataFilter{ 279 { 280 Path: "z", 281 Type: v1alpha1.JSONTypeString, 282 Value: []string{"v"}, 283 }, 284 }, 285 } 286 filtersLogicalOperator := v1alpha1.AndLogicalOperator 287 now := time.Now().UTC() 288 event := &v1alpha1.Event{ 289 Context: &v1alpha1.EventContext{ 290 Type: "webhook", 291 SpecVersion: "0.3", 292 Source: "webhook-gateway", 293 ID: "1", 294 Time: metav1.Time{ 295 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 296 }, 297 DataContentType: "application/json", 298 Subject: "example-1", 299 }, 300 Data: []byte(`{"k": "v"}`), 301 } 302 303 pass, err := filterEvent(filter, filtersLogicalOperator, event) 304 305 assert.Error(t, err) 306 assert.False(t, pass) 307 }) 308 309 t.Run("test 'or' filtersLogicalOperator", func(t *testing.T) { 310 // ctx filter: true 311 // data filter: false 312 filter := &v1alpha1.EventDependencyFilter{ 313 Context: &v1alpha1.EventContext{ 314 Type: "webhook", 315 Source: "webhook-gateway", 316 }, 317 Data: []v1alpha1.DataFilter{ 318 { 319 Path: "z", 320 Type: v1alpha1.JSONTypeString, 321 Value: []string{"v"}, 322 }, 323 }, 324 } 325 filtersLogicalOperator := v1alpha1.OrLogicalOperator 326 now := time.Now().UTC() 327 event := &v1alpha1.Event{ 328 Context: &v1alpha1.EventContext{ 329 Type: "webhook", 330 SpecVersion: "0.3", 331 Source: "webhook-gateway", 332 ID: "1", 333 Time: metav1.Time{ 334 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 335 }, 336 DataContentType: "application/json", 337 Subject: "example-1", 338 }, 339 Data: []byte(`{"k": "v"}`), 340 } 341 342 pass, err := filterEvent(filter, filtersLogicalOperator, event) 343 344 assert.Error(t, err) 345 assert.True(t, pass) 346 }) 347 348 t.Run("test 'or' filtersLogicalOperator with error", func(t *testing.T) { 349 // ctx filter: true 350 // data filter: error (false) 351 filter := &v1alpha1.EventDependencyFilter{ 352 Context: &v1alpha1.EventContext{ 353 Type: "webhook", 354 Source: "webhook-gateway", 355 }, 356 Data: []v1alpha1.DataFilter{ 357 { 358 Path: "z", 359 Type: v1alpha1.JSONTypeString, 360 Value: []string{"v"}, 361 }, 362 }, 363 } 364 filtersLogicalOperator := v1alpha1.OrLogicalOperator 365 now := time.Now().UTC() 366 event := &v1alpha1.Event{ 367 Context: &v1alpha1.EventContext{ 368 Type: "webhook", 369 SpecVersion: "0.3", 370 Source: "webhook-gateway", 371 ID: "1", 372 Time: metav1.Time{ 373 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 374 }, 375 DataContentType: "application/json", 376 Subject: "example-1", 377 }, 378 Data: []byte(`{"k": "v"}`), 379 } 380 381 pass, err := filterEvent(filter, filtersLogicalOperator, event) 382 383 assert.Error(t, err) 384 assert.True(t, pass) 385 }) 386 387 t.Run("test advanced logic: (A && B) && (C && D)", func(t *testing.T) { 388 // data filter: A && B == true 389 // expr filter: C && D == true 390 filter := &v1alpha1.EventDependencyFilter{ 391 DataLogicalOperator: v1alpha1.EmptyLogicalOperator, // default AND 392 Data: []v1alpha1.DataFilter{ 393 { 394 // A 395 Path: "a", 396 Type: v1alpha1.JSONTypeString, 397 Value: []string{"x"}, 398 }, 399 { 400 // B 401 Path: "b", 402 Type: v1alpha1.JSONTypeNumber, 403 Value: []string{"10"}, 404 }, 405 }, 406 ExprLogicalOperator: v1alpha1.EmptyLogicalOperator, // default AND 407 Exprs: []v1alpha1.ExprFilter{ 408 { 409 // C 410 Expr: `d == "hello world"`, 411 Fields: []v1alpha1.PayloadField{ 412 { 413 Path: "c.d", 414 Name: "d", 415 }, 416 }, 417 }, 418 { 419 // D 420 Expr: `e == false`, 421 Fields: []v1alpha1.PayloadField{ 422 { 423 Path: "c.e", 424 Name: "e", 425 }, 426 }, 427 }, 428 }, 429 } 430 filtersLogicalOperator := v1alpha1.EmptyLogicalOperator // default AND 431 now := time.Now().UTC() 432 event := &v1alpha1.Event{ 433 Context: &v1alpha1.EventContext{ 434 Time: metav1.Time{ 435 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 436 }, 437 }, 438 Data: []byte(`{ "a": "x", "b": 10, "c": { "d": "hello world", "e": false } }`), 439 } 440 441 pass, err := filterEvent(filter, filtersLogicalOperator, event) 442 443 assert.NoError(t, err) 444 assert.True(t, pass) 445 }) 446 447 t.Run("test advanced logic: (A && B) && (C && D) with error", func(t *testing.T) { 448 // data filter: A && B == error (false) 449 // expr filter: C && D == true 450 filter := &v1alpha1.EventDependencyFilter{ 451 DataLogicalOperator: v1alpha1.EmptyLogicalOperator, // default AND 452 Data: []v1alpha1.DataFilter{ 453 { 454 // A 455 Path: "z", 456 Type: v1alpha1.JSONTypeString, 457 Value: []string{"x"}, 458 }, 459 { 460 // B 461 Path: "b", 462 Type: v1alpha1.JSONTypeNumber, 463 Value: []string{"10"}, 464 }, 465 }, 466 ExprLogicalOperator: v1alpha1.EmptyLogicalOperator, // default AND 467 Exprs: []v1alpha1.ExprFilter{ 468 { 469 // C 470 Expr: `d == "hello world"`, 471 Fields: []v1alpha1.PayloadField{ 472 { 473 Path: "c.d", 474 Name: "d", 475 }, 476 }, 477 }, 478 { 479 // D 480 Expr: `e == false"`, 481 Fields: []v1alpha1.PayloadField{ 482 { 483 Path: "c.e", 484 Name: "e", 485 }, 486 }, 487 }, 488 }, 489 } 490 filtersLogicalOperator := v1alpha1.EmptyLogicalOperator // default AND 491 now := time.Now().UTC() 492 event := &v1alpha1.Event{ 493 Context: &v1alpha1.EventContext{ 494 Time: metav1.Time{ 495 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 496 }, 497 }, 498 Data: []byte(`{ "a": "x", "b": 10, "c": { "d": "hello world", "e": false } }`), 499 } 500 501 pass, err := filterEvent(filter, filtersLogicalOperator, event) 502 503 assert.Error(t, err) 504 assert.False(t, pass) 505 }) 506 507 t.Run("test advanced logic: (A && B) || (C && D)", func(t *testing.T) { 508 // data filter: A && B == true 509 // expr filter: C && D == false 510 filter := &v1alpha1.EventDependencyFilter{ 511 DataLogicalOperator: v1alpha1.AndLogicalOperator, 512 Data: []v1alpha1.DataFilter{ 513 { 514 // A 515 Path: "a", 516 Type: v1alpha1.JSONTypeString, 517 Value: []string{"x"}, 518 }, 519 { 520 // B 521 Path: "b", 522 Type: v1alpha1.JSONTypeNumber, 523 Value: []string{"10"}, 524 }, 525 }, 526 ExprLogicalOperator: v1alpha1.AndLogicalOperator, 527 Exprs: []v1alpha1.ExprFilter{ 528 { 529 // C 530 Expr: `d == "hello world"`, 531 Fields: []v1alpha1.PayloadField{ 532 { 533 Path: "c.d", 534 Name: "d", 535 }, 536 }, 537 }, 538 { 539 // D 540 Expr: `e == true`, 541 Fields: []v1alpha1.PayloadField{ 542 { 543 Path: "c.e", 544 Name: "e", 545 }, 546 }, 547 }, 548 }, 549 } 550 filtersLogicalOperator := v1alpha1.OrLogicalOperator 551 now := time.Now().UTC() 552 event := &v1alpha1.Event{ 553 Context: &v1alpha1.EventContext{ 554 Time: metav1.Time{ 555 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 556 }, 557 }, 558 Data: []byte(`{ "a": "x", "b": 10, "c": { "d": "hello world", "e": false } }`), 559 } 560 561 pass, err := filterEvent(filter, filtersLogicalOperator, event) 562 563 assert.NoError(t, err) 564 assert.True(t, pass) 565 }) 566 567 t.Run("test advanced logic: (A || B) && (C || D)", func(t *testing.T) { 568 // data filter: A || B == true 569 // expr filter: C || D == false 570 filter := &v1alpha1.EventDependencyFilter{ 571 DataLogicalOperator: v1alpha1.OrLogicalOperator, 572 Data: []v1alpha1.DataFilter{ 573 { 574 // A 575 Path: "a", 576 Type: v1alpha1.JSONTypeString, 577 Value: []string{"x"}, 578 }, 579 { 580 // B 581 Path: "b", 582 Type: v1alpha1.JSONTypeNumber, 583 Value: []string{"11"}, 584 }, 585 }, 586 ExprLogicalOperator: v1alpha1.OrLogicalOperator, 587 Exprs: []v1alpha1.ExprFilter{ 588 { 589 // C 590 Expr: `d == "hello world"`, 591 Fields: []v1alpha1.PayloadField{ 592 { 593 Path: "c.d", 594 Name: "d", 595 }, 596 }, 597 }, 598 { 599 // D 600 Expr: `e == true`, 601 Fields: []v1alpha1.PayloadField{ 602 { 603 Path: "c.e", 604 Name: "e", 605 }, 606 }, 607 }, 608 }, 609 } 610 filtersLogicalOperator := v1alpha1.AndLogicalOperator 611 now := time.Now().UTC() 612 event := &v1alpha1.Event{ 613 Context: &v1alpha1.EventContext{ 614 Time: metav1.Time{ 615 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 616 }, 617 }, 618 Data: []byte(`{ "a": "x", "b": 10, "c": { "d": "hello world", "e": false } }`), 619 } 620 621 pass, err := filterEvent(filter, filtersLogicalOperator, event) 622 623 assert.NoError(t, err) 624 assert.True(t, pass) 625 }) 626 627 t.Run("filtersLogicalOperator == 'or' with only a subset of filters specified", func(t *testing.T) { 628 filter := &v1alpha1.EventDependencyFilter{ 629 Exprs: []v1alpha1.ExprFilter{ 630 { 631 Expr: `A == "not-valid"`, // this will evaluate to false 632 Fields: []v1alpha1.PayloadField{ 633 { 634 Path: "a.b", 635 Name: "A", 636 }, 637 }, 638 }, 639 }, 640 Data: []v1alpha1.DataFilter{ // these evaluate to false 641 { 642 Path: "a.d.e.f", 643 Type: "string", 644 Value: []string{"not-valid"}, 645 }, 646 { 647 Path: "a.h.i", 648 Type: "string", 649 Value: []string{"not-valid", "not-valid-2"}, 650 }, 651 }, 652 } 653 654 eventDataBytes, err := json.Marshal(map[string]interface{}{ 655 "a": map[string]interface{}{ 656 "b": "c", 657 "d": map[string]interface{}{ 658 "e": map[string]interface{}{ 659 "f": "g", 660 }, 661 }, 662 "h": map[string]interface{}{ 663 "i": "j", 664 }, 665 }, 666 }) 667 668 assert.NoError(t, err) 669 670 // should return false because the two filters above evaluate to false 671 filtersLogicalOperator := v1alpha1.OrLogicalOperator 672 673 now := time.Now().UTC() 674 event := &v1alpha1.Event{ 675 Context: &v1alpha1.EventContext{ 676 Time: metav1.Time{ 677 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 678 }, 679 }, 680 Data: eventDataBytes, 681 } 682 683 pass, err := filterEvent(filter, filtersLogicalOperator, event) 684 685 assert.NoError(t, err) 686 assert.False(t, pass) 687 }) 688 689 t.Run("test advanced logic: (A || B) || (C || D)", func(t *testing.T) { 690 // data filter: A || B == false 691 // expr filter: C || D == true 692 filter := &v1alpha1.EventDependencyFilter{ 693 DataLogicalOperator: v1alpha1.OrLogicalOperator, 694 Data: []v1alpha1.DataFilter{ 695 { 696 // A 697 Path: "a", 698 Type: v1alpha1.JSONTypeString, 699 Value: []string{"y"}, 700 }, 701 { 702 // B 703 Path: "b", 704 Type: v1alpha1.JSONTypeNumber, 705 Value: []string{"11"}, 706 }, 707 }, 708 ExprLogicalOperator: v1alpha1.OrLogicalOperator, 709 Exprs: []v1alpha1.ExprFilter{ 710 { 711 // C 712 Expr: `d == "hello world"`, 713 Fields: []v1alpha1.PayloadField{ 714 { 715 Path: "c.d", 716 Name: "d", 717 }, 718 }, 719 }, 720 { 721 // D 722 Expr: `e == false`, 723 Fields: []v1alpha1.PayloadField{ 724 { 725 Path: "c.e", 726 Name: "e", 727 }, 728 }, 729 }, 730 }, 731 } 732 filtersLogicalOperator := v1alpha1.OrLogicalOperator 733 now := time.Now().UTC() 734 event := &v1alpha1.Event{ 735 Context: &v1alpha1.EventContext{ 736 Time: metav1.Time{ 737 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 738 }, 739 }, 740 Data: []byte(`{ "a": "x", "b": 10, "c": { "d": "hello world", "e": false } }`), 741 } 742 743 pass, err := filterEvent(filter, filtersLogicalOperator, event) 744 745 assert.NoError(t, err) 746 assert.True(t, pass) 747 }) 748 749 t.Run("test advanced logic: (A && B) || (C || D)", func(t *testing.T) { 750 // data filter: A && B == true 751 // expr filter: C || D == false 752 filter := &v1alpha1.EventDependencyFilter{ 753 DataLogicalOperator: v1alpha1.AndLogicalOperator, 754 Data: []v1alpha1.DataFilter{ 755 { 756 // A 757 Path: "a", 758 Type: v1alpha1.JSONTypeString, 759 Value: []string{"x"}, 760 }, 761 { 762 // B 763 Path: "b", 764 Type: v1alpha1.JSONTypeNumber, 765 Value: []string{"10"}, 766 }, 767 }, 768 ExprLogicalOperator: v1alpha1.OrLogicalOperator, 769 Exprs: []v1alpha1.ExprFilter{ 770 { 771 // C 772 Expr: `d == "hello everybody"`, 773 Fields: []v1alpha1.PayloadField{ 774 { 775 Path: "c.d", 776 Name: "d", 777 }, 778 }, 779 }, 780 { 781 // D 782 Expr: `e == true`, 783 Fields: []v1alpha1.PayloadField{ 784 { 785 Path: "c.e", 786 Name: "e", 787 }, 788 }, 789 }, 790 }, 791 } 792 filtersLogicalOperator := v1alpha1.OrLogicalOperator 793 now := time.Now().UTC() 794 event := &v1alpha1.Event{ 795 Context: &v1alpha1.EventContext{ 796 Time: metav1.Time{ 797 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 798 }, 799 }, 800 Data: []byte(`{ "a": "x", "b": 10, "c": { "d": "hello world", "e": false } }`), 801 } 802 803 pass, err := filterEvent(filter, filtersLogicalOperator, event) 804 805 assert.NoError(t, err) 806 assert.True(t, pass) 807 }) 808 809 t.Run("test advanced logic: (A || B) || (C && D)", func(t *testing.T) { 810 // data filter: A || B == true 811 // expr filter: C && D == false 812 filter := &v1alpha1.EventDependencyFilter{ 813 DataLogicalOperator: v1alpha1.OrLogicalOperator, 814 Data: []v1alpha1.DataFilter{ 815 { 816 // A 817 Path: "a", 818 Type: v1alpha1.JSONTypeString, 819 Value: []string{"x"}, 820 }, 821 { 822 // B 823 Path: "b", 824 Type: v1alpha1.JSONTypeNumber, 825 Value: []string{"11"}, 826 }, 827 }, 828 ExprLogicalOperator: v1alpha1.AndLogicalOperator, 829 Exprs: []v1alpha1.ExprFilter{ 830 { 831 // C 832 Expr: `d == "hello everybody"`, 833 Fields: []v1alpha1.PayloadField{ 834 { 835 Path: "c.d", 836 Name: "d", 837 }, 838 }, 839 }, 840 { 841 // D 842 Expr: `e == false`, 843 Fields: []v1alpha1.PayloadField{ 844 { 845 Path: "c.e", 846 Name: "e", 847 }, 848 }, 849 }, 850 }, 851 } 852 filtersLogicalOperator := v1alpha1.OrLogicalOperator 853 now := time.Now().UTC() 854 event := &v1alpha1.Event{ 855 Context: &v1alpha1.EventContext{ 856 Time: metav1.Time{ 857 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 858 }, 859 }, 860 Data: []byte(`{ "a": "x", "b": 10, "c": { "d": "hello world", "e": false } }`), 861 } 862 863 pass, err := filterEvent(filter, filtersLogicalOperator, event) 864 865 assert.NoError(t, err) 866 assert.True(t, pass) 867 }) 868 869 t.Run("test advanced logic: (A && B) && (C || D)", func(t *testing.T) { 870 // data filter: A && B == false 871 // expr filter: C || D == false 872 filter := &v1alpha1.EventDependencyFilter{ 873 DataLogicalOperator: v1alpha1.AndLogicalOperator, 874 Data: []v1alpha1.DataFilter{ 875 { 876 // A 877 Path: "a", 878 Type: v1alpha1.JSONTypeString, 879 Value: []string{"x"}, 880 }, 881 { 882 // B 883 Path: "b", 884 Type: v1alpha1.JSONTypeNumber, 885 Value: []string{"11"}, 886 }, 887 }, 888 ExprLogicalOperator: v1alpha1.OrLogicalOperator, 889 Exprs: []v1alpha1.ExprFilter{ 890 { 891 // C 892 Expr: `d == "hello everybody"`, 893 Fields: []v1alpha1.PayloadField{ 894 { 895 Path: "c.d", 896 Name: "d", 897 }, 898 }, 899 }, 900 { 901 // D 902 Expr: `e == true`, 903 Fields: []v1alpha1.PayloadField{ 904 { 905 Path: "c.e", 906 Name: "e", 907 }, 908 }, 909 }, 910 }, 911 } 912 filtersLogicalOperator := v1alpha1.AndLogicalOperator 913 now := time.Now().UTC() 914 event := &v1alpha1.Event{ 915 Context: &v1alpha1.EventContext{ 916 Time: metav1.Time{ 917 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 918 }, 919 }, 920 Data: []byte(`{ "a": "x", "b": 10, "c": { "d": "hello world", "e": false } }`), 921 } 922 923 pass, err := filterEvent(filter, filtersLogicalOperator, event) 924 925 assert.NoError(t, err) 926 assert.False(t, pass) 927 }) 928 929 t.Run("test advanced logic: (A || B) && (C && D)", func(t *testing.T) { 930 // data filter: A || B == true 931 // expr filter: C && D == error (false) 932 filter := &v1alpha1.EventDependencyFilter{ 933 DataLogicalOperator: v1alpha1.OrLogicalOperator, 934 Data: []v1alpha1.DataFilter{ 935 { 936 // A 937 Path: "a", 938 Type: v1alpha1.JSONTypeString, 939 Value: []string{"x"}, 940 }, 941 { 942 // B 943 Path: "b", 944 Type: v1alpha1.JSONTypeNumber, 945 Value: []string{"10"}, 946 }, 947 }, 948 ExprLogicalOperator: v1alpha1.AndLogicalOperator, 949 Exprs: []v1alpha1.ExprFilter{ 950 { 951 // C 952 Expr: `f == "hello world"`, 953 Fields: []v1alpha1.PayloadField{ 954 { 955 Path: "c.f", 956 Name: "f", 957 }, 958 }, 959 }, 960 { 961 // D 962 Expr: `e == false`, 963 Fields: []v1alpha1.PayloadField{ 964 { 965 Path: "c.e", 966 Name: "e", 967 }, 968 }, 969 }, 970 }, 971 } 972 filtersLogicalOperator := v1alpha1.AndLogicalOperator 973 now := time.Now().UTC() 974 event := &v1alpha1.Event{ 975 Context: &v1alpha1.EventContext{ 976 Time: metav1.Time{ 977 Time: time.Date(now.Year(), now.Month(), now.Day(), 16, 36, 34, 0, time.UTC), 978 }, 979 }, 980 Data: []byte(`{ "a": "x", "b": 10, "c": { "d": "hello world", "e": false } }`), 981 } 982 983 pass, err := filterEvent(filter, filtersLogicalOperator, event) 984 985 assert.Error(t, err) 986 assert.False(t, pass) 987 }) 988 }