diff --git a/bucketing/constants.go b/bucketing/constants.go index cddd196c..baff4f13 100644 --- a/bucketing/constants.go +++ b/bucketing/constants.go @@ -46,6 +46,10 @@ const ( ComparatorNotExist = "!exist" ComparatorContain = "contain" ComparatorNotContain = "!contain" + ComparatorStartWith = "startWith" + ComparatorNotStartWith = "!startWith" + ComparatorEndWith = "endWith" + ComparatorNotEndWith = "!endWith" ) const ( diff --git a/bucketing/segmentation.go b/bucketing/segmentation.go index 114f8dff..629d2992 100644 --- a/bucketing/segmentation.go +++ b/bucketing/segmentation.go @@ -103,6 +103,14 @@ func checkStringsFilter(str string, filter *UserFilter) bool { return str != "" && stringArrayContains(values, str) } else if operator == "!contain" { return str == "" || !stringArrayContains(values, str) + } else if operator == "startWith" { + return str != "" && stringArrayStartsWith(values, str) + } else if operator == "!startWith" { + return str == "" || !stringArrayStartsWith(values, str) + } else if operator == "endWith" { + return str != "" && stringArrayEndsWith(values, str) + } else if operator == "!endWith" { + return str == "" || !stringArrayEndsWith(values, str) } else { return false } @@ -126,6 +134,24 @@ func stringArrayContains(substrings []string, search string) bool { return false } +func stringArrayStartsWith(prefixes []string, search string) bool { + for _, prefix := range prefixes { + if strings.HasPrefix(search, prefix) { + return true + } + } + return false +} + +func stringArrayEndsWith(suffixes []string, search string) bool { + for _, suffix := range suffixes { + if strings.HasSuffix(search, suffix) { + return true + } + } + return false +} + func _checkBooleanFilter(b bool, filter *UserFilter) bool { contains := func(arr []bool, search bool) bool { for _, s := range arr { diff --git a/bucketing/segmentation_test.go b/bucketing/segmentation_test.go index c34c9329..6989ad06 100644 --- a/bucketing/segmentation_test.go +++ b/bucketing/segmentation_test.go @@ -1592,6 +1592,30 @@ func TestDoesUserPassFilter_WithUserEmailFilter(t *testing.T) { values: []interface{}{"@gmail.com", "@devcycle.com", "@hotmail.com"}, expected: true, }, + { + name: "User email starts with filter", + comparator: ComparatorStartWith, + values: []interface{}{"test"}, + expected: true, + }, + { + name: "User email emds with filter", + comparator: ComparatorEndWith, + values: []interface{}{"@devcycle.com"}, + expected: true, + }, + { + name: "User email does not start with filter", + comparator: ComparatorStartWith, + values: []interface{}{"user"}, + expected: false, + }, + { + name: "User email does not end with filter", + comparator: ComparatorEndWith, + values: []interface{}{"@devcycle.io"}, + expected: false, + }, } for _, tc := range testCases {