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  }