@@ -91,6 +91,55 @@ describe("evaluateStringRule", () => {
9191 } ) ;
9292} ) ;
9393
94+ describe ( "evaluateStringRule - email pattern matching" , ( ) => {
95+ const emailRule = ( op : string , val ?: string , vals ?: string [ ] ) => ( {
96+ type : "email" as const ,
97+ operator : op ,
98+ value : val ,
99+ values : vals ,
100+ enabled : true ,
101+ batch : false ,
102+ } ) ;
103+
104+ it ( "handles ends_with for email domain patterns" , ( ) => {
105+ // Common use case: target users by email domain
106+ expect ( evaluateStringRule ( "user@databuddy.cc" , emailRule ( "ends_with" , "@databuddy.cc" ) ) ) . toBe ( true ) ;
107+ expect ( evaluateStringRule ( "admin@databuddy.cc" , emailRule ( "ends_with" , "@databuddy.cc" ) ) ) . toBe ( true ) ;
108+ expect ( evaluateStringRule ( "user@other.com" , emailRule ( "ends_with" , "@databuddy.cc" ) ) ) . toBe ( false ) ;
109+ expect ( evaluateStringRule ( "user@company.io" , emailRule ( "ends_with" , ".io" ) ) ) . toBe ( true ) ;
110+ expect ( evaluateStringRule ( "user@company.com" , emailRule ( "ends_with" , ".io" ) ) ) . toBe ( false ) ;
111+ } ) ;
112+
113+ it ( "handles starts_with for email prefix patterns" , ( ) => {
114+ // Target emails starting with a prefix (e.g., admin@, support@)
115+ expect ( evaluateStringRule ( "admin@company.com" , emailRule ( "starts_with" , "admin@" ) ) ) . toBe ( true ) ;
116+ expect ( evaluateStringRule ( "admin@other.org" , emailRule ( "starts_with" , "admin@" ) ) ) . toBe ( true ) ;
117+ expect ( evaluateStringRule ( "user@company.com" , emailRule ( "starts_with" , "admin@" ) ) ) . toBe ( false ) ;
118+ expect ( evaluateStringRule ( "support@company.com" , emailRule ( "starts_with" , "support" ) ) ) . toBe ( true ) ;
119+ } ) ;
120+
121+ it ( "handles contains for partial email matching" , ( ) => {
122+ // Target emails containing a substring
123+ expect ( evaluateStringRule ( "user@company.internal.com" , emailRule ( "contains" , "internal" ) ) ) . toBe ( true ) ;
124+ expect ( evaluateStringRule ( "internal-user@company.com" , emailRule ( "contains" , "internal" ) ) ) . toBe ( true ) ;
125+ expect ( evaluateStringRule ( "user@company.com" , emailRule ( "contains" , "internal" ) ) ) . toBe ( false ) ;
126+ expect ( evaluateStringRule ( "beta-tester@company.com" , emailRule ( "contains" , "beta" ) ) ) . toBe ( true ) ;
127+ } ) ;
128+
129+ it ( "handles exact match for full email addresses" , ( ) => {
130+ expect ( evaluateStringRule ( "user@databuddy.cc" , emailRule ( "equals" , "user@databuddy.cc" ) ) ) . toBe ( true ) ;
131+ expect ( evaluateStringRule ( "other@databuddy.cc" , emailRule ( "equals" , "user@databuddy.cc" ) ) ) . toBe ( false ) ;
132+ } ) ;
133+
134+ it ( "handles in/not_in for email lists" , ( ) => {
135+ const allowedEmails = [ "admin@co.com" , "support@co.com" , "dev@co.com" ] ;
136+ expect ( evaluateStringRule ( "admin@co.com" , emailRule ( "in" , undefined , allowedEmails ) ) ) . toBe ( true ) ;
137+ expect ( evaluateStringRule ( "random@co.com" , emailRule ( "in" , undefined , allowedEmails ) ) ) . toBe ( false ) ;
138+ expect ( evaluateStringRule ( "random@co.com" , emailRule ( "not_in" , undefined , allowedEmails ) ) ) . toBe ( true ) ;
139+ expect ( evaluateStringRule ( "admin@co.com" , emailRule ( "not_in" , undefined , allowedEmails ) ) ) . toBe ( false ) ;
140+ } ) ;
141+ } ) ;
142+
94143describe ( "evaluateValueRule" , ( ) => {
95144 const rule = ( op : string , val ?: unknown , vals ?: unknown [ ] ) => ( {
96145 type : "property" as const ,
0 commit comments